2015-04-22 05:45:33 -04:00
|
|
|
import {ddescribe, describe, it, expect} from 'angular2/test_lib';
|
2014-12-29 12:51:52 -05:00
|
|
|
|
2015-02-05 16:08:05 -05:00
|
|
|
import {Lexer, Token} from 'angular2/src/change_detection/parser/lexer';
|
2014-12-29 12:51:52 -05:00
|
|
|
|
2015-02-05 16:08:05 -05:00
|
|
|
import {List, ListWrapper} from "angular2/src/facade/collection";
|
2015-05-26 20:12:38 -04:00
|
|
|
import {StringWrapper} from "angular2/src/facade/lang";
|
2014-10-06 15:44:38 -04:00
|
|
|
|
2015-05-26 20:12:38 -04:00
|
|
|
function lex(text: string): List<any> {
|
2014-10-28 12:22:38 -04:00
|
|
|
return new Lexer().tokenize(text);
|
2014-10-06 15:44:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function expectToken(token, index) {
|
|
|
|
expect(token instanceof Token).toBe(true);
|
|
|
|
expect(token.index).toEqual(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectCharacterToken(token, index, character) {
|
|
|
|
expect(character.length).toBe(1);
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isCharacter(StringWrapper.charCodeAt(character, 0))).toBe(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectOperatorToken(token, index, operator) {
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isOperator(operator)).toBe(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectNumberToken(token, index, n) {
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isNumber()).toBe(true);
|
|
|
|
expect(token.toNumber()).toEqual(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectStringToken(token, index, str) {
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isString()).toBe(true);
|
|
|
|
expect(token.toString()).toEqual(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectIdentifierToken(token, index, identifier) {
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isIdentifier()).toBe(true);
|
|
|
|
expect(token.toString()).toEqual(identifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
function expectKeywordToken(token, index, keyword) {
|
|
|
|
expectToken(token, index);
|
|
|
|
expect(token.isKeyword()).toBe(true);
|
|
|
|
expect(token.toString()).toEqual(keyword);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function main() {
|
2014-10-28 12:22:38 -04:00
|
|
|
describe('lexer', function() {
|
2014-10-06 15:44:38 -04:00
|
|
|
describe('token', function() {
|
|
|
|
it('should tokenize a simple identifier', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<int> = lex("j");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(1);
|
|
|
|
expectIdentifierToken(tokens[0], 0, 'j');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize a dotted identifier', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<int> = lex("j.k");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(3);
|
|
|
|
expectIdentifierToken(tokens[0], 0, 'j');
|
2015-05-26 20:12:38 -04:00
|
|
|
expectCharacterToken(tokens[1], 1, '.');
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[2], 2, 'k');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize an operator', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<int> = lex("j-k");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(3);
|
|
|
|
expectOperatorToken(tokens[1], 1, '-');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize an indexed operator', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<int> = lex("j[k]");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(4);
|
|
|
|
expectCharacterToken(tokens[1], 1, "[");
|
|
|
|
expectCharacterToken(tokens[3], 3, "]");
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize numbers', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<int> = lex("88");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(1);
|
|
|
|
expectNumberToken(tokens[0], 0, 88);
|
|
|
|
});
|
|
|
|
|
2015-05-26 20:12:38 -04:00
|
|
|
it('should tokenize numbers within index ops',
|
|
|
|
function() { expectNumberToken(lex("a[22]")[2], 2, 22); });
|
2014-10-06 15:44:38 -04:00
|
|
|
|
2015-05-26 20:12:38 -04:00
|
|
|
it('should tokenize simple quoted strings',
|
|
|
|
function() { expectStringToken(lex('"a"')[0], 0, "a"); });
|
2014-10-06 15:44:38 -04:00
|
|
|
|
2015-05-26 20:12:38 -04:00
|
|
|
it('should tokenize quoted strings with escaped quotes',
|
|
|
|
function() { expectStringToken(lex('"a\\""')[0], 0, 'a"'); });
|
2014-10-06 15:44:38 -04:00
|
|
|
|
|
|
|
it('should tokenize a string', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("j-a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[0], 0, 'j');
|
|
|
|
expectOperatorToken(tokens[1], 1, '-');
|
|
|
|
expectIdentifierToken(tokens[2], 2, 'a');
|
|
|
|
expectCharacterToken(tokens[3], 3, '.');
|
|
|
|
expectIdentifierToken(tokens[4], 4, 'bc');
|
|
|
|
expectCharacterToken(tokens[5], 6, '[');
|
|
|
|
expectNumberToken(tokens[6], 7, 22);
|
|
|
|
expectCharacterToken(tokens[7], 9, ']');
|
|
|
|
expectOperatorToken(tokens[8], 10, '+');
|
|
|
|
expectNumberToken(tokens[9], 11, 1.3);
|
|
|
|
expectOperatorToken(tokens[10], 14, '|');
|
|
|
|
expectIdentifierToken(tokens[11], 15, 'f');
|
|
|
|
expectCharacterToken(tokens[12], 16, ':');
|
|
|
|
expectStringToken(tokens[13], 17, "a'c");
|
|
|
|
expectCharacterToken(tokens[14], 23, ':');
|
|
|
|
expectStringToken(tokens[15], 24, 'd"e');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize undefined', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("undefined");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectKeywordToken(tokens[0], 0, "undefined");
|
|
|
|
expect(tokens[0].isKeywordUndefined()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should ignore whitespace', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("a \t \n \r b");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[0], 0, 'a');
|
|
|
|
expectIdentifierToken(tokens[1], 8, 'b');
|
|
|
|
});
|
|
|
|
|
2015-05-26 04:19:47 -04:00
|
|
|
it('should tokenize quoted string', () => {
|
2014-10-06 15:44:38 -04:00
|
|
|
var str = "['\\'', \"\\\"\"]";
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex(str);
|
2014-10-06 15:44:38 -04:00
|
|
|
expectStringToken(tokens[1], 1, "'");
|
|
|
|
expectStringToken(tokens[3], 7, '"');
|
|
|
|
});
|
|
|
|
|
2015-05-26 04:19:47 -04:00
|
|
|
it('should tokenize escaped quoted string', () => {
|
2014-10-06 15:44:38 -04:00
|
|
|
var str = '"\\"\\n\\f\\r\\t\\v\\u00A0"';
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex(str);
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(1);
|
|
|
|
expect(tokens[0].toString()).toEqual('"\n\f\r\t\v\u00A0');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize unicode', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex('"\\u00A0"');
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(1);
|
|
|
|
expect(tokens[0].toString()).toEqual('\u00a0');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize relation', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("! == != < > <= >= === !==");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectOperatorToken(tokens[0], 0, '!');
|
|
|
|
expectOperatorToken(tokens[1], 2, '==');
|
|
|
|
expectOperatorToken(tokens[2], 5, '!=');
|
|
|
|
expectOperatorToken(tokens[3], 8, '<');
|
|
|
|
expectOperatorToken(tokens[4], 10, '>');
|
|
|
|
expectOperatorToken(tokens[5], 12, '<=');
|
|
|
|
expectOperatorToken(tokens[6], 15, '>=');
|
2015-04-22 05:45:33 -04:00
|
|
|
expectOperatorToken(tokens[7], 18, '===');
|
|
|
|
expectOperatorToken(tokens[8], 22, '!==');
|
2014-10-06 15:44:38 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize statements', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("a;b;");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[0], 0, 'a');
|
|
|
|
expectCharacterToken(tokens[1], 1, ';');
|
|
|
|
expectIdentifierToken(tokens[2], 2, 'b');
|
|
|
|
expectCharacterToken(tokens[3], 3, ';');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize function invocation', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("a()");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[0], 0, 'a');
|
|
|
|
expectCharacterToken(tokens[1], 1, '(');
|
|
|
|
expectCharacterToken(tokens[2], 2, ')');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize simple method invocations', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("a.method()");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[2], 2, 'method');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize method invocation', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("a.b.c (d) - e.f()");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectIdentifierToken(tokens[0], 0, 'a');
|
|
|
|
expectCharacterToken(tokens[1], 1, '.');
|
|
|
|
expectIdentifierToken(tokens[2], 2, 'b');
|
|
|
|
expectCharacterToken(tokens[3], 3, '.');
|
|
|
|
expectIdentifierToken(tokens[4], 4, 'c');
|
|
|
|
expectCharacterToken(tokens[5], 6, '(');
|
|
|
|
expectIdentifierToken(tokens[6], 7, 'd');
|
|
|
|
expectCharacterToken(tokens[7], 8, ')');
|
|
|
|
expectOperatorToken(tokens[8], 10, '-');
|
|
|
|
expectIdentifierToken(tokens[9], 12, 'e');
|
|
|
|
expectCharacterToken(tokens[10], 13, '.');
|
|
|
|
expectIdentifierToken(tokens[11], 14, 'f');
|
|
|
|
expectCharacterToken(tokens[12], 15, '(');
|
|
|
|
expectCharacterToken(tokens[13], 16, ')');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize number', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("0.5");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectNumberToken(tokens[0], 0, 0.5);
|
|
|
|
});
|
|
|
|
|
|
|
|
// NOTE(deboer): NOT A LEXER TEST
|
2015-05-26 04:19:47 -04:00
|
|
|
// it('should tokenize negative number', () => {
|
2014-10-06 15:44:38 -04:00
|
|
|
// var tokens:List<Token> = lex("-0.5");
|
|
|
|
// expectNumberToken(tokens[0], 0, -0.5);
|
|
|
|
// });
|
|
|
|
|
|
|
|
it('should tokenize number with exponent', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("0.5E-10");
|
2014-10-06 15:44:38 -04:00
|
|
|
expect(tokens.length).toEqual(1);
|
|
|
|
expectNumberToken(tokens[0], 0, 0.5E-10);
|
|
|
|
tokens = lex("0.5E+10");
|
|
|
|
expectNumberToken(tokens[0], 0, 0.5E+10);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should throws exception for invalid exponent', function() {
|
2015-07-23 11:43:45 -04:00
|
|
|
expect(() => { lex("0.5E-"); })
|
2015-05-26 20:12:38 -04:00
|
|
|
.toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-]');
|
2014-10-06 15:44:38 -04:00
|
|
|
|
2015-07-23 11:43:45 -04:00
|
|
|
expect(() => { lex("0.5E-A"); })
|
2015-05-26 20:12:38 -04:00
|
|
|
.toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-A]');
|
2014-10-06 15:44:38 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should tokenize number starting with a dot', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex(".5");
|
2014-10-06 15:44:38 -04:00
|
|
|
expectNumberToken(tokens[0], 0, 0.5);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should throw error on invalid unicode', function() {
|
2015-07-23 11:43:45 -04:00
|
|
|
expect(() => { lex("'\\u1''bla'"); })
|
2015-05-26 20:12:38 -04:00
|
|
|
.toThrowError(
|
|
|
|
"Lexer Error: Invalid unicode escape [\\u1''b] at column 2 in expression ['\\u1''bla']");
|
2014-10-06 15:44:38 -04:00
|
|
|
});
|
|
|
|
|
2014-11-18 19:38:36 -05:00
|
|
|
it('should tokenize hash as operator', function() {
|
2015-05-26 20:12:38 -04:00
|
|
|
var tokens: List<Token> = lex("#");
|
2014-11-18 19:38:36 -05:00
|
|
|
expectOperatorToken(tokens[0], 0, '#');
|
|
|
|
});
|
|
|
|
|
2015-05-26 04:19:47 -04:00
|
|
|
it('should tokenize ?. as operator', () => {
|
|
|
|
var tokens: List<Token> = lex('?.');
|
|
|
|
expectOperatorToken(tokens[0], 0, '?.');
|
|
|
|
});
|
|
|
|
|
2014-10-06 15:44:38 -04:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|