function_spec.js 21 KB

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