core_utils_spec.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * JavaScript code in this page
  4. *
  5. * Copyright 2022 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * JavaScript code in this page
  21. */
  22. "use strict";
  23. var _primitives = require("../../core/primitives.js");
  24. var _core_utils = require("../../core/core_utils.js");
  25. var _test_utils = require("./test_utils.js");
  26. describe("core_utils", function () {
  27. describe("getInheritableProperty", function () {
  28. it("handles non-dictionary arguments", function () {
  29. expect((0, _core_utils.getInheritableProperty)({
  30. dict: null,
  31. key: "foo"
  32. })).toEqual(undefined);
  33. expect((0, _core_utils.getInheritableProperty)({
  34. dict: undefined,
  35. key: "foo"
  36. })).toEqual(undefined);
  37. });
  38. it("handles dictionaries that do not contain the property", function () {
  39. const emptyDict = new _primitives.Dict();
  40. expect((0, _core_utils.getInheritableProperty)({
  41. dict: emptyDict,
  42. key: "foo"
  43. })).toEqual(undefined);
  44. const filledDict = new _primitives.Dict();
  45. filledDict.set("bar", "baz");
  46. expect((0, _core_utils.getInheritableProperty)({
  47. dict: filledDict,
  48. key: "foo"
  49. })).toEqual(undefined);
  50. });
  51. it("fetches the property if it is not inherited", function () {
  52. const ref = _primitives.Ref.get(10, 0);
  53. const xref = new _test_utils.XRefMock([{
  54. ref,
  55. data: "quux"
  56. }]);
  57. const dict = new _primitives.Dict(xref);
  58. dict.set("foo", "bar");
  59. expect((0, _core_utils.getInheritableProperty)({
  60. dict,
  61. key: "foo"
  62. })).toEqual("bar");
  63. dict.set("baz", ["qux", ref]);
  64. expect((0, _core_utils.getInheritableProperty)({
  65. dict,
  66. key: "baz",
  67. getArray: true
  68. })).toEqual(["qux", "quux"]);
  69. });
  70. it("fetches the property if it is inherited and present on one level", function () {
  71. const ref = _primitives.Ref.get(10, 0);
  72. const xref = new _test_utils.XRefMock([{
  73. ref,
  74. data: "quux"
  75. }]);
  76. const firstDict = new _primitives.Dict(xref);
  77. const secondDict = new _primitives.Dict(xref);
  78. firstDict.set("Parent", secondDict);
  79. secondDict.set("foo", "bar");
  80. expect((0, _core_utils.getInheritableProperty)({
  81. dict: firstDict,
  82. key: "foo"
  83. })).toEqual("bar");
  84. secondDict.set("baz", ["qux", ref]);
  85. expect((0, _core_utils.getInheritableProperty)({
  86. dict: firstDict,
  87. key: "baz",
  88. getArray: true
  89. })).toEqual(["qux", "quux"]);
  90. });
  91. it("fetches the property if it is inherited and present on multiple levels", function () {
  92. const ref = _primitives.Ref.get(10, 0);
  93. const xref = new _test_utils.XRefMock([{
  94. ref,
  95. data: "quux"
  96. }]);
  97. const firstDict = new _primitives.Dict(xref);
  98. const secondDict = new _primitives.Dict(xref);
  99. firstDict.set("Parent", secondDict);
  100. firstDict.set("foo", "bar1");
  101. secondDict.set("foo", "bar2");
  102. expect((0, _core_utils.getInheritableProperty)({
  103. dict: firstDict,
  104. key: "foo"
  105. })).toEqual("bar1");
  106. expect((0, _core_utils.getInheritableProperty)({
  107. dict: firstDict,
  108. key: "foo",
  109. getArray: false,
  110. stopWhenFound: false
  111. })).toEqual(["bar1", "bar2"]);
  112. firstDict.set("baz", ["qux1", ref]);
  113. secondDict.set("baz", ["qux2", ref]);
  114. expect((0, _core_utils.getInheritableProperty)({
  115. dict: firstDict,
  116. key: "baz",
  117. getArray: true,
  118. stopWhenFound: false
  119. })).toEqual([["qux1", "quux"], ["qux2", "quux"]]);
  120. });
  121. });
  122. describe("toRomanNumerals", function () {
  123. it("handles invalid arguments", function () {
  124. for (const input of ["foo", -1, 0]) {
  125. expect(function () {
  126. (0, _core_utils.toRomanNumerals)(input);
  127. }).toThrow(new Error("The number should be a positive integer."));
  128. }
  129. });
  130. it("converts numbers to uppercase Roman numerals", function () {
  131. expect((0, _core_utils.toRomanNumerals)(1)).toEqual("I");
  132. expect((0, _core_utils.toRomanNumerals)(6)).toEqual("VI");
  133. expect((0, _core_utils.toRomanNumerals)(7)).toEqual("VII");
  134. expect((0, _core_utils.toRomanNumerals)(8)).toEqual("VIII");
  135. expect((0, _core_utils.toRomanNumerals)(10)).toEqual("X");
  136. expect((0, _core_utils.toRomanNumerals)(40)).toEqual("XL");
  137. expect((0, _core_utils.toRomanNumerals)(100)).toEqual("C");
  138. expect((0, _core_utils.toRomanNumerals)(500)).toEqual("D");
  139. expect((0, _core_utils.toRomanNumerals)(1000)).toEqual("M");
  140. expect((0, _core_utils.toRomanNumerals)(2019)).toEqual("MMXIX");
  141. });
  142. it("converts numbers to lowercase Roman numerals", function () {
  143. expect((0, _core_utils.toRomanNumerals)(1, true)).toEqual("i");
  144. expect((0, _core_utils.toRomanNumerals)(6, true)).toEqual("vi");
  145. expect((0, _core_utils.toRomanNumerals)(7, true)).toEqual("vii");
  146. expect((0, _core_utils.toRomanNumerals)(8, true)).toEqual("viii");
  147. expect((0, _core_utils.toRomanNumerals)(10, true)).toEqual("x");
  148. expect((0, _core_utils.toRomanNumerals)(40, true)).toEqual("xl");
  149. expect((0, _core_utils.toRomanNumerals)(100, true)).toEqual("c");
  150. expect((0, _core_utils.toRomanNumerals)(500, true)).toEqual("d");
  151. expect((0, _core_utils.toRomanNumerals)(1000, true)).toEqual("m");
  152. expect((0, _core_utils.toRomanNumerals)(2019, true)).toEqual("mmxix");
  153. });
  154. });
  155. describe("log2", function () {
  156. it("handles values smaller than/equal to zero", function () {
  157. expect((0, _core_utils.log2)(0)).toEqual(0);
  158. expect((0, _core_utils.log2)(-1)).toEqual(0);
  159. });
  160. it("handles values larger than zero", function () {
  161. expect((0, _core_utils.log2)(1)).toEqual(0);
  162. expect((0, _core_utils.log2)(2)).toEqual(1);
  163. expect((0, _core_utils.log2)(3)).toEqual(2);
  164. expect((0, _core_utils.log2)(3.14)).toEqual(2);
  165. });
  166. });
  167. describe("isWhiteSpace", function () {
  168. it("handles space characters", function () {
  169. expect((0, _core_utils.isWhiteSpace)(0x20)).toEqual(true);
  170. expect((0, _core_utils.isWhiteSpace)(0x09)).toEqual(true);
  171. expect((0, _core_utils.isWhiteSpace)(0x0d)).toEqual(true);
  172. expect((0, _core_utils.isWhiteSpace)(0x0a)).toEqual(true);
  173. });
  174. it("handles non-space characters", function () {
  175. expect((0, _core_utils.isWhiteSpace)(0x0b)).toEqual(false);
  176. expect((0, _core_utils.isWhiteSpace)(null)).toEqual(false);
  177. expect((0, _core_utils.isWhiteSpace)(undefined)).toEqual(false);
  178. });
  179. });
  180. describe("parseXFAPath", function () {
  181. it("should get a correctly parsed path", function () {
  182. const path = "foo.bar[12].oof[3].rab.FOO[123].BAR[456]";
  183. expect((0, _core_utils.parseXFAPath)(path)).toEqual([{
  184. name: "foo",
  185. pos: 0
  186. }, {
  187. name: "bar",
  188. pos: 12
  189. }, {
  190. name: "oof",
  191. pos: 3
  192. }, {
  193. name: "rab",
  194. pos: 0
  195. }, {
  196. name: "FOO",
  197. pos: 123
  198. }, {
  199. name: "BAR",
  200. pos: 456
  201. }]);
  202. });
  203. });
  204. describe("escapePDFName", function () {
  205. it("should escape PDF name", function () {
  206. expect((0, _core_utils.escapePDFName)("hello")).toEqual("hello");
  207. expect((0, _core_utils.escapePDFName)("\xfehello")).toEqual("#fehello");
  208. expect((0, _core_utils.escapePDFName)("he\xfell\xffo")).toEqual("he#fell#ffo");
  209. expect((0, _core_utils.escapePDFName)("\xfehe\xfell\xffo\xff")).toEqual("#fehe#fell#ffo#ff");
  210. expect((0, _core_utils.escapePDFName)("#h#e#l#l#o")).toEqual("#23h#23e#23l#23l#23o");
  211. expect((0, _core_utils.escapePDFName)("#()<>[]{}/%")).toEqual("#23#28#29#3c#3e#5b#5d#7b#7d#2f#25");
  212. });
  213. });
  214. describe("escapeString", function () {
  215. it("should escape (, ), \\n, \\r, and \\", function () {
  216. expect((0, _core_utils.escapeString)("((a\\a))\n(b(b\\b)\rb)")).toEqual("\\(\\(a\\\\a\\)\\)\\n\\(b\\(b\\\\b\\)\\rb\\)");
  217. });
  218. });
  219. describe("encodeToXmlString", function () {
  220. it("should get a correctly encoded string with some entities", function () {
  221. const str = "\"\u0397ell😂' & <W😂rld>";
  222. expect((0, _core_utils.encodeToXmlString)(str)).toEqual("&quot;&#x397;ell&#x1F602;&apos; &amp; &lt;W&#x1F602;rld&gt;");
  223. });
  224. it("should get a correctly encoded basic ascii string", function () {
  225. const str = "hello world";
  226. expect((0, _core_utils.encodeToXmlString)(str)).toEqual(str);
  227. });
  228. });
  229. describe("validateCSSFont", function () {
  230. it("Check font family", function () {
  231. const cssFontInfo = {
  232. fontFamily: `"blah blah " blah blah"`,
  233. fontWeight: 0,
  234. italicAngle: 0
  235. };
  236. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  237. cssFontInfo.fontFamily = `"blah blah \\" blah blah"`;
  238. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(true);
  239. cssFontInfo.fontFamily = `'blah blah ' blah blah'`;
  240. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  241. cssFontInfo.fontFamily = `'blah blah \\' blah blah'`;
  242. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(true);
  243. cssFontInfo.fontFamily = `"blah blah `;
  244. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  245. cssFontInfo.fontFamily = `blah blah"`;
  246. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  247. cssFontInfo.fontFamily = `'blah blah `;
  248. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  249. cssFontInfo.fontFamily = `blah blah'`;
  250. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  251. cssFontInfo.fontFamily = "blah blah blah";
  252. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(true);
  253. cssFontInfo.fontFamily = "blah 0blah blah";
  254. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  255. cssFontInfo.fontFamily = "blah blah -0blah";
  256. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  257. cssFontInfo.fontFamily = "blah blah --blah";
  258. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  259. cssFontInfo.fontFamily = "blah blah -blah";
  260. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(true);
  261. cssFontInfo.fontFamily = "blah fdqAJqjHJK23kl23__--Kj blah";
  262. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(true);
  263. cssFontInfo.fontFamily = "blah fdqAJqjH$JK23kl23__--Kj blah";
  264. expect((0, _core_utils.validateCSSFont)(cssFontInfo)).toEqual(false);
  265. });
  266. it("Check font weight", function () {
  267. const cssFontInfo = {
  268. fontFamily: "blah",
  269. fontWeight: 100,
  270. italicAngle: 0
  271. };
  272. (0, _core_utils.validateCSSFont)(cssFontInfo);
  273. expect(cssFontInfo.fontWeight).toEqual("100");
  274. cssFontInfo.fontWeight = "700";
  275. (0, _core_utils.validateCSSFont)(cssFontInfo);
  276. expect(cssFontInfo.fontWeight).toEqual("700");
  277. cssFontInfo.fontWeight = "normal";
  278. (0, _core_utils.validateCSSFont)(cssFontInfo);
  279. expect(cssFontInfo.fontWeight).toEqual("normal");
  280. cssFontInfo.fontWeight = 314;
  281. (0, _core_utils.validateCSSFont)(cssFontInfo);
  282. expect(cssFontInfo.fontWeight).toEqual("400");
  283. });
  284. it("Check italic angle", function () {
  285. const cssFontInfo = {
  286. fontFamily: "blah",
  287. fontWeight: 100,
  288. italicAngle: 10
  289. };
  290. (0, _core_utils.validateCSSFont)(cssFontInfo);
  291. expect(cssFontInfo.italicAngle).toEqual("10");
  292. cssFontInfo.italicAngle = -123;
  293. (0, _core_utils.validateCSSFont)(cssFontInfo);
  294. expect(cssFontInfo.italicAngle).toEqual("14");
  295. cssFontInfo.italicAngle = "91";
  296. (0, _core_utils.validateCSSFont)(cssFontInfo);
  297. expect(cssFontInfo.italicAngle).toEqual("14");
  298. cssFontInfo.italicAngle = 2.718;
  299. (0, _core_utils.validateCSSFont)(cssFontInfo);
  300. expect(cssFontInfo.italicAngle).toEqual("2.718");
  301. });
  302. });
  303. describe("isAscii", function () {
  304. it("handles ascii/non-ascii strings", function () {
  305. expect((0, _core_utils.isAscii)("hello world")).toEqual(true);
  306. expect((0, _core_utils.isAscii)("こんにちは世界の")).toEqual(false);
  307. expect((0, _core_utils.isAscii)("hello world in Japanese is こんにちは世界の")).toEqual(false);
  308. });
  309. });
  310. describe("stringToUTF16HexString", function () {
  311. it("should encode a string in UTF16 hexadecimal format", function () {
  312. expect((0, _core_utils.stringToUTF16HexString)("hello world")).toEqual("00680065006c006c006f00200077006f0072006c0064");
  313. expect((0, _core_utils.stringToUTF16HexString)("こんにちは世界の")).toEqual("30533093306b3061306f4e16754c306e");
  314. });
  315. });
  316. describe("stringToUTF16String", function () {
  317. it("should encode a string in UTF16", function () {
  318. expect((0, _core_utils.stringToUTF16String)("hello world")).toEqual("\0h\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d");
  319. expect((0, _core_utils.stringToUTF16String)("こんにちは世界の")).toEqual("\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e");
  320. });
  321. it("should encode a string in UTF16BE with a BOM", function () {
  322. expect((0, _core_utils.stringToUTF16String)("hello world", true)).toEqual("\xfe\xff\0h\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d");
  323. expect((0, _core_utils.stringToUTF16String)("こんにちは世界の", true)).toEqual("\xfe\xff\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e");
  324. });
  325. });
  326. });