de36b2aaba
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes). Prettier is being used for a couple of reasons: - To be consistent with `mozilla-central`, where Prettier is already in use across the tree. - To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters. Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some). Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long. *Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit. (On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
632 lines
21 KiB
JavaScript
632 lines
21 KiB
JavaScript
/* Copyright 2017 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import {
|
|
PostScriptCompiler,
|
|
PostScriptEvaluator,
|
|
} from "../../src/core/function";
|
|
import { PostScriptLexer, PostScriptParser } from "../../src/core/ps_parser";
|
|
import { StringStream } from "../../src/core/stream";
|
|
|
|
describe("function", function() {
|
|
beforeEach(function() {
|
|
jasmine.addMatchers({
|
|
toMatchArray(util, customEqualityTesters) {
|
|
return {
|
|
compare(actual, expected) {
|
|
var result = {};
|
|
if (actual.length !== expected.length) {
|
|
result.pass = false;
|
|
result.message =
|
|
"Array length: " +
|
|
actual.length +
|
|
", expected: " +
|
|
expected.length;
|
|
return result;
|
|
}
|
|
result.pass = true;
|
|
for (var i = 0; i < expected.length; i++) {
|
|
var a = actual[i],
|
|
b = expected[i];
|
|
if (Array.isArray(b)) {
|
|
if (a.length !== b.length) {
|
|
result.pass = false;
|
|
break;
|
|
}
|
|
for (var j = 0; j < a.length; j++) {
|
|
var suba = a[j],
|
|
subb = b[j];
|
|
if (suba !== subb) {
|
|
result.pass = false;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if (a !== b) {
|
|
result.pass = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
};
|
|
},
|
|
});
|
|
});
|
|
|
|
describe("PostScriptParser", function() {
|
|
function parse(program) {
|
|
var stream = new StringStream(program);
|
|
var parser = new PostScriptParser(new PostScriptLexer(stream));
|
|
return parser.parse();
|
|
}
|
|
it("parses empty programs", function() {
|
|
var output = parse("{}");
|
|
expect(output.length).toEqual(0);
|
|
});
|
|
it("parses positive numbers", function() {
|
|
var number = 999;
|
|
var program = parse("{ " + number + " }");
|
|
var expectedProgram = [number];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("parses negative numbers", function() {
|
|
var number = -999;
|
|
var program = parse("{ " + number + " }");
|
|
var expectedProgram = [number];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("parses negative floats", function() {
|
|
var number = 3.3;
|
|
var program = parse("{ " + number + " }");
|
|
var expectedProgram = [number];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("parses operators", function() {
|
|
var program = parse("{ sub }");
|
|
var expectedProgram = ["sub"];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("parses if statements", function() {
|
|
var program = parse("{ { 99 } if }");
|
|
var expectedProgram = [3, "jz", 99];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("parses ifelse statements", function() {
|
|
var program = parse("{ { 99 } { 44 } ifelse }");
|
|
var expectedProgram = [5, "jz", 99, 6, "j", 44];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
it("handles missing brackets", function() {
|
|
expect(function() {
|
|
parse("{");
|
|
}).toThrow(new Error("Unexpected symbol: found undefined expected 1."));
|
|
});
|
|
it("handles junk after the end", function() {
|
|
var number = 3.3;
|
|
var program = parse("{ " + number + " }#");
|
|
var expectedProgram = [number];
|
|
expect(program).toMatchArray(expectedProgram);
|
|
});
|
|
});
|
|
|
|
describe("PostScriptEvaluator", function() {
|
|
function evaluate(program) {
|
|
var stream = new StringStream(program);
|
|
var parser = new PostScriptParser(new PostScriptLexer(stream));
|
|
var code = parser.parse();
|
|
var evaluator = new PostScriptEvaluator(code);
|
|
var output = evaluator.execute();
|
|
return output;
|
|
}
|
|
|
|
it("pushes stack", function() {
|
|
var stack = evaluate("{ 99 }");
|
|
var expectedStack = [99];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles if with true", function() {
|
|
var stack = evaluate("{ 1 {99} if }");
|
|
var expectedStack = [99];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles if with false", function() {
|
|
var stack = evaluate("{ 0 {99} if }");
|
|
var expectedStack = [];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles ifelse with true", function() {
|
|
var stack = evaluate("{ 1 {99} {77} ifelse }");
|
|
var expectedStack = [99];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles ifelse with false", function() {
|
|
var stack = evaluate("{ 0 {99} {77} ifelse }");
|
|
var expectedStack = [77];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles nested if", function() {
|
|
var stack = evaluate("{ 1 {1 {77} if} if }");
|
|
var expectedStack = [77];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
|
|
it("abs", function() {
|
|
var stack = evaluate("{ -2 abs }");
|
|
var expectedStack = [2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("adds", function() {
|
|
var stack = evaluate("{ 1 2 add }");
|
|
var expectedStack = [3];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("boolean and", function() {
|
|
var stack = evaluate("{ true false and }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("bitwise and", function() {
|
|
var stack = evaluate("{ 254 1 and }");
|
|
var expectedStack = [254 & 1];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the inverse tangent of a number", function() {
|
|
var stack = evaluate("{ 90 atan }");
|
|
var expectedStack = [Math.atan(90)];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles bitshifting ", function() {
|
|
var stack = evaluate("{ 50 2 bitshift }");
|
|
var expectedStack = [200];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the ceiling value", function() {
|
|
var stack = evaluate("{ 9.9 ceiling }");
|
|
var expectedStack = [10];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("copies", function() {
|
|
var stack = evaluate("{ 99 98 2 copy }");
|
|
var expectedStack = [99, 98, 99, 98];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the cosine of a number", function() {
|
|
var stack = evaluate("{ 90 cos }");
|
|
var expectedStack = [Math.cos(90)];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("converts to int", function() {
|
|
var stack = evaluate("{ 9.9 cvi }");
|
|
var expectedStack = [9];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("converts negatives to int", function() {
|
|
var stack = evaluate("{ -9.9 cvi }");
|
|
var expectedStack = [-9];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("converts to real", function() {
|
|
var stack = evaluate("{ 55.34 cvr }");
|
|
var expectedStack = [55.34];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("divides", function() {
|
|
var stack = evaluate("{ 6 5 div }");
|
|
var expectedStack = [1.2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("maps division by zero to infinity", function() {
|
|
var stack = evaluate("{ 6 0 div }");
|
|
var expectedStack = [Infinity];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("duplicates", function() {
|
|
var stack = evaluate("{ 99 dup }");
|
|
var expectedStack = [99, 99];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("accepts an equality", function() {
|
|
var stack = evaluate("{ 9 9 eq }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects an inequality", function() {
|
|
var stack = evaluate("{ 9 8 eq }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("exchanges", function() {
|
|
var stack = evaluate("{ 44 99 exch }");
|
|
var expectedStack = [99, 44];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles exponentiation", function() {
|
|
var stack = evaluate("{ 10 2 exp }");
|
|
var expectedStack = [100];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("pushes false onto the stack", function() {
|
|
var stack = evaluate("{ false }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the floor value", function() {
|
|
var stack = evaluate("{ 9.9 floor }");
|
|
var expectedStack = [9];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles greater than or equal to", function() {
|
|
var stack = evaluate("{ 10 9 ge }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects less than for greater than or equal to", function() {
|
|
var stack = evaluate("{ 8 9 ge }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles greater than", function() {
|
|
var stack = evaluate("{ 10 9 gt }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects less than or equal for greater than", function() {
|
|
var stack = evaluate("{ 9 9 gt }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("divides to integer", function() {
|
|
var stack = evaluate("{ 2 3 idiv }");
|
|
var expectedStack = [0];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("divides to negative integer", function() {
|
|
var stack = evaluate("{ -2 3 idiv }");
|
|
var expectedStack = [0];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("duplicates index", function() {
|
|
var stack = evaluate("{ 4 3 2 1 2 index }");
|
|
var expectedStack = [4, 3, 2, 1, 3];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles less than or equal to", function() {
|
|
var stack = evaluate("{ 9 10 le }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects greater than for less than or equal to", function() {
|
|
var stack = evaluate("{ 10 9 le }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the natural logarithm", function() {
|
|
var stack = evaluate("{ 10 ln }");
|
|
var expectedStack = [Math.log(10)];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the base 10 logarithm", function() {
|
|
var stack = evaluate("{ 100 log }");
|
|
var expectedStack = [2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("handles less than", function() {
|
|
var stack = evaluate("{ 9 10 lt }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects greater than or equal to for less than", function() {
|
|
var stack = evaluate("{ 10 9 lt }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("performs the modulo operation", function() {
|
|
var stack = evaluate("{ 4 3 mod }");
|
|
var expectedStack = [1];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("multiplies two numbers (positive result)", function() {
|
|
var stack = evaluate("{ 9 8 mul }");
|
|
var expectedStack = [72];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("multiplies two numbers (negative result)", function() {
|
|
var stack = evaluate("{ 9 -8 mul }");
|
|
var expectedStack = [-72];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("accepts an inequality", function() {
|
|
var stack = evaluate("{ 9 8 ne }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rejects an equality", function() {
|
|
var stack = evaluate("{ 9 9 ne }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("negates", function() {
|
|
var stack = evaluate("{ 4.5 neg }");
|
|
var expectedStack = [-4.5];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("boolean not", function() {
|
|
var stack = evaluate("{ true not }");
|
|
var expectedStack = [false];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("bitwise not", function() {
|
|
var stack = evaluate("{ 12 not }");
|
|
var expectedStack = [-13];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("boolean or", function() {
|
|
var stack = evaluate("{ true false or }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("bitwise or", function() {
|
|
var stack = evaluate("{ 254 1 or }");
|
|
var expectedStack = [254 | 1];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("pops stack", function() {
|
|
var stack = evaluate("{ 1 2 pop }");
|
|
var expectedStack = [1];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rolls stack right", function() {
|
|
var stack = evaluate("{ 1 3 2 2 4 1 roll }");
|
|
var expectedStack = [2, 1, 3, 2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rolls stack left", function() {
|
|
var stack = evaluate("{ 1 3 2 2 4 -1 roll }");
|
|
var expectedStack = [3, 2, 2, 1];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("rounds a number", function() {
|
|
var stack = evaluate("{ 9.52 round }");
|
|
var expectedStack = [10];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates the sine of a number", function() {
|
|
var stack = evaluate("{ 90 sin }");
|
|
var expectedStack = [Math.sin(90)];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates a square root (integer)", function() {
|
|
var stack = evaluate("{ 100 sqrt }");
|
|
var expectedStack = [10];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates a square root (float)", function() {
|
|
var stack = evaluate("{ 99 sqrt }");
|
|
var expectedStack = [Math.sqrt(99)];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("subtracts (positive result)", function() {
|
|
var stack = evaluate("{ 6 4 sub }");
|
|
var expectedStack = [2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("subtracts (negative result)", function() {
|
|
var stack = evaluate("{ 4 6 sub }");
|
|
var expectedStack = [-2];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("pushes true onto the stack", function() {
|
|
var stack = evaluate("{ true }");
|
|
var expectedStack = [true];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("truncates a number", function() {
|
|
var stack = evaluate("{ 35.004 truncate }");
|
|
var expectedStack = [35];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
it("calculates an exclusive or value", function() {
|
|
var stack = evaluate("{ 3 9 xor }");
|
|
var expectedStack = [10];
|
|
expect(stack).toMatchArray(expectedStack);
|
|
});
|
|
});
|
|
|
|
describe("PostScriptCompiler", function() {
|
|
function check(code, domain, range, samples) {
|
|
var compiler = new PostScriptCompiler();
|
|
var compiledCode = compiler.compile(code, domain, range);
|
|
if (samples === null) {
|
|
expect(compiledCode).toBeNull();
|
|
} else {
|
|
expect(compiledCode).not.toBeNull();
|
|
// eslint-disable-next-line no-new-func
|
|
var fn = new Function(
|
|
"src",
|
|
"srcOffset",
|
|
"dest",
|
|
"destOffset",
|
|
compiledCode
|
|
);
|
|
for (var i = 0; i < samples.length; i++) {
|
|
var out = new Float32Array(samples[i].output.length);
|
|
fn(samples[i].input, 0, out, 0);
|
|
expect(Array.prototype.slice.call(out, 0)).toMatchArray(
|
|
samples[i].output
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
it("check compiled add", function() {
|
|
check([0.25, 0.5, "add"], [], [0, 1], [{ input: [], output: [0.75] }]);
|
|
check([0, "add"], [0, 1], [0, 1], [{ input: [0.25], output: [0.25] }]);
|
|
check([0.5, "add"], [0, 1], [0, 1], [{ input: [0.25], output: [0.75] }]);
|
|
check(
|
|
[0, "exch", "add"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25], output: [0.25] }]
|
|
);
|
|
check(
|
|
[0.5, "exch", "add"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25], output: [0.75] }]
|
|
);
|
|
check(
|
|
["add"],
|
|
[0, 1, 0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25, 0.5], output: [0.75] }]
|
|
);
|
|
check(["add"], [0, 1], [0, 1], null);
|
|
});
|
|
it("check compiled sub", function() {
|
|
check([0.5, 0.25, "sub"], [], [0, 1], [{ input: [], output: [0.25] }]);
|
|
check([0, "sub"], [0, 1], [0, 1], [{ input: [0.25], output: [0.25] }]);
|
|
check([0.5, "sub"], [0, 1], [0, 1], [{ input: [0.75], output: [0.25] }]);
|
|
check(
|
|
[0, "exch", "sub"],
|
|
[0, 1],
|
|
[-1, 1],
|
|
[{ input: [0.25], output: [-0.25] }]
|
|
);
|
|
check(
|
|
[0.75, "exch", "sub"],
|
|
[0, 1],
|
|
[-1, 1],
|
|
[{ input: [0.25], output: [0.5] }]
|
|
);
|
|
check(
|
|
["sub"],
|
|
[0, 1, 0, 1],
|
|
[-1, 1],
|
|
[{ input: [0.25, 0.5], output: [-0.25] }]
|
|
);
|
|
check(["sub"], [0, 1], [0, 1], null);
|
|
|
|
check(
|
|
[1, "dup", 3, 2, "roll", "sub", "sub"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.75], output: [0.75] }]
|
|
);
|
|
});
|
|
it("check compiled mul", function() {
|
|
check([0.25, 0.5, "mul"], [], [0, 1], [{ input: [], output: [0.125] }]);
|
|
check([0, "mul"], [0, 1], [0, 1], [{ input: [0.25], output: [0] }]);
|
|
check([0.5, "mul"], [0, 1], [0, 1], [{ input: [0.25], output: [0.125] }]);
|
|
check([1, "mul"], [0, 1], [0, 1], [{ input: [0.25], output: [0.25] }]);
|
|
check(
|
|
[0, "exch", "mul"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25], output: [0] }]
|
|
);
|
|
check(
|
|
[0.5, "exch", "mul"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25], output: [0.125] }]
|
|
);
|
|
check(
|
|
[1, "exch", "mul"],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25], output: [0.25] }]
|
|
);
|
|
check(
|
|
["mul"],
|
|
[0, 1, 0, 1],
|
|
[0, 1],
|
|
[{ input: [0.25, 0.5], output: [0.125] }]
|
|
);
|
|
check(["mul"], [0, 1], [0, 1], null);
|
|
});
|
|
it("check compiled max", function() {
|
|
check(
|
|
["dup", 0.75, "gt", 7, "jz", "pop", 0.75],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [0.5], output: [0.5] }]
|
|
);
|
|
check(
|
|
["dup", 0.75, "gt", 7, "jz", "pop", 0.75],
|
|
[0, 1],
|
|
[0, 1],
|
|
[{ input: [1], output: [0.75] }]
|
|
);
|
|
check(["dup", 0.75, "gt", 5, "jz", "pop", 0.75], [0, 1], [0, 1], null);
|
|
});
|
|
it("check pop/roll/index", function() {
|
|
check([1, "pop"], [0, 1], [0, 1], [{ input: [0.5], output: [0.5] }]);
|
|
check(
|
|
[1, 3, -1, "roll"],
|
|
[0, 1, 0, 1],
|
|
[0, 1, 0, 1, 0, 1],
|
|
[{ input: [0.25, 0.5], output: [0.5, 1, 0.25] }]
|
|
);
|
|
check(
|
|
[1, 3, 1, "roll"],
|
|
[0, 1, 0, 1],
|
|
[0, 1, 0, 1, 0, 1],
|
|
[{ input: [0.25, 0.5], output: [1, 0.25, 0.5] }]
|
|
);
|
|
check([1, 3, 1.5, "roll"], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1], null);
|
|
check(
|
|
[1, 1, "index"],
|
|
[0, 1],
|
|
[0, 1, 0, 1, 0, 1],
|
|
[{ input: [0.5], output: [0.5, 1, 0.5] }]
|
|
);
|
|
check([1, 3, "index", "pop"], [0, 1], [0, 1], null);
|
|
check([1, 0.5, "index", "pop"], [0, 1], [0, 1], null);
|
|
});
|
|
it("check input boundaries", function() {
|
|
check([], [0, 0.5], [0, 1], [{ input: [1], output: [0.5] }]);
|
|
check([], [0.5, 1], [0, 1], [{ input: [0], output: [0.5] }]);
|
|
check(
|
|
["dup"],
|
|
[0.5, 0.75],
|
|
[0, 1, 0, 1],
|
|
[{ input: [0], output: [0.5, 0.5] }]
|
|
);
|
|
check([], [100, 1001], [0, 10000], [{ input: [1000], output: [1000] }]);
|
|
});
|
|
it("check output boundaries", function() {
|
|
check([], [0, 1], [0, 0.5], [{ input: [1], output: [0.5] }]);
|
|
check([], [0, 1], [0.5, 1], [{ input: [0], output: [0.5] }]);
|
|
check(
|
|
["dup"],
|
|
[0, 1],
|
|
[0.5, 1, 0.75, 1],
|
|
[{ input: [0], output: [0.5, 0.75] }]
|
|
);
|
|
check([], [0, 10000], [100, 1001], [{ input: [1000], output: [1000] }]);
|
|
});
|
|
it("compile optimized", function() {
|
|
var compiler = new PostScriptCompiler();
|
|
var code = [0, "add", 1, 1, 3, -1, "roll", "sub", "sub", 1, "mul"];
|
|
var compiledCode = compiler.compile(code, [0, 1], [0, 1]);
|
|
expect(compiledCode).toEqual(
|
|
"dest[destOffset + 0] = Math.max(0, Math.min(1, src[srcOffset + 0]));"
|
|
);
|
|
});
|
|
});
|
|
});
|