primitives_spec.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. 'use strict';
  16. var corePrimitives = require('../../core/primitives.js');
  17. var Name = corePrimitives.Name;
  18. var Dict = corePrimitives.Dict;
  19. var Ref = corePrimitives.Ref;
  20. var RefSet = corePrimitives.RefSet;
  21. var Cmd = corePrimitives.Cmd;
  22. var isName = corePrimitives.isName;
  23. var isCmd = corePrimitives.isCmd;
  24. var isDict = corePrimitives.isDict;
  25. var isRef = corePrimitives.isRef;
  26. var isRefsEqual = corePrimitives.isRefsEqual;
  27. describe('primitives', function () {
  28. function XRefMock(array) {
  29. this.map = Object.create(null);
  30. for (var elem in array) {
  31. var obj = array[elem];
  32. var ref = obj.ref, data = obj.data;
  33. this.map[ref.toString()] = data;
  34. }
  35. }
  36. XRefMock.prototype = {
  37. fetch: function (ref) {
  38. return this.map[ref.toString()];
  39. },
  40. fetchIfRef: function (obj) {
  41. if (!isRef(obj)) {
  42. return obj;
  43. }
  44. return this.fetch(obj);
  45. },
  46. fetchAsync: function (ref) {
  47. return Promise.resolve(this.fetch(ref));
  48. },
  49. fetchIfRefAsync: function (obj) {
  50. return Promise.resolve(this.fetchIfRef(obj));
  51. }
  52. };
  53. describe('Name', function () {
  54. it('should retain the given name', function () {
  55. var givenName = 'Font';
  56. var name = Name.get(givenName);
  57. expect(name.name).toEqual(givenName);
  58. });
  59. it('should create only one object for a name and cache it', function () {
  60. var firstFont = Name.get('Font');
  61. var secondFont = Name.get('Font');
  62. var firstSubtype = Name.get('Subtype');
  63. var secondSubtype = Name.get('Subtype');
  64. expect(firstFont).toBe(secondFont);
  65. expect(firstSubtype).toBe(secondSubtype);
  66. expect(firstFont).not.toBe(firstSubtype);
  67. });
  68. });
  69. describe('Cmd', function () {
  70. it('should retain the given cmd name', function () {
  71. var givenCmd = 'BT';
  72. var cmd = Cmd.get(givenCmd);
  73. expect(cmd.cmd).toEqual(givenCmd);
  74. });
  75. it('should create only one object for a command and cache it', function () {
  76. var firstBT = Cmd.get('BT');
  77. var secondBT = Cmd.get('BT');
  78. var firstET = Cmd.get('ET');
  79. var secondET = Cmd.get('ET');
  80. expect(firstBT).toBe(secondBT);
  81. expect(firstET).toBe(secondET);
  82. expect(firstBT).not.toBe(firstET);
  83. });
  84. });
  85. describe('Dict', function () {
  86. var checkInvalidHasValues = function (dict) {
  87. expect(dict.has()).toBeFalsy();
  88. expect(dict.has('Prev')).toBeFalsy();
  89. };
  90. var checkInvalidKeyValues = function (dict) {
  91. expect(dict.get()).toBeUndefined();
  92. expect(dict.get('Prev')).toBeUndefined();
  93. expect(dict.get('Decode', 'D')).toBeUndefined();
  94. expect(dict.get('FontFile', 'FontFile2', 'FontFile3')).toBeNull();
  95. };
  96. var emptyDict, dictWithSizeKey, dictWithManyKeys;
  97. var storedSize = 42;
  98. var testFontFile = 'file1';
  99. var testFontFile2 = 'file2';
  100. var testFontFile3 = 'file3';
  101. beforeAll(function (done) {
  102. emptyDict = new Dict();
  103. dictWithSizeKey = new Dict();
  104. dictWithSizeKey.set('Size', storedSize);
  105. dictWithManyKeys = new Dict();
  106. dictWithManyKeys.set('FontFile', testFontFile);
  107. dictWithManyKeys.set('FontFile2', testFontFile2);
  108. dictWithManyKeys.set('FontFile3', testFontFile3);
  109. done();
  110. });
  111. afterAll(function () {
  112. emptyDict = dictWithSizeKey = dictWithManyKeys = null;
  113. });
  114. it('should return invalid values for unknown keys', function () {
  115. checkInvalidHasValues(emptyDict);
  116. checkInvalidKeyValues(emptyDict);
  117. });
  118. it('should return correct value for stored Size key', function () {
  119. expect(dictWithSizeKey.has('Size')).toBeTruthy();
  120. expect(dictWithSizeKey.get('Size')).toEqual(storedSize);
  121. expect(dictWithSizeKey.get('Prev', 'Size')).toEqual(storedSize);
  122. expect(dictWithSizeKey.get('Prev', 'Root', 'Size')).toEqual(storedSize);
  123. });
  124. it('should return invalid values for unknown keys when Size key is stored', function () {
  125. checkInvalidHasValues(dictWithSizeKey);
  126. checkInvalidKeyValues(dictWithSizeKey);
  127. });
  128. it('should return correct value for stored Size key with undefined value', function () {
  129. var dict = new Dict();
  130. dict.set('Size');
  131. expect(dict.has('Size')).toBeTruthy();
  132. checkInvalidKeyValues(dict);
  133. });
  134. it('should return correct values for multiple stored keys', function () {
  135. expect(dictWithManyKeys.has('FontFile')).toBeTruthy();
  136. expect(dictWithManyKeys.has('FontFile2')).toBeTruthy();
  137. expect(dictWithManyKeys.has('FontFile3')).toBeTruthy();
  138. expect(dictWithManyKeys.get('FontFile3')).toEqual(testFontFile3);
  139. expect(dictWithManyKeys.get('FontFile2', 'FontFile3')).toEqual(testFontFile2);
  140. expect(dictWithManyKeys.get('FontFile', 'FontFile2', 'FontFile3')).toEqual(testFontFile);
  141. });
  142. it('should asynchronously fetch unknown keys', function (done) {
  143. var keyPromises = [
  144. dictWithManyKeys.getAsync('Size'),
  145. dictWithSizeKey.getAsync('FontFile', 'FontFile2', 'FontFile3')
  146. ];
  147. Promise.all(keyPromises).then(function (values) {
  148. expect(values[0]).toBeUndefined();
  149. expect(values[1]).toBeNull();
  150. done();
  151. }).catch(function (reason) {
  152. done.fail(reason);
  153. });
  154. });
  155. it('should asynchronously fetch correct values for multiple stored keys', function (done) {
  156. var keyPromises = [
  157. dictWithManyKeys.getAsync('FontFile3'),
  158. dictWithManyKeys.getAsync('FontFile2', 'FontFile3'),
  159. dictWithManyKeys.getAsync('FontFile', 'FontFile2', 'FontFile3')
  160. ];
  161. Promise.all(keyPromises).then(function (values) {
  162. expect(values[0]).toEqual(testFontFile3);
  163. expect(values[1]).toEqual(testFontFile2);
  164. expect(values[2]).toEqual(testFontFile);
  165. done();
  166. }).catch(function (reason) {
  167. done.fail(reason);
  168. });
  169. });
  170. it('should callback for each stored key', function () {
  171. var callbackSpy = jasmine.createSpy('spy on callback in dictionary');
  172. dictWithManyKeys.forEach(callbackSpy);
  173. expect(callbackSpy).toHaveBeenCalled();
  174. var callbackSpyCalls = callbackSpy.calls;
  175. expect(callbackSpyCalls.argsFor(0)).toEqual([
  176. 'FontFile',
  177. testFontFile
  178. ]);
  179. expect(callbackSpyCalls.argsFor(1)).toEqual([
  180. 'FontFile2',
  181. testFontFile2
  182. ]);
  183. expect(callbackSpyCalls.argsFor(2)).toEqual([
  184. 'FontFile3',
  185. testFontFile3
  186. ]);
  187. expect(callbackSpyCalls.count()).toEqual(3);
  188. });
  189. it('should handle keys pointing to indirect objects, both sync and async', function (done) {
  190. var fontRef = new Ref(1, 0);
  191. var xref = new XRefMock([{
  192. ref: fontRef,
  193. data: testFontFile
  194. }]);
  195. var fontDict = new Dict(xref);
  196. fontDict.set('FontFile', fontRef);
  197. expect(fontDict.getRaw('FontFile')).toEqual(fontRef);
  198. expect(fontDict.get('FontFile', 'FontFile2', 'FontFile3')).toEqual(testFontFile);
  199. fontDict.getAsync('FontFile', 'FontFile2', 'FontFile3').then(function (value) {
  200. expect(value).toEqual(testFontFile);
  201. done();
  202. }).catch(function (reason) {
  203. done.fail(reason);
  204. });
  205. });
  206. it('should handle arrays containing indirect objects', function () {
  207. var minCoordRef = new Ref(1, 0), maxCoordRef = new Ref(2, 0);
  208. var minCoord = 0, maxCoord = 1;
  209. var xref = new XRefMock([
  210. {
  211. ref: minCoordRef,
  212. data: minCoord
  213. },
  214. {
  215. ref: maxCoordRef,
  216. data: maxCoord
  217. }
  218. ]);
  219. var xObjectDict = new Dict(xref);
  220. xObjectDict.set('BBox', [
  221. minCoord,
  222. maxCoord,
  223. minCoordRef,
  224. maxCoordRef
  225. ]);
  226. expect(xObjectDict.get('BBox')).toEqual([
  227. minCoord,
  228. maxCoord,
  229. minCoordRef,
  230. maxCoordRef
  231. ]);
  232. expect(xObjectDict.getArray('BBox')).toEqual([
  233. minCoord,
  234. maxCoord,
  235. minCoord,
  236. maxCoord
  237. ]);
  238. });
  239. it('should get all key names', function () {
  240. var expectedKeys = [
  241. 'FontFile',
  242. 'FontFile2',
  243. 'FontFile3'
  244. ];
  245. var keys = dictWithManyKeys.getKeys();
  246. expect(keys.sort()).toEqual(expectedKeys);
  247. });
  248. it('should create only one object for Dict.empty', function () {
  249. var firstDictEmpty = Dict.empty;
  250. var secondDictEmpty = Dict.empty;
  251. expect(firstDictEmpty).toBe(secondDictEmpty);
  252. expect(firstDictEmpty).not.toBe(emptyDict);
  253. });
  254. it('should correctly merge dictionaries', function () {
  255. var expectedKeys = [
  256. 'FontFile',
  257. 'FontFile2',
  258. 'FontFile3',
  259. 'Size'
  260. ];
  261. var fontFileDict = new Dict();
  262. fontFileDict.set('FontFile', 'Type1 font file');
  263. var mergedDict = Dict.merge(null, [
  264. dictWithManyKeys,
  265. dictWithSizeKey,
  266. fontFileDict
  267. ]);
  268. var mergedKeys = mergedDict.getKeys();
  269. expect(mergedKeys.sort()).toEqual(expectedKeys);
  270. expect(mergedDict.get('FontFile')).toEqual(testFontFile);
  271. });
  272. });
  273. describe('Ref', function () {
  274. it('should retain the stored values', function () {
  275. var storedNum = 4;
  276. var storedGen = 2;
  277. var ref = new Ref(storedNum, storedGen);
  278. expect(ref.num).toEqual(storedNum);
  279. expect(ref.gen).toEqual(storedGen);
  280. });
  281. });
  282. describe('RefSet', function () {
  283. it('should have a stored value', function () {
  284. var ref = new Ref(4, 2);
  285. var refset = new RefSet();
  286. refset.put(ref);
  287. expect(refset.has(ref)).toBeTruthy();
  288. });
  289. it('should not have an unknown value', function () {
  290. var ref = new Ref(4, 2);
  291. var refset = new RefSet();
  292. expect(refset.has(ref)).toBeFalsy();
  293. refset.put(ref);
  294. var anotherRef = new Ref(2, 4);
  295. expect(refset.has(anotherRef)).toBeFalsy();
  296. });
  297. });
  298. describe('isName', function () {
  299. it('handles non-names', function () {
  300. var nonName = {};
  301. expect(isName(nonName)).toEqual(false);
  302. });
  303. it('handles names', function () {
  304. var name = Name.get('Font');
  305. expect(isName(name)).toEqual(true);
  306. });
  307. it('handles names with name check', function () {
  308. var name = Name.get('Font');
  309. expect(isName(name, 'Font')).toEqual(true);
  310. expect(isName(name, 'Subtype')).toEqual(false);
  311. });
  312. });
  313. describe('isCmd', function () {
  314. it('handles non-commands', function () {
  315. var nonCmd = {};
  316. expect(isCmd(nonCmd)).toEqual(false);
  317. });
  318. it('handles commands', function () {
  319. var cmd = Cmd.get('BT');
  320. expect(isCmd(cmd)).toEqual(true);
  321. });
  322. it('handles commands with cmd check', function () {
  323. var cmd = Cmd.get('BT');
  324. expect(isCmd(cmd, 'BT')).toEqual(true);
  325. expect(isCmd(cmd, 'ET')).toEqual(false);
  326. });
  327. });
  328. describe('isDict', function () {
  329. it('handles non-dictionaries', function () {
  330. var nonDict = {};
  331. expect(isDict(nonDict)).toEqual(false);
  332. });
  333. it('handles empty dictionaries with type check', function () {
  334. var dict = Dict.empty;
  335. expect(isDict(dict)).toEqual(true);
  336. expect(isDict(dict, 'Page')).toEqual(false);
  337. });
  338. it('handles dictionaries with type check', function () {
  339. var dict = new Dict();
  340. dict.set('Type', Name.get('Page'));
  341. expect(isDict(dict, 'Page')).toEqual(true);
  342. expect(isDict(dict, 'Contents')).toEqual(false);
  343. });
  344. });
  345. describe('isRef', function () {
  346. it('handles non-refs', function () {
  347. var nonRef = {};
  348. expect(isRef(nonRef)).toEqual(false);
  349. });
  350. it('handles refs', function () {
  351. var ref = new Ref(1, 0);
  352. expect(isRef(ref)).toEqual(true);
  353. });
  354. });
  355. describe('isRefsEqual', function () {
  356. it('should handle different Refs pointing to the same object', function () {
  357. var ref1 = new Ref(1, 0);
  358. var ref2 = new Ref(1, 0);
  359. expect(isRefsEqual(ref1, ref2)).toEqual(true);
  360. });
  361. it('should handle Refs pointing to different objects', function () {
  362. var ref1 = new Ref(1, 0);
  363. var ref2 = new Ref(2, 0);
  364. expect(isRefsEqual(ref1, ref2)).toEqual(false);
  365. });
  366. });
  367. });