Write more unit tests for the lexer and the parser
Moreover, group the lexer unit tests per method. This matches what we do for other classes and makes it more easily visible which methods we don't or insufficiently unit test. The parser itself is not unit tested yet, so this patch provides a start for doing so. The `inlineStreamSkipEI` method is used in other end marker detection methods, so it's important that its functionality is correct for proper parsing.
This commit is contained in:
parent
2ee299a62b
commit
4a4b197b9d
@ -14,13 +14,79 @@
|
|||||||
*/
|
*/
|
||||||
/* eslint no-var: error */
|
/* eslint no-var: error */
|
||||||
|
|
||||||
import { Lexer, Linearization } from '../../src/core/parser';
|
import { Lexer, Linearization, Parser } from '../../src/core/parser';
|
||||||
import { FormatError } from '../../src/shared/util';
|
import { FormatError } from '../../src/shared/util';
|
||||||
import { Name } from '../../src/core/primitives';
|
import { Name } from '../../src/core/primitives';
|
||||||
import { StringStream } from '../../src/core/stream';
|
import { StringStream } from '../../src/core/stream';
|
||||||
|
|
||||||
describe('parser', function() {
|
describe('parser', function() {
|
||||||
|
describe('Parser', function() {
|
||||||
|
describe('inlineStreamSkipEI', function() {
|
||||||
|
it('should skip over the EI marker if it is found', function() {
|
||||||
|
const string = 'q 1 0 0 1 0 0 cm BI /W 10 /H 10 /BPC 1 ' +
|
||||||
|
'/F /A85 ID abc123~> EI Q';
|
||||||
|
const input = new StringStream(string);
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
const parser = new Parser(lexer, /* allowStreams = */ true,
|
||||||
|
/* xref = */ null);
|
||||||
|
parser.inlineStreamSkipEI(input);
|
||||||
|
expect(input.pos).toEqual(string.indexOf('Q'));
|
||||||
|
expect(input.peekByte()).toEqual(0x51); // 'Q'
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip to the end of stream if the EI marker is not found',
|
||||||
|
function() {
|
||||||
|
const string = 'q 1 0 0 1 0 0 cm BI /W 10 /H 10 /BPC 1 ' +
|
||||||
|
'/F /A85 ID abc123~> Q';
|
||||||
|
const input = new StringStream(string);
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
const parser = new Parser(lexer, /* allowStreams = */ true,
|
||||||
|
/* xref = */ null);
|
||||||
|
parser.inlineStreamSkipEI(input);
|
||||||
|
expect(input.pos).toEqual(string.length);
|
||||||
|
expect(input.peekByte()).toEqual(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Lexer', function() {
|
describe('Lexer', function() {
|
||||||
|
describe('nextChar', function() {
|
||||||
|
it('should return and set -1 when the end of the stream is reached',
|
||||||
|
function() {
|
||||||
|
const input = new StringStream('');
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
expect(lexer.nextChar()).toEqual(-1);
|
||||||
|
expect(lexer.currentChar).toEqual(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return and set the character after the current position',
|
||||||
|
function() {
|
||||||
|
const input = new StringStream('123');
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
expect(lexer.nextChar()).toEqual(0x32); // '2'
|
||||||
|
expect(lexer.currentChar).toEqual(0x32); // '2'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('peekChar', function() {
|
||||||
|
it('should only return -1 when the end of the stream is reached',
|
||||||
|
function() {
|
||||||
|
const input = new StringStream('');
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
expect(lexer.peekChar()).toEqual(-1);
|
||||||
|
expect(lexer.currentChar).toEqual(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only return the character after the current position',
|
||||||
|
function() {
|
||||||
|
const input = new StringStream('123');
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
expect(lexer.peekChar()).toEqual(0x32); // '2'
|
||||||
|
expect(lexer.currentChar).toEqual(0x31); // '1'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getNumber', function() {
|
||||||
it('should stop parsing numbers at the end of stream', function() {
|
it('should stop parsing numbers at the end of stream', function() {
|
||||||
const input = new StringStream('11.234');
|
const input = new StringStream('11.234');
|
||||||
const lexer = new Lexer(input);
|
const lexer = new Lexer(input);
|
||||||
@ -83,7 +149,9 @@ describe('parser', function() {
|
|||||||
// The lexer must not have consumed the 'E'
|
// The lexer must not have consumed the 'E'
|
||||||
expect(lexer.currentChar).toEqual(0x45); // 'E'
|
expect(lexer.currentChar).toEqual(0x45); // 'E'
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getString', function() {
|
||||||
it('should stop parsing strings at the end of stream', function() {
|
it('should stop parsing strings at the end of stream', function() {
|
||||||
const input = new StringStream('(1$4)');
|
const input = new StringStream('(1$4)');
|
||||||
input.getByte = function(super_getByte) {
|
input.getByte = function(super_getByte) {
|
||||||
@ -95,21 +163,26 @@ describe('parser', function() {
|
|||||||
expect(lexer.getString()).toEqual('1');
|
expect(lexer.getString()).toEqual('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw exception on bad input', function() {
|
|
||||||
// '7 0 2 15 5 2 2 2 4 3 2 4' should be parsed as '70 21 55 22 24 32'.
|
|
||||||
const input = new StringStream('<7 0 2 15 5 2 2 2 4 3 2 4>');
|
|
||||||
const lexer = new Lexer(input);
|
|
||||||
expect(lexer.getHexString()).toEqual('p!U"$2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore escaped CR and LF', function() {
|
it('should ignore escaped CR and LF', function() {
|
||||||
// '(\101\<CR><LF>\102)' should be parsed as 'AB'.
|
// '(\101\<CR><LF>\102)' should be parsed as 'AB'.
|
||||||
const input = new StringStream('(\\101\\\r\n\\102\\\r\\103\\\n\\104)');
|
const input = new StringStream('(\\101\\\r\n\\102\\\r\\103\\\n\\104)');
|
||||||
const lexer = new Lexer(input);
|
const lexer = new Lexer(input);
|
||||||
expect(lexer.getString()).toEqual('ABCD');
|
expect(lexer.getString()).toEqual('ABCD');
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle Names with invalid usage of NUMBER SIGN (#)', function() {
|
describe('getHexString', function() {
|
||||||
|
it('should not throw exception on bad input', function() {
|
||||||
|
// '7 0 2 15 5 2 2 2 4 3 2 4' should be parsed as '70 21 55 22 24 32'.
|
||||||
|
const input = new StringStream('<7 0 2 15 5 2 2 2 4 3 2 4>');
|
||||||
|
const lexer = new Lexer(input);
|
||||||
|
expect(lexer.getHexString()).toEqual('p!U"$2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getName', function() {
|
||||||
|
it('should handle Names with invalid usage of NUMBER SIGN (#)',
|
||||||
|
function() {
|
||||||
const inputNames = ['/# 680 0 R', '/#AQwerty', '/#A<</B'];
|
const inputNames = ['/# 680 0 R', '/#AQwerty', '/#A<</B'];
|
||||||
const expectedNames = ['#', '#AQwerty', '#A'];
|
const expectedNames = ['#', '#AQwerty', '#A'];
|
||||||
|
|
||||||
@ -120,6 +193,7 @@ describe('parser', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Linearization', function() {
|
describe('Linearization', function() {
|
||||||
it('should not find a linearization dictionary', function() {
|
it('should not find a linearization dictionary', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user