Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve unit test coverage for primitives #11978

Merged
merged 2 commits into from
Jun 7, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 119 additions & 63 deletions test/unit/primitives_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,34 @@
import {
Cmd,
Dict,
EOF,
isCmd,
isDict,
isEOF,
isName,
isRef,
isRefsEqual,
isStream,
Name,
Ref,
RefSet,
} from "../../src/core/primitives.js";
import { StringStream } from "../../src/core/stream.js";
import { XRefMock } from "./test_utils.js";

describe("primitives", function () {
describe("Name", function () {
it("should retain the given name", function () {
var givenName = "Font";
var name = Name.get(givenName);
const givenName = "Font";
const name = Name.get(givenName);
expect(name.name).toEqual(givenName);
});

it("should create only one object for a name and cache it", function () {
var firstFont = Name.get("Font");
var secondFont = Name.get("Font");
var firstSubtype = Name.get("Subtype");
var secondSubtype = Name.get("Subtype");
const firstFont = Name.get("Font");
const secondFont = Name.get("Font");
const firstSubtype = Name.get("Subtype");
const secondSubtype = Name.get("Subtype");

expect(firstFont).toBe(secondFont);
expect(firstSubtype).toBe(secondSubtype);
Expand All @@ -49,16 +53,16 @@ describe("primitives", function () {

describe("Cmd", function () {
it("should retain the given cmd name", function () {
var givenCmd = "BT";
var cmd = Cmd.get(givenCmd);
const givenCmd = "BT";
const cmd = Cmd.get(givenCmd);
expect(cmd.cmd).toEqual(givenCmd);
});

it("should create only one object for a command and cache it", function () {
var firstBT = Cmd.get("BT");
var secondBT = Cmd.get("BT");
var firstET = Cmd.get("ET");
var secondET = Cmd.get("ET");
const firstBT = Cmd.get("BT");
const secondBT = Cmd.get("BT");
const firstET = Cmd.get("ET");
const secondET = Cmd.get("ET");

expect(firstBT).toBe(secondBT);
expect(firstET).toBe(secondET);
Expand All @@ -67,23 +71,23 @@ describe("primitives", function () {
});

describe("Dict", function () {
var checkInvalidHasValues = function (dict) {
const checkInvalidHasValues = function (dict) {
expect(dict.has()).toBeFalsy();
expect(dict.has("Prev")).toBeFalsy();
};

var checkInvalidKeyValues = function (dict) {
const checkInvalidKeyValues = function (dict) {
expect(dict.get()).toBeUndefined();
expect(dict.get("Prev")).toBeUndefined();
expect(dict.get("Decode", "D")).toBeUndefined();
expect(dict.get("FontFile", "FontFile2", "FontFile3")).toBeUndefined();
};

var emptyDict, dictWithSizeKey, dictWithManyKeys;
var storedSize = 42;
var testFontFile = "file1";
var testFontFile2 = "file2";
var testFontFile3 = "file3";
let emptyDict, dictWithSizeKey, dictWithManyKeys;
const storedSize = 42;
const testFontFile = "file1";
const testFontFile2 = "file2";
const testFontFile3 = "file3";

beforeAll(function (done) {
emptyDict = new Dict();
Expand All @@ -103,6 +107,15 @@ describe("primitives", function () {
emptyDict = dictWithSizeKey = dictWithManyKeys = null;
});

it("should allow assigning an XRef table after creation", function () {
const dict = new Dict(null);
expect(dict.xref).toEqual(null);

const xref = new XRefMock([]);
dict.assignXref(xref);
expect(dict.xref).toEqual(xref);
});

it("should return invalid values for unknown keys", function () {
checkInvalidHasValues(emptyDict);
checkInvalidKeyValues(emptyDict);
Expand Down Expand Up @@ -147,7 +160,7 @@ describe("primitives", function () {
});

it("should asynchronously fetch unknown keys", function (done) {
var keyPromises = [
const keyPromises = [
dictWithManyKeys.getAsync("Size"),
dictWithSizeKey.getAsync("FontFile", "FontFile2", "FontFile3"),
];
Expand All @@ -164,7 +177,7 @@ describe("primitives", function () {
});

it("should asynchronously fetch correct values for multiple stored keys", function (done) {
var keyPromises = [
const keyPromises = [
dictWithManyKeys.getAsync("FontFile3"),
dictWithManyKeys.getAsync("FontFile2", "FontFile3"),
dictWithManyKeys.getAsync("FontFile", "FontFile2", "FontFile3"),
Expand All @@ -183,22 +196,22 @@ describe("primitives", function () {
});

it("should callback for each stored key", function () {
var callbackSpy = jasmine.createSpy("spy on callback in dictionary");
const callbackSpy = jasmine.createSpy("spy on callback in dictionary");

dictWithManyKeys.forEach(callbackSpy);

expect(callbackSpy).toHaveBeenCalled();
var callbackSpyCalls = callbackSpy.calls;
const callbackSpyCalls = callbackSpy.calls;
expect(callbackSpyCalls.argsFor(0)).toEqual(["FontFile", testFontFile]);
expect(callbackSpyCalls.argsFor(1)).toEqual(["FontFile2", testFontFile2]);
expect(callbackSpyCalls.argsFor(2)).toEqual(["FontFile3", testFontFile3]);
expect(callbackSpyCalls.count()).toEqual(3);
});

it("should handle keys pointing to indirect objects, both sync and async", function (done) {
var fontRef = Ref.get(1, 0);
var xref = new XRefMock([{ ref: fontRef, data: testFontFile }]);
var fontDict = new Dict(xref);
const fontRef = Ref.get(1, 0);
const xref = new XRefMock([{ ref: fontRef, data: testFontFile }]);
const fontDict = new Dict(xref);
fontDict.set("FontFile", fontRef);

expect(fontDict.getRaw("FontFile")).toEqual(fontRef);
Expand All @@ -218,15 +231,15 @@ describe("primitives", function () {
});

it("should handle arrays containing indirect objects", function () {
var minCoordRef = Ref.get(1, 0),
maxCoordRef = Ref.get(2, 0);
var minCoord = 0,
maxCoord = 1;
var xref = new XRefMock([
const minCoordRef = Ref.get(1, 0);
const maxCoordRef = Ref.get(2, 0);
const minCoord = 0;
const maxCoord = 1;
const xref = new XRefMock([
{ ref: minCoordRef, data: minCoord },
{ ref: maxCoordRef, data: maxCoord },
]);
var xObjectDict = new Dict(xref);
const xObjectDict = new Dict(xref);
xObjectDict.set("BBox", [minCoord, maxCoord, minCoordRef, maxCoordRef]);

expect(xObjectDict.get("BBox")).toEqual([
Expand All @@ -244,115 +257,146 @@ describe("primitives", function () {
});

it("should get all key names", function () {
var expectedKeys = ["FontFile", "FontFile2", "FontFile3"];
var keys = dictWithManyKeys.getKeys();
const expectedKeys = ["FontFile", "FontFile2", "FontFile3"];
const keys = dictWithManyKeys.getKeys();

expect(keys.sort()).toEqual(expectedKeys);
});

it("should create only one object for Dict.empty", function () {
var firstDictEmpty = Dict.empty;
var secondDictEmpty = Dict.empty;
const firstDictEmpty = Dict.empty;
const secondDictEmpty = Dict.empty;

expect(firstDictEmpty).toBe(secondDictEmpty);
expect(firstDictEmpty).not.toBe(emptyDict);
});

it("should correctly merge dictionaries", function () {
var expectedKeys = ["FontFile", "FontFile2", "FontFile3", "Size"];
const expectedKeys = ["FontFile", "FontFile2", "FontFile3", "Size"];

var fontFileDict = new Dict();
const fontFileDict = new Dict();
fontFileDict.set("FontFile", "Type1 font file");
var mergedDict = Dict.merge(null, [
const mergedDict = Dict.merge(null, [
dictWithManyKeys,
dictWithSizeKey,
fontFileDict,
]);
var mergedKeys = mergedDict.getKeys();
const mergedKeys = mergedDict.getKeys();

expect(mergedKeys.sort()).toEqual(expectedKeys);
expect(mergedDict.get("FontFile")).toEqual(testFontFile);
});
});

describe("Ref", function () {
it("should get a string representation", function () {
const nonZeroRef = Ref.get(4, 2);
expect(nonZeroRef.toString()).toEqual("4R2");

// If the generation number is 0, a shorter representation is used.
const zeroRef = Ref.get(4, 0);
expect(zeroRef.toString()).toEqual("4R");
});

it("should retain the stored values", function () {
var storedNum = 4;
var storedGen = 2;
var ref = Ref.get(storedNum, storedGen);
const storedNum = 4;
const storedGen = 2;
const ref = Ref.get(storedNum, storedGen);
expect(ref.num).toEqual(storedNum);
expect(ref.gen).toEqual(storedGen);
});

it("should create only one object for a reference and cache it", function () {
const firstRef = Ref.get(4, 2);
const secondRef = Ref.get(4, 2);
const firstOtherRef = Ref.get(5, 2);
const secondOtherRef = Ref.get(5, 2);

expect(firstRef).toBe(secondRef);
expect(firstOtherRef).toBe(secondOtherRef);
expect(firstRef).not.toBe(firstOtherRef);
});
});

describe("RefSet", function () {
it("should have a stored value", function () {
var ref = Ref.get(4, 2);
var refset = new RefSet();
const ref = Ref.get(4, 2);
const refset = new RefSet();
refset.put(ref);
expect(refset.has(ref)).toBeTruthy();
});
it("should not have an unknown value", function () {
var ref = Ref.get(4, 2);
var refset = new RefSet();
const ref = Ref.get(4, 2);
const refset = new RefSet();
expect(refset.has(ref)).toBeFalsy();

refset.put(ref);
var anotherRef = Ref.get(2, 4);
const anotherRef = Ref.get(2, 4);
expect(refset.has(anotherRef)).toBeFalsy();
});
});

describe("isEOF", function () {
it("handles non-EOF", function () {
const nonEOF = "foo";
expect(isEOF(nonEOF)).toEqual(false);
});

it("handles EOF", function () {
expect(isEOF(EOF)).toEqual(true);
});
});

describe("isName", function () {
it("handles non-names", function () {
var nonName = {};
const nonName = {};
expect(isName(nonName)).toEqual(false);
});

it("handles names", function () {
var name = Name.get("Font");
const name = Name.get("Font");
expect(isName(name)).toEqual(true);
});

it("handles names with name check", function () {
var name = Name.get("Font");
const name = Name.get("Font");
expect(isName(name, "Font")).toEqual(true);
expect(isName(name, "Subtype")).toEqual(false);
});
});

describe("isCmd", function () {
it("handles non-commands", function () {
var nonCmd = {};
const nonCmd = {};
expect(isCmd(nonCmd)).toEqual(false);
});

it("handles commands", function () {
var cmd = Cmd.get("BT");
const cmd = Cmd.get("BT");
expect(isCmd(cmd)).toEqual(true);
});

it("handles commands with cmd check", function () {
var cmd = Cmd.get("BT");
const cmd = Cmd.get("BT");
expect(isCmd(cmd, "BT")).toEqual(true);
expect(isCmd(cmd, "ET")).toEqual(false);
});
});

describe("isDict", function () {
it("handles non-dictionaries", function () {
var nonDict = {};
const nonDict = {};
expect(isDict(nonDict)).toEqual(false);
});

it("handles empty dictionaries with type check", function () {
var dict = Dict.empty;
const dict = Dict.empty;
expect(isDict(dict)).toEqual(true);
expect(isDict(dict, "Page")).toEqual(false);
});

it("handles dictionaries with type check", function () {
var dict = new Dict();
const dict = new Dict();
dict.set("Type", Name.get("Page"));
expect(isDict(dict, "Page")).toEqual(true);
expect(isDict(dict, "Contents")).toEqual(false);
Expand All @@ -361,27 +405,39 @@ describe("primitives", function () {

describe("isRef", function () {
it("handles non-refs", function () {
var nonRef = {};
const nonRef = {};
expect(isRef(nonRef)).toEqual(false);
});

it("handles refs", function () {
var ref = Ref.get(1, 0);
const ref = Ref.get(1, 0);
expect(isRef(ref)).toEqual(true);
});
});

describe("isRefsEqual", function () {
it("should handle Refs pointing to the same object", function () {
var ref1 = Ref.get(1, 0);
var ref2 = Ref.get(1, 0);
const ref1 = Ref.get(1, 0);
const ref2 = Ref.get(1, 0);
expect(isRefsEqual(ref1, ref2)).toEqual(true);
});

it("should handle Refs pointing to different objects", function () {
var ref1 = Ref.get(1, 0);
var ref2 = Ref.get(2, 0);
const ref1 = Ref.get(1, 0);
const ref2 = Ref.get(2, 0);
expect(isRefsEqual(ref1, ref2)).toEqual(false);
});
});

describe("isStream", function () {
it("handles non-streams", function () {
const nonStream = {};
expect(isStream(nonStream)).toEqual(false);
});

it("handles streams", function () {
const stream = new StringStream("foo");
expect(isStream(stream)).toEqual(true);
});
});
});