function_spec.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  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 _function = require('../../core/function');
  17. var _ps_parser = require('../../core/ps_parser');
  18. var _stream = require('../../core/stream');
  19. describe('function', function () {
  20. beforeEach(function () {
  21. jasmine.addMatchers({
  22. toMatchArray: function toMatchArray(util, customEqualityTesters) {
  23. return {
  24. compare: function compare(actual, expected) {
  25. var result = {};
  26. if (actual.length !== expected.length) {
  27. result.pass = false;
  28. result.message = 'Array length: ' + actual.length + ', expected: ' + expected.length;
  29. return result;
  30. }
  31. result.pass = true;
  32. for (var i = 0; i < expected.length; i++) {
  33. var a = actual[i],
  34. b = expected[i];
  35. if (Array.isArray(b)) {
  36. if (a.length !== b.length) {
  37. result.pass = false;
  38. break;
  39. }
  40. for (var j = 0; j < a.length; j++) {
  41. var suba = a[j],
  42. subb = b[j];
  43. if (suba !== subb) {
  44. result.pass = false;
  45. break;
  46. }
  47. }
  48. } else {
  49. if (a !== b) {
  50. result.pass = false;
  51. break;
  52. }
  53. }
  54. }
  55. return result;
  56. }
  57. };
  58. }
  59. });
  60. });
  61. describe('PostScriptParser', function () {
  62. function parse(program) {
  63. var stream = new _stream.StringStream(program);
  64. var parser = new _ps_parser.PostScriptParser(new _ps_parser.PostScriptLexer(stream));
  65. return parser.parse();
  66. }
  67. it('parses empty programs', function () {
  68. var output = parse('{}');
  69. expect(output.length).toEqual(0);
  70. });
  71. it('parses positive numbers', function () {
  72. var number = 999;
  73. var program = parse('{ ' + number + ' }');
  74. var expectedProgram = [number];
  75. expect(program).toMatchArray(expectedProgram);
  76. });
  77. it('parses negative numbers', function () {
  78. var number = -999;
  79. var program = parse('{ ' + number + ' }');
  80. var expectedProgram = [number];
  81. expect(program).toMatchArray(expectedProgram);
  82. });
  83. it('parses negative floats', function () {
  84. var number = 3.3;
  85. var program = parse('{ ' + number + ' }');
  86. var expectedProgram = [number];
  87. expect(program).toMatchArray(expectedProgram);
  88. });
  89. it('parses operators', function () {
  90. var program = parse('{ sub }');
  91. var expectedProgram = ['sub'];
  92. expect(program).toMatchArray(expectedProgram);
  93. });
  94. it('parses if statements', function () {
  95. var program = parse('{ { 99 } if }');
  96. var expectedProgram = [3, 'jz', 99];
  97. expect(program).toMatchArray(expectedProgram);
  98. });
  99. it('parses ifelse statements', function () {
  100. var program = parse('{ { 99 } { 44 } ifelse }');
  101. var expectedProgram = [5, 'jz', 99, 6, 'j', 44];
  102. expect(program).toMatchArray(expectedProgram);
  103. });
  104. it('handles missing brackets', function () {
  105. expect(function () {
  106. parse('{');
  107. }).toThrow(new Error('Unexpected symbol: found undefined expected 1.'));
  108. });
  109. it('handles junk after the end', function () {
  110. var number = 3.3;
  111. var program = parse('{ ' + number + ' }#');
  112. var expectedProgram = [number];
  113. expect(program).toMatchArray(expectedProgram);
  114. });
  115. });
  116. describe('PostScriptEvaluator', function () {
  117. function evaluate(program) {
  118. var stream = new _stream.StringStream(program);
  119. var parser = new _ps_parser.PostScriptParser(new _ps_parser.PostScriptLexer(stream));
  120. var code = parser.parse();
  121. var evaluator = new _function.PostScriptEvaluator(code);
  122. var output = evaluator.execute();
  123. return output;
  124. }
  125. it('pushes stack', function () {
  126. var stack = evaluate('{ 99 }');
  127. var expectedStack = [99];
  128. expect(stack).toMatchArray(expectedStack);
  129. });
  130. it('handles if with true', function () {
  131. var stack = evaluate('{ 1 {99} if }');
  132. var expectedStack = [99];
  133. expect(stack).toMatchArray(expectedStack);
  134. });
  135. it('handles if with false', function () {
  136. var stack = evaluate('{ 0 {99} if }');
  137. var expectedStack = [];
  138. expect(stack).toMatchArray(expectedStack);
  139. });
  140. it('handles ifelse with true', function () {
  141. var stack = evaluate('{ 1 {99} {77} ifelse }');
  142. var expectedStack = [99];
  143. expect(stack).toMatchArray(expectedStack);
  144. });
  145. it('handles ifelse with false', function () {
  146. var stack = evaluate('{ 0 {99} {77} ifelse }');
  147. var expectedStack = [77];
  148. expect(stack).toMatchArray(expectedStack);
  149. });
  150. it('handles nested if', function () {
  151. var stack = evaluate('{ 1 {1 {77} if} if }');
  152. var expectedStack = [77];
  153. expect(stack).toMatchArray(expectedStack);
  154. });
  155. it('abs', function () {
  156. var stack = evaluate('{ -2 abs }');
  157. var expectedStack = [2];
  158. expect(stack).toMatchArray(expectedStack);
  159. });
  160. it('adds', function () {
  161. var stack = evaluate('{ 1 2 add }');
  162. var expectedStack = [3];
  163. expect(stack).toMatchArray(expectedStack);
  164. });
  165. it('boolean and', function () {
  166. var stack = evaluate('{ true false and }');
  167. var expectedStack = [false];
  168. expect(stack).toMatchArray(expectedStack);
  169. });
  170. it('bitwise and', function () {
  171. var stack = evaluate('{ 254 1 and }');
  172. var expectedStack = [254 & 1];
  173. expect(stack).toMatchArray(expectedStack);
  174. });
  175. it('calculates the inverse tangent of a number', function () {
  176. var stack = evaluate('{ 90 atan }');
  177. var expectedStack = [Math.atan(90)];
  178. expect(stack).toMatchArray(expectedStack);
  179. });
  180. it('handles bitshifting ', function () {
  181. var stack = evaluate('{ 50 2 bitshift }');
  182. var expectedStack = [200];
  183. expect(stack).toMatchArray(expectedStack);
  184. });
  185. it('calculates the ceiling value', function () {
  186. var stack = evaluate('{ 9.9 ceiling }');
  187. var expectedStack = [10];
  188. expect(stack).toMatchArray(expectedStack);
  189. });
  190. it('copies', function () {
  191. var stack = evaluate('{ 99 98 2 copy }');
  192. var expectedStack = [99, 98, 99, 98];
  193. expect(stack).toMatchArray(expectedStack);
  194. });
  195. it('calculates the cosine of a number', function () {
  196. var stack = evaluate('{ 90 cos }');
  197. var expectedStack = [Math.cos(90)];
  198. expect(stack).toMatchArray(expectedStack);
  199. });
  200. it('converts to int', function () {
  201. var stack = evaluate('{ 9.9 cvi }');
  202. var expectedStack = [9];
  203. expect(stack).toMatchArray(expectedStack);
  204. });
  205. it('converts negatives to int', function () {
  206. var stack = evaluate('{ -9.9 cvi }');
  207. var expectedStack = [-9];
  208. expect(stack).toMatchArray(expectedStack);
  209. });
  210. it('converts to real', function () {
  211. var stack = evaluate('{ 55.34 cvr }');
  212. var expectedStack = [55.34];
  213. expect(stack).toMatchArray(expectedStack);
  214. });
  215. it('divides', function () {
  216. var stack = evaluate('{ 6 5 div }');
  217. var expectedStack = [1.2];
  218. expect(stack).toMatchArray(expectedStack);
  219. });
  220. it('maps division by zero to infinity', function () {
  221. var stack = evaluate('{ 6 0 div }');
  222. var expectedStack = [Infinity];
  223. expect(stack).toMatchArray(expectedStack);
  224. });
  225. it('duplicates', function () {
  226. var stack = evaluate('{ 99 dup }');
  227. var expectedStack = [99, 99];
  228. expect(stack).toMatchArray(expectedStack);
  229. });
  230. it('accepts an equality', function () {
  231. var stack = evaluate('{ 9 9 eq }');
  232. var expectedStack = [true];
  233. expect(stack).toMatchArray(expectedStack);
  234. });
  235. it('rejects an inequality', function () {
  236. var stack = evaluate('{ 9 8 eq }');
  237. var expectedStack = [false];
  238. expect(stack).toMatchArray(expectedStack);
  239. });
  240. it('exchanges', function () {
  241. var stack = evaluate('{ 44 99 exch }');
  242. var expectedStack = [99, 44];
  243. expect(stack).toMatchArray(expectedStack);
  244. });
  245. it('handles exponentiation', function () {
  246. var stack = evaluate('{ 10 2 exp }');
  247. var expectedStack = [100];
  248. expect(stack).toMatchArray(expectedStack);
  249. });
  250. it('pushes false onto the stack', function () {
  251. var stack = evaluate('{ false }');
  252. var expectedStack = [false];
  253. expect(stack).toMatchArray(expectedStack);
  254. });
  255. it('calculates the floor value', function () {
  256. var stack = evaluate('{ 9.9 floor }');
  257. var expectedStack = [9];
  258. expect(stack).toMatchArray(expectedStack);
  259. });
  260. it('handles greater than or equal to', function () {
  261. var stack = evaluate('{ 10 9 ge }');
  262. var expectedStack = [true];
  263. expect(stack).toMatchArray(expectedStack);
  264. });
  265. it('rejects less than for greater than or equal to', function () {
  266. var stack = evaluate('{ 8 9 ge }');
  267. var expectedStack = [false];
  268. expect(stack).toMatchArray(expectedStack);
  269. });
  270. it('handles greater than', function () {
  271. var stack = evaluate('{ 10 9 gt }');
  272. var expectedStack = [true];
  273. expect(stack).toMatchArray(expectedStack);
  274. });
  275. it('rejects less than or equal for greater than', function () {
  276. var stack = evaluate('{ 9 9 gt }');
  277. var expectedStack = [false];
  278. expect(stack).toMatchArray(expectedStack);
  279. });
  280. it('divides to integer', function () {
  281. var stack = evaluate('{ 2 3 idiv }');
  282. var expectedStack = [0];
  283. expect(stack).toMatchArray(expectedStack);
  284. });
  285. it('divides to negative integer', function () {
  286. var stack = evaluate('{ -2 3 idiv }');
  287. var expectedStack = [0];
  288. expect(stack).toMatchArray(expectedStack);
  289. });
  290. it('duplicates index', function () {
  291. var stack = evaluate('{ 4 3 2 1 2 index }');
  292. var expectedStack = [4, 3, 2, 1, 3];
  293. expect(stack).toMatchArray(expectedStack);
  294. });
  295. it('handles less than or equal to', function () {
  296. var stack = evaluate('{ 9 10 le }');
  297. var expectedStack = [true];
  298. expect(stack).toMatchArray(expectedStack);
  299. });
  300. it('rejects greater than for less than or equal to', function () {
  301. var stack = evaluate('{ 10 9 le }');
  302. var expectedStack = [false];
  303. expect(stack).toMatchArray(expectedStack);
  304. });
  305. it('calculates the natural logarithm', function () {
  306. var stack = evaluate('{ 10 ln }');
  307. var expectedStack = [Math.log(10)];
  308. expect(stack).toMatchArray(expectedStack);
  309. });
  310. it('calculates the base 10 logarithm', function () {
  311. var stack = evaluate('{ 100 log }');
  312. var expectedStack = [2];
  313. expect(stack).toMatchArray(expectedStack);
  314. });
  315. it('handles less than', function () {
  316. var stack = evaluate('{ 9 10 lt }');
  317. var expectedStack = [true];
  318. expect(stack).toMatchArray(expectedStack);
  319. });
  320. it('rejects greater than or equal to for less than', function () {
  321. var stack = evaluate('{ 10 9 lt }');
  322. var expectedStack = [false];
  323. expect(stack).toMatchArray(expectedStack);
  324. });
  325. it('performs the modulo operation', function () {
  326. var stack = evaluate('{ 4 3 mod }');
  327. var expectedStack = [1];
  328. expect(stack).toMatchArray(expectedStack);
  329. });
  330. it('multiplies two numbers (positive result)', function () {
  331. var stack = evaluate('{ 9 8 mul }');
  332. var expectedStack = [72];
  333. expect(stack).toMatchArray(expectedStack);
  334. });
  335. it('multiplies two numbers (negative result)', function () {
  336. var stack = evaluate('{ 9 -8 mul }');
  337. var expectedStack = [-72];
  338. expect(stack).toMatchArray(expectedStack);
  339. });
  340. it('accepts an inequality', function () {
  341. var stack = evaluate('{ 9 8 ne }');
  342. var expectedStack = [true];
  343. expect(stack).toMatchArray(expectedStack);
  344. });
  345. it('rejects an equality', function () {
  346. var stack = evaluate('{ 9 9 ne }');
  347. var expectedStack = [false];
  348. expect(stack).toMatchArray(expectedStack);
  349. });
  350. it('negates', function () {
  351. var stack = evaluate('{ 4.5 neg }');
  352. var expectedStack = [-4.5];
  353. expect(stack).toMatchArray(expectedStack);
  354. });
  355. it('boolean not', function () {
  356. var stack = evaluate('{ true not }');
  357. var expectedStack = [false];
  358. expect(stack).toMatchArray(expectedStack);
  359. });
  360. it('bitwise not', function () {
  361. var stack = evaluate('{ 12 not }');
  362. var expectedStack = [-13];
  363. expect(stack).toMatchArray(expectedStack);
  364. });
  365. it('boolean or', function () {
  366. var stack = evaluate('{ true false or }');
  367. var expectedStack = [true];
  368. expect(stack).toMatchArray(expectedStack);
  369. });
  370. it('bitwise or', function () {
  371. var stack = evaluate('{ 254 1 or }');
  372. var expectedStack = [254 | 1];
  373. expect(stack).toMatchArray(expectedStack);
  374. });
  375. it('pops stack', function () {
  376. var stack = evaluate('{ 1 2 pop }');
  377. var expectedStack = [1];
  378. expect(stack).toMatchArray(expectedStack);
  379. });
  380. it('rolls stack right', function () {
  381. var stack = evaluate('{ 1 3 2 2 4 1 roll }');
  382. var expectedStack = [2, 1, 3, 2];
  383. expect(stack).toMatchArray(expectedStack);
  384. });
  385. it('rolls stack left', function () {
  386. var stack = evaluate('{ 1 3 2 2 4 -1 roll }');
  387. var expectedStack = [3, 2, 2, 1];
  388. expect(stack).toMatchArray(expectedStack);
  389. });
  390. it('rounds a number', function () {
  391. var stack = evaluate('{ 9.52 round }');
  392. var expectedStack = [10];
  393. expect(stack).toMatchArray(expectedStack);
  394. });
  395. it('calculates the sine of a number', function () {
  396. var stack = evaluate('{ 90 sin }');
  397. var expectedStack = [Math.sin(90)];
  398. expect(stack).toMatchArray(expectedStack);
  399. });
  400. it('calculates a square root (integer)', function () {
  401. var stack = evaluate('{ 100 sqrt }');
  402. var expectedStack = [10];
  403. expect(stack).toMatchArray(expectedStack);
  404. });
  405. it('calculates a square root (float)', function () {
  406. var stack = evaluate('{ 99 sqrt }');
  407. var expectedStack = [Math.sqrt(99)];
  408. expect(stack).toMatchArray(expectedStack);
  409. });
  410. it('subtracts (positive result)', function () {
  411. var stack = evaluate('{ 6 4 sub }');
  412. var expectedStack = [2];
  413. expect(stack).toMatchArray(expectedStack);
  414. });
  415. it('subtracts (negative result)', function () {
  416. var stack = evaluate('{ 4 6 sub }');
  417. var expectedStack = [-2];
  418. expect(stack).toMatchArray(expectedStack);
  419. });
  420. it('pushes true onto the stack', function () {
  421. var stack = evaluate('{ true }');
  422. var expectedStack = [true];
  423. expect(stack).toMatchArray(expectedStack);
  424. });
  425. it('truncates a number', function () {
  426. var stack = evaluate('{ 35.004 truncate }');
  427. var expectedStack = [35];
  428. expect(stack).toMatchArray(expectedStack);
  429. });
  430. it('calculates an exclusive or value', function () {
  431. var stack = evaluate('{ 3 9 xor }');
  432. var expectedStack = [10];
  433. expect(stack).toMatchArray(expectedStack);
  434. });
  435. });
  436. describe('PostScriptCompiler', function () {
  437. function check(code, domain, range, samples) {
  438. var compiler = new _function.PostScriptCompiler();
  439. var compiledCode = compiler.compile(code, domain, range);
  440. if (samples === null) {
  441. expect(compiledCode).toBeNull();
  442. } else {
  443. expect(compiledCode).not.toBeNull();
  444. var fn = new Function('src', 'srcOffset', 'dest', 'destOffset', compiledCode);
  445. for (var i = 0; i < samples.length; i++) {
  446. var out = new Float32Array(samples[i].output.length);
  447. fn(samples[i].input, 0, out, 0);
  448. expect(Array.prototype.slice.call(out, 0)).toMatchArray(samples[i].output);
  449. }
  450. }
  451. }
  452. it('check compiled add', function () {
  453. check([0.25, 0.5, 'add'], [], [0, 1], [{
  454. input: [],
  455. output: [0.75]
  456. }]);
  457. check([0, 'add'], [0, 1], [0, 1], [{
  458. input: [0.25],
  459. output: [0.25]
  460. }]);
  461. check([0.5, 'add'], [0, 1], [0, 1], [{
  462. input: [0.25],
  463. output: [0.75]
  464. }]);
  465. check([0, 'exch', 'add'], [0, 1], [0, 1], [{
  466. input: [0.25],
  467. output: [0.25]
  468. }]);
  469. check([0.5, 'exch', 'add'], [0, 1], [0, 1], [{
  470. input: [0.25],
  471. output: [0.75]
  472. }]);
  473. check(['add'], [0, 1, 0, 1], [0, 1], [{
  474. input: [0.25, 0.5],
  475. output: [0.75]
  476. }]);
  477. check(['add'], [0, 1], [0, 1], null);
  478. });
  479. it('check compiled sub', function () {
  480. check([0.5, 0.25, 'sub'], [], [0, 1], [{
  481. input: [],
  482. output: [0.25]
  483. }]);
  484. check([0, 'sub'], [0, 1], [0, 1], [{
  485. input: [0.25],
  486. output: [0.25]
  487. }]);
  488. check([0.5, 'sub'], [0, 1], [0, 1], [{
  489. input: [0.75],
  490. output: [0.25]
  491. }]);
  492. check([0, 'exch', 'sub'], [0, 1], [-1, 1], [{
  493. input: [0.25],
  494. output: [-0.25]
  495. }]);
  496. check([0.75, 'exch', 'sub'], [0, 1], [-1, 1], [{
  497. input: [0.25],
  498. output: [0.5]
  499. }]);
  500. check(['sub'], [0, 1, 0, 1], [-1, 1], [{
  501. input: [0.25, 0.5],
  502. output: [-0.25]
  503. }]);
  504. check(['sub'], [0, 1], [0, 1], null);
  505. check([1, 'dup', 3, 2, 'roll', 'sub', 'sub'], [0, 1], [0, 1], [{
  506. input: [0.75],
  507. output: [0.75]
  508. }]);
  509. });
  510. it('check compiled mul', function () {
  511. check([0.25, 0.5, 'mul'], [], [0, 1], [{
  512. input: [],
  513. output: [0.125]
  514. }]);
  515. check([0, 'mul'], [0, 1], [0, 1], [{
  516. input: [0.25],
  517. output: [0]
  518. }]);
  519. check([0.5, 'mul'], [0, 1], [0, 1], [{
  520. input: [0.25],
  521. output: [0.125]
  522. }]);
  523. check([1, 'mul'], [0, 1], [0, 1], [{
  524. input: [0.25],
  525. output: [0.25]
  526. }]);
  527. check([0, 'exch', 'mul'], [0, 1], [0, 1], [{
  528. input: [0.25],
  529. output: [0]
  530. }]);
  531. check([0.5, 'exch', 'mul'], [0, 1], [0, 1], [{
  532. input: [0.25],
  533. output: [0.125]
  534. }]);
  535. check([1, 'exch', 'mul'], [0, 1], [0, 1], [{
  536. input: [0.25],
  537. output: [0.25]
  538. }]);
  539. check(['mul'], [0, 1, 0, 1], [0, 1], [{
  540. input: [0.25, 0.5],
  541. output: [0.125]
  542. }]);
  543. check(['mul'], [0, 1], [0, 1], null);
  544. });
  545. it('check compiled max', function () {
  546. check(['dup', 0.75, 'gt', 7, 'jz', 'pop', 0.75], [0, 1], [0, 1], [{
  547. input: [0.5],
  548. output: [0.5]
  549. }]);
  550. check(['dup', 0.75, 'gt', 7, 'jz', 'pop', 0.75], [0, 1], [0, 1], [{
  551. input: [1],
  552. output: [0.75]
  553. }]);
  554. check(['dup', 0.75, 'gt', 5, 'jz', 'pop', 0.75], [0, 1], [0, 1], null);
  555. });
  556. it('check pop/roll/index', function () {
  557. check([1, 'pop'], [0, 1], [0, 1], [{
  558. input: [0.5],
  559. output: [0.5]
  560. }]);
  561. check([1, 3, -1, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1], [{
  562. input: [0.25, 0.5],
  563. output: [0.5, 1, 0.25]
  564. }]);
  565. check([1, 3, 1, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1], [{
  566. input: [0.25, 0.5],
  567. output: [1, 0.25, 0.5]
  568. }]);
  569. check([1, 3, 1.5, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1], null);
  570. check([1, 1, 'index'], [0, 1], [0, 1, 0, 1, 0, 1], [{
  571. input: [0.5],
  572. output: [0.5, 1, 0.5]
  573. }]);
  574. check([1, 3, 'index', 'pop'], [0, 1], [0, 1], null);
  575. check([1, 0.5, 'index', 'pop'], [0, 1], [0, 1], null);
  576. });
  577. it('check input boundaries', function () {
  578. check([], [0, 0.5], [0, 1], [{
  579. input: [1],
  580. output: [0.5]
  581. }]);
  582. check([], [0.5, 1], [0, 1], [{
  583. input: [0],
  584. output: [0.5]
  585. }]);
  586. check(['dup'], [0.5, 0.75], [0, 1, 0, 1], [{
  587. input: [0],
  588. output: [0.5, 0.5]
  589. }]);
  590. check([], [100, 1001], [0, 10000], [{
  591. input: [1000],
  592. output: [1000]
  593. }]);
  594. });
  595. it('check output boundaries', function () {
  596. check([], [0, 1], [0, 0.5], [{
  597. input: [1],
  598. output: [0.5]
  599. }]);
  600. check([], [0, 1], [0.5, 1], [{
  601. input: [0],
  602. output: [0.5]
  603. }]);
  604. check(['dup'], [0, 1], [0.5, 1, 0.75, 1], [{
  605. input: [0],
  606. output: [0.5, 0.75]
  607. }]);
  608. check([], [0, 10000], [100, 1001], [{
  609. input: [1000],
  610. output: [1000]
  611. }]);
  612. });
  613. it('compile optimized', function () {
  614. var compiler = new _function.PostScriptCompiler();
  615. var code = [0, 'add', 1, 1, 3, -1, 'roll', 'sub', 'sub', 1, 'mul'];
  616. var compiledCode = compiler.compile(code, [0, 1], [0, 1]);
  617. expect(compiledCode).toEqual('dest[destOffset + 0] = Math.max(0, Math.min(1, src[srcOffset + 0]));');
  618. });
  619. });
  620. });