pdf.js/test/unit/function_spec.js
2012-04-18 09:48:28 -07:00

232 lines
7.1 KiB
JavaScript

/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict';
describe('function', function() {
beforeEach(function() {
this.addMatchers({
toMatchArray: function(expected) {
var actual = this.actual;
if (actual.length != expected.length)
return false;
for (var i = 0; i < expected.length; i++) {
var a = actual[i], b = expected[i];
if (isArray(b)) {
if (a.length != b.length)
return false;
for (var j = 0; j < a.length; j++) {
var suba = a[j], subb = b[j];
if (suba !== subb)
return false;
}
} else {
if (a !== b)
return false;
}
}
return true;
}
});
});
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 ands', function() {
var stack = evaluate('{ true false and }');
var expectedStack = [false];
expect(stack).toMatchArray(expectedStack);
});
it('bitwise ands', function() {
var stack = evaluate('{ 254 1 and }');
var expectedStack = [254 & 1];
expect(stack).toMatchArray(expectedStack);
});
// TODO atan
// TODO bitshift
// TODO ceiling
// TODO copy
// TODO cos
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);
});
// TODO cvr
// TODO div
it('duplicates', function() {
var stack = evaluate('{ 99 dup }');
var expectedStack = [99, 99];
expect(stack).toMatchArray(expectedStack);
});
// TODO eq
it('exchanges', function() {
var stack = evaluate('{ 44 99 exch }');
var expectedStack = [99, 44];
expect(stack).toMatchArray(expectedStack);
});
// TODO exp
// TODO false
// TODO floor
// TODO ge
// TODO gt
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);
});
// TODO le
// TODO ln
// TODO log
// TODO lt
// TODO mod
// TODO mul
// TODO ne
// TODO neg
// TODO not
// TODO or
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);
});
// TODO round
// TODO sin
// TODO sqrt
// TODO sub
// TODO true
// TODO truncate
// TODO xor
});
});