feat(Compiler): case sensitive html parser

close #4417
Closes #5264
This commit is contained in:
Victor Berchet
2015-11-10 15:56:25 -08:00
parent adb87562bb
commit 36a423fac8
13 changed files with 834 additions and 381 deletions

View File

@ -1,8 +1,22 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from '../../test_lib';
import {BaseException} from '../../src/facade/exceptions';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {BaseException} from 'angular2/src/facade/exceptions';
import {tokenizeHtml, HtmlToken, HtmlTokenType} from '../../src/compiler/html_lexer';
import {ParseSourceSpan, ParseLocation} from '../../src/compiler/parse_util';
import {
tokenizeHtml,
HtmlToken,
HtmlTokenType,
HtmlTokenError
} from 'angular2/src/compiler/html_lexer';
import {ParseSourceSpan, ParseLocation, ParseSourceFile} from 'angular2/src/compiler/parse_util';
export function main() {
describe('HtmlLexer', () => {
@ -253,11 +267,35 @@ export function main() {
});
it('should parse attributes with entities in values', () => {
expect(tokenizeAndHumanizeParts('<t a="&#65;">'))
expect(tokenizeAndHumanizeParts('<t a="&#65;&#x41;">'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'A'],
[HtmlTokenType.ATTR_VALUE, 'AA'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should not decode entities without trailing ";"', () => {
expect(tokenizeAndHumanizeParts('<t a="&amp" b="c&&d">'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, '&amp'],
[HtmlTokenType.ATTR_NAME, null, 'b'],
[HtmlTokenType.ATTR_VALUE, 'c&&d'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with "&" in values', () => {
expect(tokenizeAndHumanizeParts('<t a="b && c &">'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b && c &'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
@ -343,13 +381,22 @@ export function main() {
.toEqual([[HtmlTokenType.TEXT, 'a&amp;b'], [HtmlTokenType.EOF, '']]);
});
it('should report unknown named entities >', () => {
it('should report malformed/unknown entities', () => {
expect(tokenizeAndHumanizeErrors('&tbo;'))
.toEqual([[HtmlTokenType.TEXT, 'Unknown entity "tbo"', '0:0']]);
.toEqual([
[
HtmlTokenType.TEXT,
'Unknown entity "tbo" - use the "&#<decimal>;" or "&#x<hex>;" syntax',
'0:0'
]
]);
expect(tokenizeAndHumanizeErrors('&#asdf;'))
.toEqual([[HtmlTokenType.TEXT, 'Unknown entity "#asdf"', '0:0']]);
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:3']]);
expect(tokenizeAndHumanizeErrors('&#xasdf;'))
.toEqual([[HtmlTokenType.TEXT, 'Unknown entity "#xasdf"', '0:0']]);
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:4']]);
expect(tokenizeAndHumanizeErrors('&#xABC'))
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "EOF"', '0:6']]);
});
});
@ -364,6 +411,11 @@ export function main() {
.toEqual([[HtmlTokenType.TEXT, 'a&b'], [HtmlTokenType.EOF]]);
});
it('should parse text starting with "&"', () => {
expect(tokenizeAndHumanizeParts('a && b &'))
.toEqual([[HtmlTokenType.TEXT, 'a && b &'], [HtmlTokenType.EOF]]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('a'))
.toEqual([[HtmlTokenType.TEXT, 'a'], [HtmlTokenType.EOF, '']]);
@ -486,6 +538,17 @@ export function main() {
});
describe('errors', () => {
it('should include 2 lines of context in message', () => {
let src = "111\n222\n333\nE\n444\n555\n666\n";
let file = new ParseSourceFile(src, 'file://');
let location = new ParseLocation(file, 12, 123, 456);
let error = new HtmlTokenError('**ERROR**', null, location);
expect(error.toString())
.toEqual(`**ERROR** ("\n222\n333\n[ERROR ->]E\n444\n555\n"): file://@123:456`);
});
});
});
}