revert(format): Revert "chore(format): update to latest formatter"

This reverts commit 03627aa84d.
This commit is contained in:
Alex Rickabaugh
2016-04-12 09:40:37 -07:00
parent 03627aa84d
commit 60727c4d2b
527 changed files with 19247 additions and 13970 deletions

View File

@ -1,8 +1,36 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, TestComponentBuilder, beforeEachProviders} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder,
beforeEachProviders
} from 'angular2/testing_internal';
import {MapWrapper} from 'angular2/src/facade/collection';
import {CompileDirectiveMetadata, CompileTypeMetadata} from 'angular2/src/compiler/directive_metadata';
import {
CompileDirectiveMetadata,
CompileTypeMetadata
} from 'angular2/src/compiler/directive_metadata';
import {TemplateParser} from 'angular2/src/compiler/template_parser';
import {Parser, Lexer, ChangeDetectorDefinition, ChangeDetectorGenConfig, DynamicProtoChangeDetector, ChangeDetectionStrategy, ChangeDispatcher, DirectiveIndex, Locals, BindingTarget, ChangeDetector} from 'angular2/src/core/change_detection/change_detection';
import {
Parser,
Lexer,
ChangeDetectorDefinition,
ChangeDetectorGenConfig,
DynamicProtoChangeDetector,
ChangeDetectionStrategy,
ChangeDispatcher,
DirectiveIndex,
Locals,
BindingTarget,
ChangeDetector
} from 'angular2/src/core/change_detection/change_detection';
import {Pipes} from 'angular2/src/core/change_detection/pipes';
import {createChangeDetectorDefinitions} from 'angular2/src/compiler/change_definition_factory';
import {TestDirective, TestDispatcher, TestPipes} from './change_detector_mocks';
@ -29,14 +57,13 @@ export function main() {
pipes = new TestPipes();
}));
function createChangeDetector(
template: string, directives: CompileDirectiveMetadata[],
protoViewIndex: number = 0): ChangeDetector {
function createChangeDetector(template: string, directives: CompileDirectiveMetadata[],
protoViewIndex: number = 0): ChangeDetector {
var protoChangeDetectors =
createChangeDetectorDefinitions(
new CompileTypeMetadata({name: 'SomeComp'}), ChangeDetectionStrategy.Default,
new ChangeDetectorGenConfig(true, false, false),
parser.parse(template, directives, [], 'TestComp'))
createChangeDetectorDefinitions(new CompileTypeMetadata({name: 'SomeComp'}),
ChangeDetectionStrategy.Default,
new ChangeDetectorGenConfig(true, false, false),
parser.parse(template, directives, [], 'TestComp'))
.map(definition => new DynamicProtoChangeDetector(definition));
var changeDetector = protoChangeDetectors[protoViewIndex].instantiate();
changeDetector.hydrate(context, locals, dispatcher, pipes);

View File

@ -1,4 +1,17 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {provide} from 'angular2/src/core/di';
import {CONST_EXPR, stringify, IS_DART} from 'angular2/src/facade/lang';
@ -6,12 +19,28 @@ import {MapWrapper} from 'angular2/src/facade/collection';
import {ChangeDetectionCompiler} from 'angular2/src/compiler/change_detector_compiler';
import {CompileDirectiveMetadata, CompileTypeMetadata} from 'angular2/src/compiler/directive_metadata';
import {SourceModule, SourceExpression, SourceExpressions, moduleRef} from 'angular2/src/compiler/source_module';
import {
CompileDirectiveMetadata,
CompileTypeMetadata
} from 'angular2/src/compiler/directive_metadata';
import {
SourceModule,
SourceExpression,
SourceExpressions,
moduleRef
} from 'angular2/src/compiler/source_module';
import {TemplateParser} from 'angular2/src/compiler/template_parser';
import {ChangeDetectorGenConfig, ChangeDetectionStrategy, ChangeDispatcher, DirectiveIndex, Locals, BindingTarget, ChangeDetector} from 'angular2/src/core/change_detection/change_detection';
import {
ChangeDetectorGenConfig,
ChangeDetectionStrategy,
ChangeDispatcher,
DirectiveIndex,
Locals,
BindingTarget,
ChangeDetector
} from 'angular2/src/core/change_detection/change_detection';
import {evalModule} from './eval_module';
@ -31,15 +60,18 @@ export function main() {
return;
}
describe('ChangeDetectorCompiler', () => {
beforeEachProviders(() => [TEST_PROVIDERS, provide(ChangeDetectorGenConfig, {
useValue: new ChangeDetectorGenConfig(true, false, false)
})]);
beforeEachProviders(() => [
TEST_PROVIDERS,
provide(ChangeDetectorGenConfig,
{useValue: new ChangeDetectorGenConfig(true, false, false)})
]);
var parser: TemplateParser;
var compiler: ChangeDetectionCompiler;
beforeEachProviders(
() => [provide(
ChangeDetectorGenConfig, {useValue: new ChangeDetectorGenConfig(true, false, false)})]);
beforeEachProviders(() => [
provide(ChangeDetectorGenConfig,
{useValue: new ChangeDetectorGenConfig(true, false, false)})
]);
beforeEach(inject([TemplateParser, ChangeDetectionCompiler], (_parser, _compiler) => {
parser = _parser;
@ -47,9 +79,8 @@ export function main() {
}));
describe('compileComponentRuntime', () => {
function detectChanges(
compiler: ChangeDetectionCompiler, template: string,
directives: CompileDirectiveMetadata[] = CONST_EXPR([])): string[] {
function detectChanges(compiler: ChangeDetectionCompiler, template: string,
directives: CompileDirectiveMetadata[] = CONST_EXPR([])): string[] {
var type =
new CompileTypeMetadata({name: stringify(SomeComponent), moduleUrl: THIS_MODULE_URL});
var parsedTemplate = parser.parse(template, directives, [], 'TestComp');
@ -59,9 +90,8 @@ export function main() {
}
it('should watch element properties', () => {
expect(detectChanges(compiler, '<div [elProp]="someProp">')).toEqual([
'elementProperty(elProp)=someValue'
]);
expect(detectChanges(compiler, '<div [elProp]="someProp">'))
.toEqual(['elementProperty(elProp)=someValue']);
});
});
@ -79,10 +109,11 @@ export function main() {
}
it('should watch element properties', inject([AsyncTestCompleter], (async) => {
detectChanges(compiler, '<div [elProp]="someProp">').then((value) => {
expect(value).toEqual(['elementProperty(elProp)=someValue']);
async.done();
});
detectChanges(compiler, '<div [elProp]="someProp">')
.then((value) => {
expect(value).toEqual(['elementProperty(elProp)=someValue']);
async.done();
});
}));
});
@ -90,8 +121,8 @@ export function main() {
});
}
function createTestableModule(
source: SourceExpressions, changeDetectorIndex: number): SourceModule {
function createTestableModule(source: SourceExpressions,
changeDetectorIndex: number): SourceModule {
var resultExpression =
`${THIS_MODULE_REF}testChangeDetector(([${source.expressions.join(',')}])[${changeDetectorIndex}])`;
var testableSource = `${source.declarations.join('\n')}

View File

@ -1,7 +1,12 @@
import {isBlank} from 'angular2/src/facade/lang';
import {Pipes} from 'angular2/src/core/change_detection/pipes';
import {EventEmitter} from 'angular2/src/facade/async';
import {ChangeDetector, ChangeDispatcher, DirectiveIndex, BindingTarget} from 'angular2/src/core/change_detection/change_detection';
import {
ChangeDetector,
ChangeDispatcher,
DirectiveIndex,
BindingTarget
} from 'angular2/src/core/change_detection/change_detection';
export class TestDirective {
eventLog: string[] = [];

View File

@ -1,12 +1,27 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {isPresent} from 'angular2/src/facade/lang';
import {isPresent} from "angular2/src/facade/lang";
import {CssToken, CssScannerError, CssLexer, CssLexerMode, CssTokenType} from 'angular2/src/compiler/css/lexer';
import {
CssToken,
CssScannerError,
CssLexer,
CssLexerMode,
CssTokenType
} from 'angular2/src/compiler/css/lexer';
export function main() {
function tokenize(
code, trackComments: boolean = false, mode: CssLexerMode = CssLexerMode.ALL): CssToken[] {
function tokenize(code, trackComments: boolean = false,
mode: CssLexerMode = CssLexerMode.ALL): CssToken[] {
var scanner = new CssLexer().scan(code, trackComments);
scanner.setMode(mode);
@ -26,7 +41,7 @@ export function main() {
describe('CssLexer', () => {
it('should lex newline characters as whitespace when whitespace mode is on', () => {
var newlines = ['\n', '\r\n', '\r', '\f'];
var newlines = ["\n", "\r\n", "\r", "\f"];
newlines.forEach((line) => {
var token = tokenize(line, false, CssLexerMode.ALL_TRACK_WS)[0];
expect(token.type).toEqual(CssTokenType.Whitespace);
@ -34,7 +49,7 @@ export function main() {
});
it('should combined newline characters as one newline token when whitespace mode is on', () => {
var newlines = ['\n', '\r\n', '\r', '\f'].join('');
var newlines = ["\n", "\r\n", "\r", "\f"].join("");
var tokens = tokenize(newlines, false, CssLexerMode.ALL_TRACK_WS);
expect(tokens.length).toEqual(1);
expect(tokens[0].type).toEqual(CssTokenType.Whitespace);
@ -42,14 +57,13 @@ export function main() {
it('should not consider whitespace or newline values at all when whitespace mode is off',
() => {
var newlines = ['\n', '\r\n', '\r', '\f'].join('');
var newlines = ["\n", "\r\n", "\r", "\f"].join("");
var tokens = tokenize(newlines);
expect(tokens.length).toEqual(0);
});
it('should lex simple selectors and their inner properties', () => {
var cssCode = '\n' +
' .selector { my-prop: my-value; }\n';
var cssCode = "\n" + " .selector { my-prop: my-value; }\n";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Character);
@ -78,9 +92,7 @@ export function main() {
});
it('should capture the column and line values for each token', () => {
var cssCode = '#id {\n' +
' prop:value;\n' +
'}';
var cssCode = "#id {\n" + " prop:value;\n" + "}";
var tokens = tokenize(cssCode);
@ -126,13 +138,13 @@ export function main() {
});
it('should lex quoted strings and escape accordingly', () => {
var cssCode = 'prop: \'some { value } \\\' that is quoted\'';
var cssCode = "prop: 'some { value } \\' that is quoted'";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Identifier);
expect(tokens[1].type).toEqual(CssTokenType.Character);
expect(tokens[2].type).toEqual(CssTokenType.String);
expect(tokens[2].strValue).toEqual('\'some { value } \\\' that is quoted\'');
expect(tokens[2].strValue).toEqual("'some { value } \\' that is quoted'");
});
it('should treat attribute operators as regular characters', () => {
@ -140,27 +152,27 @@ export function main() {
});
it('should lex numbers properly and set them as numbers', () => {
var cssCode = '0 1 -2 3.0 -4.001';
var cssCode = "0 1 -2 3.0 -4.001";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Number);
expect(tokens[0].strValue).toEqual('0');
expect(tokens[0].strValue).toEqual("0");
expect(tokens[1].type).toEqual(CssTokenType.Number);
expect(tokens[1].strValue).toEqual('1');
expect(tokens[1].strValue).toEqual("1");
expect(tokens[2].type).toEqual(CssTokenType.Number);
expect(tokens[2].strValue).toEqual('-2');
expect(tokens[2].strValue).toEqual("-2");
expect(tokens[3].type).toEqual(CssTokenType.Number);
expect(tokens[3].strValue).toEqual('3.0');
expect(tokens[3].strValue).toEqual("3.0");
expect(tokens[4].type).toEqual(CssTokenType.Number);
expect(tokens[4].strValue).toEqual('-4.001');
expect(tokens[4].strValue).toEqual("-4.001");
});
it('should lex @keywords', () => {
var cssCode = '@import()@something';
var cssCode = "@import()@something";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.AtKeyword);
@ -177,7 +189,7 @@ export function main() {
});
it('should still lex a number even if it has a dimension suffix', () => {
var cssCode = '40% is 40 percent';
var cssCode = "40% is 40 percent";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Number);
@ -194,7 +206,7 @@ export function main() {
});
it('should allow escaped character and unicode character-strings in CSS selectors', () => {
var cssCode = '\\123456 .some\\thing \{\}';
var cssCode = "\\123456 .some\\thing \{\}";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Identifier);
@ -206,67 +218,67 @@ export function main() {
});
it('should distinguish identifiers and numbers from special characters', () => {
var cssCode = 'one*two=-4+three-4-equals_value$';
var cssCode = "one*two=-4+three-4-equals_value$";
var tokens = tokenize(cssCode);
expect(tokens[0].type).toEqual(CssTokenType.Identifier);
expect(tokens[0].strValue).toEqual('one');
expect(tokens[0].strValue).toEqual("one");
expect(tokens[1].type).toEqual(CssTokenType.Character);
expect(tokens[1].strValue).toEqual('*');
expect(tokens[1].strValue).toEqual("*");
expect(tokens[2].type).toEqual(CssTokenType.Identifier);
expect(tokens[2].strValue).toEqual('two');
expect(tokens[2].strValue).toEqual("two");
expect(tokens[3].type).toEqual(CssTokenType.Character);
expect(tokens[3].strValue).toEqual('=');
expect(tokens[3].strValue).toEqual("=");
expect(tokens[4].type).toEqual(CssTokenType.Number);
expect(tokens[4].strValue).toEqual('-4');
expect(tokens[4].strValue).toEqual("-4");
expect(tokens[5].type).toEqual(CssTokenType.Character);
expect(tokens[5].strValue).toEqual('+');
expect(tokens[5].strValue).toEqual("+");
expect(tokens[6].type).toEqual(CssTokenType.Identifier);
expect(tokens[6].strValue).toEqual('three-4-equals_value');
expect(tokens[6].strValue).toEqual("three-4-equals_value");
expect(tokens[7].type).toEqual(CssTokenType.Character);
expect(tokens[7].strValue).toEqual('$');
expect(tokens[7].strValue).toEqual("$");
});
it('should filter out comments and whitespace by default', () => {
var cssCode = '.selector /* comment */ { /* value */ }';
var cssCode = ".selector /* comment */ { /* value */ }";
var tokens = tokenize(cssCode);
expect(tokens[0].strValue).toEqual('.');
expect(tokens[1].strValue).toEqual('selector');
expect(tokens[2].strValue).toEqual('{');
expect(tokens[3].strValue).toEqual('}');
expect(tokens[0].strValue).toEqual(".");
expect(tokens[1].strValue).toEqual("selector");
expect(tokens[2].strValue).toEqual("{");
expect(tokens[3].strValue).toEqual("}");
});
it('should track comments when the flag is set to true', () => {
var cssCode = '.selector /* comment */ { /* value */ }';
var cssCode = ".selector /* comment */ { /* value */ }";
var trackComments = true;
var tokens = tokenize(cssCode, trackComments, CssLexerMode.ALL_TRACK_WS);
expect(tokens[0].strValue).toEqual('.');
expect(tokens[1].strValue).toEqual('selector');
expect(tokens[2].strValue).toEqual(' ');
expect(tokens[0].strValue).toEqual(".");
expect(tokens[1].strValue).toEqual("selector");
expect(tokens[2].strValue).toEqual(" ");
expect(tokens[3].type).toEqual(CssTokenType.Comment);
expect(tokens[3].strValue).toEqual('/* comment */');
expect(tokens[3].strValue).toEqual("/* comment */");
expect(tokens[4].strValue).toEqual(' ');
expect(tokens[5].strValue).toEqual('{');
expect(tokens[6].strValue).toEqual(' ');
expect(tokens[4].strValue).toEqual(" ");
expect(tokens[5].strValue).toEqual("{");
expect(tokens[6].strValue).toEqual(" ");
expect(tokens[7].type).toEqual(CssTokenType.Comment);
expect(tokens[7].strValue).toEqual('/* value */');
expect(tokens[7].strValue).toEqual("/* value */");
});
describe('Selector Mode', () => {
it('should throw an error if a selector is being parsed while in the wrong mode', () => {
var cssCode = '.class > tag';
var cssCode = ".class > tag";
var capturedMessage;
try {
@ -293,18 +305,18 @@ export function main() {
it('should consider attribute selectors as valid input and throw when an invalid modifier is used',
() => {
function tokenizeAttr(modifier) {
var cssCode = 'value' + modifier + '=\'something\'';
var cssCode = "value" + modifier + "='something'";
return tokenize(cssCode, false, CssLexerMode.ATTRIBUTE_SELECTOR);
}
expect(tokenizeAttr('*').length).toEqual(4);
expect(tokenizeAttr('|').length).toEqual(4);
expect(tokenizeAttr('^').length).toEqual(4);
expect(tokenizeAttr('$').length).toEqual(4);
expect(tokenizeAttr('~').length).toEqual(4);
expect(tokenizeAttr('').length).toEqual(3);
expect(tokenizeAttr("*").length).toEqual(4);
expect(tokenizeAttr("|").length).toEqual(4);
expect(tokenizeAttr("^").length).toEqual(4);
expect(tokenizeAttr("$").length).toEqual(4);
expect(tokenizeAttr("~").length).toEqual(4);
expect(tokenizeAttr("").length).toEqual(3);
expect(() => { tokenizeAttr('+'); }).toThrow();
expect(() => { tokenizeAttr("+"); }).toThrow();
});
});
@ -314,15 +326,15 @@ export function main() {
// the reason why the numbers are so high is because MediaQueries keep
// track of the whitespace values
expect(tokenizeQuery('(prop: value)').length).toEqual(5);
expect(tokenizeQuery('(prop: value) and (prop2: value2)').length).toEqual(11);
expect(tokenizeQuery('tv and (prop: value)').length).toEqual(7);
expect(tokenizeQuery('print and ((prop: value) or (prop2: value2))').length).toEqual(15);
expect(tokenizeQuery('(content: \'something $ crazy inside &\')').length).toEqual(5);
expect(tokenizeQuery("(prop: value)").length).toEqual(5);
expect(tokenizeQuery("(prop: value) and (prop2: value2)").length).toEqual(11);
expect(tokenizeQuery("tv and (prop: value)").length).toEqual(7);
expect(tokenizeQuery("print and ((prop: value) or (prop2: value2))").length).toEqual(15);
expect(tokenizeQuery("(content: 'something $ crazy inside &')").length).toEqual(5);
expect(() => { tokenizeQuery('(max-height: 10 + 20)'); }).toThrow();
expect(() => { tokenizeQuery("(max-height: 10 + 20)"); }).toThrow();
expect(() => { tokenizeQuery('(max-height: fifty < 100)'); }).toThrow();
expect(() => { tokenizeQuery("(max-height: fifty < 100)"); }).toThrow();
});
});
@ -333,13 +345,13 @@ export function main() {
return tokenize(code, false, CssLexerMode.PSEUDO_SELECTOR);
}
expect(tokenizePseudo('lang(en-us)').length).toEqual(4);
expect(tokenizePseudo('hover').length).toEqual(1);
expect(tokenizePseudo('focus').length).toEqual(1);
expect(tokenizePseudo("lang(en-us)").length).toEqual(4);
expect(tokenizePseudo("hover").length).toEqual(1);
expect(tokenizePseudo("focus").length).toEqual(1);
expect(() => { tokenizePseudo('lang(something:broken)'); }).toThrow();
expect(() => { tokenizePseudo("lang(something:broken)"); }).toThrow();
expect(() => { tokenizePseudo('not(.selector)'); }).toThrow();
expect(() => { tokenizePseudo("not(.selector)"); }).toThrow();
});
});
@ -350,35 +362,32 @@ export function main() {
return tokenize(code, false, CssLexerMode.PSEUDO_SELECTOR);
}
expect(tokenizePseudo('lang(en-us)').length).toEqual(4);
expect(tokenizePseudo('hover').length).toEqual(1);
expect(tokenizePseudo('focus').length).toEqual(1);
expect(tokenizePseudo("lang(en-us)").length).toEqual(4);
expect(tokenizePseudo("hover").length).toEqual(1);
expect(tokenizePseudo("focus").length).toEqual(1);
expect(() => { tokenizePseudo('lang(something:broken)'); }).toThrow();
expect(() => { tokenizePseudo("lang(something:broken)"); }).toThrow();
expect(() => { tokenizePseudo('not(.selector)'); }).toThrow();
expect(() => { tokenizePseudo("not(.selector)"); }).toThrow();
});
});
describe(
'Style Block Mode', () => {
it('should style blocks with a reduced subset of valid characters',
() => {
function tokenizeStyles(code) {
return tokenize(code, false, CssLexerMode.STYLE_BLOCK);
}
describe('Style Block Mode', () => {
it('should style blocks with a reduced subset of valid characters', () => {
function tokenizeStyles(code) { return tokenize(code, false, CssLexerMode.STYLE_BLOCK); }
expect(tokenizeStyles(`
expect(tokenizeStyles(`
key: value;
prop: 100;
style: value3!important;
`).length).toEqual(14);
`).length)
.toEqual(14);
expect(() => tokenizeStyles(` key$: value; `)).toThrow();
expect(() => tokenizeStyles(` key: value$; `)).toThrow();
expect(() => tokenizeStyles(` key: value + 10; `)).toThrow();
expect(() => tokenizeStyles(` key: &value; `)).toThrow();
});
});
expect(() => tokenizeStyles(` key$: value; `)).toThrow();
expect(() => tokenizeStyles(` key: value$; `)).toThrow();
expect(() => tokenizeStyles(` key: value + 10; `)).toThrow();
expect(() => tokenizeStyles(` key: &value; `)).toThrow();
});
});
});
}

View File

@ -1,8 +1,35 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {BaseException} from 'angular2/src/facade/exceptions';
import {ParsedCssResult, CssParser, BlockType, CssSelectorRuleAST, CssKeyframeRuleAST, CssKeyframeDefinitionAST, CssBlockDefinitionRuleAST, CssMediaQueryRuleAST, CssBlockRuleAST, CssInlineRuleAST, CssStyleValueAST, CssSelectorAST, CssDefinitionAST, CssStyleSheetAST, CssRuleAST, CssBlockAST, CssParseError} from 'angular2/src/compiler/css/parser';
import {
ParsedCssResult,
CssParser,
BlockType,
CssSelectorRuleAST,
CssKeyframeRuleAST,
CssKeyframeDefinitionAST,
CssBlockDefinitionRuleAST,
CssMediaQueryRuleAST,
CssBlockRuleAST,
CssInlineRuleAST,
CssStyleValueAST,
CssSelectorAST,
CssDefinitionAST,
CssStyleSheetAST,
CssRuleAST,
CssBlockAST,
CssParseError
} from 'angular2/src/compiler/css/parser';
import {CssLexer} from 'angular2/src/compiler/css/lexer';
@ -67,17 +94,17 @@ export function main() {
var rule = <CssSelectorRuleAST>ast.rules[0];
expect(rule.selectors.length).toBe(7);
assertTokens(rule.selectors[0].tokens, ['.', 'class']);
assertTokens(rule.selectors[1].tokens, ['#', 'id']);
assertTokens(rule.selectors[2].tokens, ['tag']);
assertTokens(rule.selectors[3].tokens, ['[', 'attr', ']']);
assertTokens(rule.selectors[4].tokens, ['key', ' ', '+', ' ', 'value']);
assertTokens(rule.selectors[5].tokens, ['*', ' ', 'value']);
assertTokens(rule.selectors[6].tokens, [':', '-moz-any-link']);
assertTokens(rule.selectors[0].tokens, [".", "class"]);
assertTokens(rule.selectors[1].tokens, ["#", "id"]);
assertTokens(rule.selectors[2].tokens, ["tag"]);
assertTokens(rule.selectors[3].tokens, ["[", "attr", "]"]);
assertTokens(rule.selectors[4].tokens, ["key", " ", "+", " ", "value"]);
assertTokens(rule.selectors[5].tokens, ["*", " ", "value"]);
assertTokens(rule.selectors[6].tokens, [":", "-moz-any-link"]);
var style1 = <CssDefinitionAST>rule.block.entries[0];
expect(style1.property.strValue).toEqual('prop');
assertTokens(style1.value.tokens, ['value123']);
expect(style1.property.strValue).toEqual("prop");
assertTokens(style1.value.tokens, ["value123"]);
});
it('should parse keyframe rules', () => {
@ -160,16 +187,16 @@ export function main() {
var importRule = <CssInlineRuleAST>ast.rules[0];
expect(importRule.type).toEqual(BlockType.Import);
assertTokens(importRule.value.tokens, ['url', '(', 'remote', '.', 'css', ')']);
assertTokens(importRule.value.tokens, ["url", "(", "remote", ".", "css", ")"]);
var charsetRule = <CssInlineRuleAST>ast.rules[1];
expect(charsetRule.type).toEqual(BlockType.Charset);
assertTokens(charsetRule.value.tokens, ['UTF-8']);
assertTokens(charsetRule.value.tokens, ["UTF-8"]);
var namespaceRule = <CssInlineRuleAST>ast.rules[2];
expect(namespaceRule.type).toEqual(BlockType.Namespace);
assertTokens(
namespaceRule.value.tokens, ['ng', 'url', '(', 'http://angular.io/namespace/ng', ')']);
assertTokens(namespaceRule.value.tokens,
["ng", "url", "(", "http://angular.io/namespace/ng", ")"]);
});
it('should parse CSS values that contain functions and leave the inner function data untokenized',
@ -189,9 +216,8 @@ export function main() {
expect(defs.length).toEqual(3);
assertTokens((<CssDefinitionAST>defs[0]).value.tokens, ['url', '(', 'matias.css', ')']);
assertTokens(
(<CssDefinitionAST>defs[1]).value.tokens,
['cubic-bezier', '(', '0.755, 0.050, 0.855, 0.060', ')']);
assertTokens((<CssDefinitionAST>defs[1]).value.tokens,
['cubic-bezier', '(', '0.755, 0.050, 0.855, 0.060', ')']);
assertTokens((<CssDefinitionAST>defs[2]).value.tokens, ['calc', '(', '100% - 50px', ')']);
});
@ -239,7 +265,7 @@ export function main() {
var importRule = <CssInlineRuleAST>ast.rules[0];
expect(importRule.type).toEqual(BlockType.Import);
assertTokens(importRule.value.tokens, ['url', '(', 'something something', ')']);
assertTokens(importRule.value.tokens, ["url", "(", "something something", ")"]);
var fontFaceRule = <CssBlockRuleAST>ast.rules[1];
expect(fontFaceRule.type).toEqual(BlockType.FontFace);
@ -304,7 +330,7 @@ export function main() {
expect(documentRule.type).toEqual(BlockType.Document);
var rule = <CssSelectorRuleAST>documentRule.block.entries[0];
expect(rule.strValue).toEqual('body');
expect(rule.strValue).toEqual("body");
});
it('should parse the @page rule', () => {
@ -322,11 +348,11 @@ export function main() {
var rules = ast.rules;
var pageRule1 = <CssBlockDefinitionRuleAST>rules[0];
expect(pageRule1.strValue).toEqual('one');
expect(pageRule1.strValue).toEqual("one");
expect(pageRule1.type).toEqual(BlockType.Page);
var pageRule2 = <CssBlockDefinitionRuleAST>rules[1];
expect(pageRule2.strValue).toEqual('two');
expect(pageRule2.strValue).toEqual("two");
expect(pageRule2.type).toEqual(BlockType.Page);
var selectorOne = <CssSelectorRuleAST>pageRule1.block.entries[0];
@ -382,15 +408,15 @@ export function main() {
expect(ast.rules.length).toEqual(3);
var rule1 = <CssSelectorRuleAST>ast.rules[0];
expect(rule1.selectors[0].strValue).toEqual('tag&');
expect(rule1.selectors[0].strValue).toEqual("tag&");
expect(rule1.block.entries.length).toEqual(1);
var rule2 = <CssSelectorRuleAST>ast.rules[1];
expect(rule2.selectors[0].strValue).toEqual('.%tag');
expect(rule2.selectors[0].strValue).toEqual(".%tag");
expect(rule2.block.entries.length).toEqual(1);
var rule3 = <CssSelectorRuleAST>ast.rules[2];
expect(rule3.selectors[0].strValue).toEqual('#tag$');
expect(rule3.selectors[0].strValue).toEqual("#tag$");
expect(rule3.block.entries.length).toEqual(1);
});

View File

@ -1,9 +1,39 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {NumberWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang';
import {NumberWrapper, StringWrapper, isPresent} from "angular2/src/facade/lang";
import {BaseException} from 'angular2/src/facade/exceptions';
import {CssToken, CssParser, CssParseError, BlockType, CssAST, CssSelectorRuleAST, CssKeyframeRuleAST, CssKeyframeDefinitionAST, CssBlockDefinitionRuleAST, CssMediaQueryRuleAST, CssBlockRuleAST, CssInlineRuleAST, CssStyleValueAST, CssSelectorAST, CssDefinitionAST, CssStyleSheetAST, CssRuleAST, CssBlockAST, CssASTVisitor, CssUnknownTokenListAST} from 'angular2/src/compiler/css/parser';
import {
CssToken,
CssParser,
CssParseError,
BlockType,
CssAST,
CssSelectorRuleAST,
CssKeyframeRuleAST,
CssKeyframeDefinitionAST,
CssBlockDefinitionRuleAST,
CssMediaQueryRuleAST,
CssBlockRuleAST,
CssInlineRuleAST,
CssStyleValueAST,
CssSelectorAST,
CssDefinitionAST,
CssStyleSheetAST,
CssRuleAST,
CssBlockAST,
CssASTVisitor,
CssUnknownTokenListAST
} from 'angular2/src/compiler/css/parser';
import {CssLexer} from 'angular2/src/compiler/css/lexer';
@ -23,49 +53,49 @@ class MyVisitor implements CssASTVisitor {
constructor(ast: CssStyleSheetAST, context?: any) { ast.visit(this, context); }
visitCssValue(ast, context?: any): void { this._capture('visitCssValue', ast, context); }
visitCssValue(ast, context?: any): void { this._capture("visitCssValue", ast, context); }
visitInlineCssRule(ast, context?: any): void {
this._capture('visitInlineCssRule', ast, context);
this._capture("visitInlineCssRule", ast, context);
}
visitCssKeyframeRule(ast: CssKeyframeRuleAST, context?: any): void {
this._capture('visitCssKeyframeRule', ast, context);
this._capture("visitCssKeyframeRule", ast, context);
ast.block.visit(this, context);
}
visitCssKeyframeDefinition(ast: CssKeyframeDefinitionAST, context?: any): void {
this._capture('visitCssKeyframeDefinition', ast, context);
this._capture("visitCssKeyframeDefinition", ast, context);
ast.block.visit(this, context);
}
visitCssMediaQueryRule(ast: CssMediaQueryRuleAST, context?: any): void {
this._capture('visitCssMediaQueryRule', ast, context);
this._capture("visitCssMediaQueryRule", ast, context);
ast.block.visit(this, context);
}
visitCssSelectorRule(ast: CssSelectorRuleAST, context?: any): void {
this._capture('visitCssSelectorRule', ast, context);
this._capture("visitCssSelectorRule", ast, context);
ast.selectors.forEach((selAST: CssSelectorAST) => { selAST.visit(this, context); });
ast.block.visit(this, context);
}
visitCssSelector(ast: CssSelectorAST, context?: any): void {
this._capture('visitCssSelector', ast, context);
this._capture("visitCssSelector", ast, context);
}
visitCssDefinition(ast: CssDefinitionAST, context?: any): void {
this._capture('visitCssDefinition', ast, context);
this._capture("visitCssDefinition", ast, context);
ast.value.visit(this, context);
}
visitCssBlock(ast: CssBlockAST, context?: any): void {
this._capture('visitCssBlock', ast, context);
this._capture("visitCssBlock", ast, context);
ast.entries.forEach((entryAST: CssAST) => { entryAST.visit(this, context); });
}
visitCssStyleSheet(ast: CssStyleSheetAST, context?: any): void {
this._capture('visitCssStyleSheet', ast, context);
this._capture("visitCssStyleSheet", ast, context);
ast.rules.forEach((ruleAST: CssRuleAST) => { ruleAST.visit(this, context); });
}
@ -178,7 +208,7 @@ export function main() {
expect(captures.length).toEqual(1);
var query1 = <CssMediaQueryRuleAST>captures[0][0];
_assertTokens(query1.query, ['all', 'and', '(', 'max-width', '100', 'px', ')']);
_assertTokens(query1.query, ["all", "and", "(", "max-width", "100", "px", ")"]);
expect(query1.block.entries.length).toEqual(1);
});

View File

@ -1,6 +1,27 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, TestComponentBuilder} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder
} from 'angular2/testing_internal';
import {CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata, CompileProviderMetadata, CompileDiDependencyMetadata, CompileQueryMetadata, CompileIdentifierMetadata, CompileFactoryMetadata} from 'angular2/src/compiler/directive_metadata';
import {
CompileDirectiveMetadata,
CompileTypeMetadata,
CompileTemplateMetadata,
CompileProviderMetadata,
CompileDiDependencyMetadata,
CompileQueryMetadata,
CompileIdentifierMetadata,
CompileFactoryMetadata
} from 'angular2/src/compiler/directive_metadata';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import {ChangeDetectionStrategy} from 'angular2/src/core/change_detection';
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
@ -46,24 +67,32 @@ export function main() {
outputs: ['someEvent'],
host: {'(event1)': 'handler1', '[prop1]': 'expr1', 'attr1': 'attrValue2'},
lifecycleHooks: [LifecycleHooks.OnChanges],
providers: [new CompileProviderMetadata({
token: 'token',
useClass: fullTypeMeta,
useExisting: new CompileIdentifierMetadata({name: 'someName'}),
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
useValue: 'someValue',
})],
viewProviders: [new CompileProviderMetadata({
token: 'token',
useClass: fullTypeMeta,
useExisting: new CompileIdentifierMetadata({name: 'someName'}),
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
useValue: 'someValue',
})],
queries: [new CompileQueryMetadata(
{selectors: ['selector'], descendants: true, first: false, propertyName: 'prop'})],
viewQueries: [new CompileQueryMetadata(
{selectors: ['selector'], descendants: true, first: false, propertyName: 'prop'})]
providers: [
new CompileProviderMetadata({
token: 'token',
useClass: fullTypeMeta,
useExisting: new CompileIdentifierMetadata({name: 'someName'}),
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
useValue: 'someValue',
})
],
viewProviders: [
new CompileProviderMetadata({
token: 'token',
useClass: fullTypeMeta,
useExisting: new CompileIdentifierMetadata({name: 'someName'}),
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
useValue: 'someValue',
})
],
queries: [
new CompileQueryMetadata(
{selectors: ['selector'], descendants: true, first: false, propertyName: 'prop'})
],
viewQueries: [
new CompileQueryMetadata(
{selectors: ['selector'], descendants: true, first: false, propertyName: 'prop'})
]
});
});

View File

@ -1,4 +1,16 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject
} from 'angular2/testing_internal';
import {IS_DART} from 'angular2/src/facade/lang';
import {evalModule} from './eval_module';
@ -19,10 +31,11 @@ export function main() {
it('should call the "run" function and allow to use imports',
inject([AsyncTestCompleter], (async) => {
var moduleSource = IS_DART ? testDartModule : testJsModule;
evalModule(moduleSource, [[THIS_MODULE_URL, 'tst']], [1]).then((value) => {
expect(value).toEqual([1, 23]);
async.done();
});
evalModule(moduleSource, [[THIS_MODULE_URL, 'tst']], [1])
.then((value) => {
expect(value).toEqual([1, 23]);
async.done();
});
}));
});
}

View File

@ -1,5 +1,13 @@
import {HtmlParser, HtmlParseTreeResult, HtmlTreeError} from 'angular2/src/compiler/html_parser';
import {HtmlAst, HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from 'angular2/src/compiler/html_ast';
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
htmlVisitAll
} from 'angular2/src/compiler/html_ast';
import {ParseError, ParseLocation} from 'angular2/src/compiler/parse_util';
import {BaseException} from 'angular2/src/facade/exceptions';

View File

@ -1,479 +1,584 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {BaseException} from 'angular2/src/facade/exceptions';
import {tokenizeHtml, HtmlToken, HtmlTokenType, HtmlTokenError} from 'angular2/src/compiler/html_lexer';
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', () => {
describe('line/column numbers', () => {
it('should work without newlines', () => {
expect(tokenizeAndHumanizeLineColumn('<t>a</t>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'], [HtmlTokenType.TAG_OPEN_END, '0:2'],
[HtmlTokenType.TEXT, '0:3'], [HtmlTokenType.TAG_CLOSE, '0:4'],
[HtmlTokenType.EOF, '0:8']
]);
expect(tokenizeAndHumanizeLineColumn('<t>a</t>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'],
[HtmlTokenType.TAG_OPEN_END, '0:2'],
[HtmlTokenType.TEXT, '0:3'],
[HtmlTokenType.TAG_CLOSE, '0:4'],
[HtmlTokenType.EOF, '0:8']
]);
});
it('should work with one newline', () => {
expect(tokenizeAndHumanizeLineColumn('<t>\na</t>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'], [HtmlTokenType.TAG_OPEN_END, '0:2'],
[HtmlTokenType.TEXT, '0:3'], [HtmlTokenType.TAG_CLOSE, '1:1'],
[HtmlTokenType.EOF, '1:5']
]);
expect(tokenizeAndHumanizeLineColumn('<t>\na</t>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'],
[HtmlTokenType.TAG_OPEN_END, '0:2'],
[HtmlTokenType.TEXT, '0:3'],
[HtmlTokenType.TAG_CLOSE, '1:1'],
[HtmlTokenType.EOF, '1:5']
]);
});
it('should work with multiple newlines', () => {
expect(tokenizeAndHumanizeLineColumn('<t\n>\na</t>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'], [HtmlTokenType.TAG_OPEN_END, '1:0'],
[HtmlTokenType.TEXT, '1:1'], [HtmlTokenType.TAG_CLOSE, '2:1'],
[HtmlTokenType.EOF, '2:5']
]);
expect(tokenizeAndHumanizeLineColumn('<t\n>\na</t>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'],
[HtmlTokenType.TAG_OPEN_END, '1:0'],
[HtmlTokenType.TEXT, '1:1'],
[HtmlTokenType.TAG_CLOSE, '2:1'],
[HtmlTokenType.EOF, '2:5']
]);
});
it('should work with CR and LF', () => {
expect(tokenizeAndHumanizeLineColumn('<t\n>\r\na\r</t>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'], [HtmlTokenType.TAG_OPEN_END, '1:0'],
[HtmlTokenType.TEXT, '1:1'], [HtmlTokenType.TAG_CLOSE, '2:1'],
[HtmlTokenType.EOF, '2:5']
]);
expect(tokenizeAndHumanizeLineColumn('<t\n>\r\na\r</t>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '0:0'],
[HtmlTokenType.TAG_OPEN_END, '1:0'],
[HtmlTokenType.TEXT, '1:1'],
[HtmlTokenType.TAG_CLOSE, '2:1'],
[HtmlTokenType.EOF, '2:5']
]);
});
});
describe('comments', () => {
it('should parse comments', () => {
expect(tokenizeAndHumanizeParts('<!--t\ne\rs\r\nt-->')).toEqual([
[HtmlTokenType.COMMENT_START], [HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.COMMENT_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<!--t\ne\rs\r\nt-->'))
.toEqual([
[HtmlTokenType.COMMENT_START],
[HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.COMMENT_END],
[HtmlTokenType.EOF]
]);
});
it('should store the locations',
() => {expect(tokenizeAndHumanizeSourceSpans('<!--t\ne\rs\r\nt-->')).toEqual([
[HtmlTokenType.COMMENT_START, '<!--'], [HtmlTokenType.RAW_TEXT, 't\ne\rs\r\nt'],
[HtmlTokenType.COMMENT_END, '-->'], [HtmlTokenType.EOF, '']
])});
() => {expect(tokenizeAndHumanizeSourceSpans('<!--t\ne\rs\r\nt-->'))
.toEqual([
[HtmlTokenType.COMMENT_START, '<!--'],
[HtmlTokenType.RAW_TEXT, 't\ne\rs\r\nt'],
[HtmlTokenType.COMMENT_END, '-->'],
[HtmlTokenType.EOF, '']
])});
it('should report <!- without -', () => {
expect(tokenizeAndHumanizeErrors('<!-a')).toEqual([
[HtmlTokenType.COMMENT_START, 'Unexpected character "a"', '0:3']
]);
expect(tokenizeAndHumanizeErrors('<!-a'))
.toEqual([[HtmlTokenType.COMMENT_START, 'Unexpected character "a"', '0:3']]);
});
it('should report missing end comment', () => {
expect(tokenizeAndHumanizeErrors('<!--')).toEqual([
[HtmlTokenType.RAW_TEXT, 'Unexpected character "EOF"', '0:4']
]);
expect(tokenizeAndHumanizeErrors('<!--'))
.toEqual([[HtmlTokenType.RAW_TEXT, 'Unexpected character "EOF"', '0:4']]);
});
});
describe('doctype', () => {
it('should parse doctypes', () => {
expect(tokenizeAndHumanizeParts('<!doctype html>')).toEqual([
[HtmlTokenType.DOC_TYPE, 'doctype html'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<!doctype html>'))
.toEqual([[HtmlTokenType.DOC_TYPE, 'doctype html'], [HtmlTokenType.EOF]]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('<!doctype html>')).toEqual([
[HtmlTokenType.DOC_TYPE, '<!doctype html>'], [HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('<!doctype html>'))
.toEqual([[HtmlTokenType.DOC_TYPE, '<!doctype html>'], [HtmlTokenType.EOF, '']]);
});
it('should report missing end doctype', () => {
expect(tokenizeAndHumanizeErrors('<!')).toEqual([
[HtmlTokenType.DOC_TYPE, 'Unexpected character "EOF"', '0:2']
]);
expect(tokenizeAndHumanizeErrors('<!'))
.toEqual([[HtmlTokenType.DOC_TYPE, 'Unexpected character "EOF"', '0:2']]);
});
});
describe('CDATA', () => {
it('should parse CDATA', () => {
expect(tokenizeAndHumanizeParts('<![CDATA[t\ne\rs\r\nt]]>')).toEqual([
[HtmlTokenType.CDATA_START], [HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.CDATA_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<![CDATA[t\ne\rs\r\nt]]>'))
.toEqual([
[HtmlTokenType.CDATA_START],
[HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.CDATA_END],
[HtmlTokenType.EOF]
]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('<![CDATA[t\ne\rs\r\nt]]>')).toEqual([
[HtmlTokenType.CDATA_START, '<![CDATA['], [HtmlTokenType.RAW_TEXT, 't\ne\rs\r\nt'],
[HtmlTokenType.CDATA_END, ']]>'], [HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('<![CDATA[t\ne\rs\r\nt]]>'))
.toEqual([
[HtmlTokenType.CDATA_START, '<![CDATA['],
[HtmlTokenType.RAW_TEXT, 't\ne\rs\r\nt'],
[HtmlTokenType.CDATA_END, ']]>'],
[HtmlTokenType.EOF, '']
]);
});
it('should report <![ without CDATA[', () => {
expect(tokenizeAndHumanizeErrors('<![a')).toEqual([
[HtmlTokenType.CDATA_START, 'Unexpected character "a"', '0:3']
]);
expect(tokenizeAndHumanizeErrors('<![a'))
.toEqual([[HtmlTokenType.CDATA_START, 'Unexpected character "a"', '0:3']]);
});
it('should report missing end cdata', () => {
expect(tokenizeAndHumanizeErrors('<![CDATA[')).toEqual([
[HtmlTokenType.RAW_TEXT, 'Unexpected character "EOF"', '0:9']
]);
expect(tokenizeAndHumanizeErrors('<![CDATA['))
.toEqual([[HtmlTokenType.RAW_TEXT, 'Unexpected character "EOF"', '0:9']]);
});
});
describe('open tags', () => {
it('should parse open tags without prefix', () => {
expect(tokenizeAndHumanizeParts('<test>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<test>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse namespace prefix', () => {
expect(tokenizeAndHumanizeParts('<ns1:test>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, 'ns1', 'test'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<ns1:test>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, 'ns1', 'test'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse void tags', () => {
expect(tokenizeAndHumanizeParts('<test/>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'], [HtmlTokenType.TAG_OPEN_END_VOID],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<test/>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'],
[HtmlTokenType.TAG_OPEN_END_VOID],
[HtmlTokenType.EOF]
]);
});
it('should allow whitespace after the tag name', () => {
expect(tokenizeAndHumanizeParts('<test >')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<test >'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'test'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('<test>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<test'], [HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('<test>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<test'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.EOF, '']
]);
});
});
describe('attributes', () => {
it('should parse attributes without prefix', () => {
expect(tokenizeAndHumanizeParts('<t a>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t a>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with prefix', () => {
expect(tokenizeAndHumanizeParts('<t ns1:a>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, 'ns1', 'a'],
[HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t ns1:a>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, 'ns1', 'a'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes whose prefix is not valid', () => {
expect(tokenizeAndHumanizeParts('<t (ns1:a)>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, '(ns1:a)'],
[HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t (ns1:a)>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, '(ns1:a)'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with single quote value', () => {
expect(tokenizeAndHumanizeParts('<t a=\'b\'>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'], [HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts("<t a='b'>"))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with double quote value', () => {
expect(tokenizeAndHumanizeParts('<t a="b">')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'], [HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t a="b">'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with unquoted value', () => {
expect(tokenizeAndHumanizeParts('<t a=b>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'], [HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t a=b>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should allow whitespace', () => {
expect(tokenizeAndHumanizeParts('<t a = b >')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'], [HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t a = b >'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should parse attributes with entities in values', () => {
expect(tokenizeAndHumanizeParts('<t a="&#65;&#x41;">')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 'AA'], [HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('<t a="&#65;&#x41;">'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, '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]
]);
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]
]);
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]
]);
});
it('should parse values with CR and LF', () => {
expect(tokenizeAndHumanizeParts('<t a=\'t\ne\rs\r\nt\'>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'], [HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 't\ne\ns\nt'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts("<t a='t\ne\rs\r\nt'>"))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 't'],
[HtmlTokenType.ATTR_NAME, null, 'a'],
[HtmlTokenType.ATTR_VALUE, 't\ne\ns\nt'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.EOF]
]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('<t a=b>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<t'], [HtmlTokenType.ATTR_NAME, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'], [HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('<t a=b>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<t'],
[HtmlTokenType.ATTR_NAME, 'a'],
[HtmlTokenType.ATTR_VALUE, 'b'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.EOF, '']
]);
});
});
describe('closing tags', () => {
it('should parse closing tags without prefix', () => {
expect(tokenizeAndHumanizeParts('</test>')).toEqual([
[HtmlTokenType.TAG_CLOSE, null, 'test'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('</test>'))
.toEqual([[HtmlTokenType.TAG_CLOSE, null, 'test'], [HtmlTokenType.EOF]]);
});
it('should parse closing tags with prefix', () => {
expect(tokenizeAndHumanizeParts('</ns1:test>')).toEqual([
[HtmlTokenType.TAG_CLOSE, 'ns1', 'test'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('</ns1:test>'))
.toEqual([[HtmlTokenType.TAG_CLOSE, 'ns1', 'test'], [HtmlTokenType.EOF]]);
});
it('should allow whitespace', () => {
expect(tokenizeAndHumanizeParts('</ test >')).toEqual([
[HtmlTokenType.TAG_CLOSE, null, 'test'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('</ test >'))
.toEqual([[HtmlTokenType.TAG_CLOSE, null, 'test'], [HtmlTokenType.EOF]]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('</test>')).toEqual([
[HtmlTokenType.TAG_CLOSE, '</test>'], [HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('</test>'))
.toEqual([[HtmlTokenType.TAG_CLOSE, '</test>'], [HtmlTokenType.EOF, '']]);
});
it('should report missing name after </', () => {
expect(tokenizeAndHumanizeErrors('</')).toEqual([
[HtmlTokenType.TAG_CLOSE, 'Unexpected character "EOF"', '0:2']
]);
expect(tokenizeAndHumanizeErrors('</'))
.toEqual([[HtmlTokenType.TAG_CLOSE, 'Unexpected character "EOF"', '0:2']]);
});
it('should report missing >', () => {
expect(tokenizeAndHumanizeErrors('</test')).toEqual([
[HtmlTokenType.TAG_CLOSE, 'Unexpected character "EOF"', '0:6']
]);
expect(tokenizeAndHumanizeErrors('</test'))
.toEqual([[HtmlTokenType.TAG_CLOSE, 'Unexpected character "EOF"', '0:6']]);
});
});
describe('entities', () => {
it('should parse named entities', () => {
expect(tokenizeAndHumanizeParts('a&amp;b')).toEqual([
[HtmlTokenType.TEXT, 'a&b'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('a&amp;b'))
.toEqual([[HtmlTokenType.TEXT, 'a&b'], [HtmlTokenType.EOF]]);
});
it('should parse hexadecimal entities', () => {
expect(tokenizeAndHumanizeParts('&#x41;&#X41;')).toEqual([
[HtmlTokenType.TEXT, 'AA'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('&#x41;&#X41;'))
.toEqual([[HtmlTokenType.TEXT, 'AA'], [HtmlTokenType.EOF]]);
});
it('should parse decimal entities', () => {
expect(tokenizeAndHumanizeParts('&#65;')).toEqual([
[HtmlTokenType.TEXT, 'A'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('&#65;'))
.toEqual([[HtmlTokenType.TEXT, 'A'], [HtmlTokenType.EOF]]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans('a&amp;b')).toEqual([
[HtmlTokenType.TEXT, 'a&amp;b'], [HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans('a&amp;b'))
.toEqual([[HtmlTokenType.TEXT, 'a&amp;b'], [HtmlTokenType.EOF, '']]);
});
it('should report malformed/unknown entities', () => {
expect(tokenizeAndHumanizeErrors('&tbo;')).toEqual([[
HtmlTokenType.TEXT,
'Unknown entity "tbo" - use the "&#<decimal>;" or "&#x<hex>;" syntax', '0:0'
]]);
expect(tokenizeAndHumanizeErrors('&#asdf;')).toEqual([
[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:3']
]);
expect(tokenizeAndHumanizeErrors('&#xasdf;')).toEqual([
[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:4']
]);
expect(tokenizeAndHumanizeErrors('&tbo;'))
.toEqual([
[
HtmlTokenType.TEXT,
'Unknown entity "tbo" - use the "&#<decimal>;" or "&#x<hex>;" syntax',
'0:0'
]
]);
expect(tokenizeAndHumanizeErrors('&#asdf;'))
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:3']]);
expect(tokenizeAndHumanizeErrors('&#xasdf;'))
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "s"', '0:4']]);
expect(tokenizeAndHumanizeErrors('&#xABC')).toEqual([
[HtmlTokenType.TEXT, 'Unexpected character "EOF"', '0:6']
]);
expect(tokenizeAndHumanizeErrors('&#xABC'))
.toEqual([[HtmlTokenType.TEXT, 'Unexpected character "EOF"', '0:6']]);
});
});
describe('regular text', () => {
it('should parse text', () => {
expect(tokenizeAndHumanizeParts('a')).toEqual([
[HtmlTokenType.TEXT, 'a'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('a'))
.toEqual([[HtmlTokenType.TEXT, 'a'], [HtmlTokenType.EOF]]);
});
it('should handle CR & LF', () => {
expect(tokenizeAndHumanizeParts('t\ne\rs\r\nt')).toEqual([
[HtmlTokenType.TEXT, 't\ne\ns\nt'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('t\ne\rs\r\nt'))
.toEqual([[HtmlTokenType.TEXT, 't\ne\ns\nt'], [HtmlTokenType.EOF]]);
});
it('should parse entities', () => {
expect(tokenizeAndHumanizeParts('a&amp;b')).toEqual([
[HtmlTokenType.TEXT, 'a&b'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('a&amp;b'))
.toEqual([[HtmlTokenType.TEXT, 'a&b'], [HtmlTokenType.EOF]]);
});
it('should parse text starting with "&"', () => {
expect(tokenizeAndHumanizeParts('a && b &')).toEqual([
[HtmlTokenType.TEXT, 'a && b &'], [HtmlTokenType.EOF]
]);
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, '']
]);
expect(tokenizeAndHumanizeSourceSpans('a'))
.toEqual([[HtmlTokenType.TEXT, 'a'], [HtmlTokenType.EOF, '']]);
});
it('should allow "<" in text nodes', () => {
expect(tokenizeAndHumanizeParts('{{ a < b ? c : d }}')).toEqual([
[HtmlTokenType.TEXT, '{{ a < b ? c : d }}'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('{{ a < b ? c : d }}'))
.toEqual([[HtmlTokenType.TEXT, '{{ a < b ? c : d }}'], [HtmlTokenType.EOF]]);
expect(tokenizeAndHumanizeSourceSpans('<p>a<b</p>')).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<p'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.TEXT, 'a<b'],
[HtmlTokenType.TAG_CLOSE, '</p>'],
[HtmlTokenType.EOF, ''],
]);
expect(tokenizeAndHumanizeSourceSpans('<p>a<b</p>'))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<p'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.TEXT, 'a<b'],
[HtmlTokenType.TAG_CLOSE, '</p>'],
[HtmlTokenType.EOF, ''],
]);
expect(tokenizeAndHumanizeParts('< a>')).toEqual([
[HtmlTokenType.TEXT, '< a>'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('< a>'))
.toEqual([[HtmlTokenType.TEXT, '< a>'], [HtmlTokenType.EOF]]);
});
// TODO(vicb): make the lexer aware of Angular expressions
// see https://github.com/angular/angular/issues/5679
it('should parse valid start tag in interpolation', () => {
expect(tokenizeAndHumanizeParts('{{ a <b && c > d }}')).toEqual([
[HtmlTokenType.TEXT, '{{ a '], [HtmlTokenType.TAG_OPEN_START, null, 'b'],
[HtmlTokenType.ATTR_NAME, null, '&&'], [HtmlTokenType.ATTR_NAME, null, 'c'],
[HtmlTokenType.TAG_OPEN_END], [HtmlTokenType.TEXT, ' d }}'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts('{{ a <b && c > d }}'))
.toEqual([
[HtmlTokenType.TEXT, '{{ a '],
[HtmlTokenType.TAG_OPEN_START, null, 'b'],
[HtmlTokenType.ATTR_NAME, null, '&&'],
[HtmlTokenType.ATTR_NAME, null, 'c'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.TEXT, ' d }}'],
[HtmlTokenType.EOF]
]);
});
});
describe('raw text', () => {
it('should parse text', () => {
expect(tokenizeAndHumanizeParts(`<script>t\ne\rs\r\nt</script>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'], [HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<script>t\ne\rs\r\nt</script>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
});
it('should not detect entities', () => {
expect(tokenizeAndHumanizeParts(`<script>&amp;</SCRIPT>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, '&amp;'], [HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<script>&amp;</SCRIPT>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, '&amp;'],
[HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
});
it('should ignore other opening tags', () => {
expect(tokenizeAndHumanizeParts(`<script>a<div></script>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 'a<div>'], [HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<script>a<div></script>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 'a<div>'],
[HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
});
it('should ignore other closing tags', () => {
expect(tokenizeAndHumanizeParts(`<script>a</test></script>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 'a</test>'], [HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<script>a</test></script>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'script'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.RAW_TEXT, 'a</test>'],
[HtmlTokenType.TAG_CLOSE, null, 'script'],
[HtmlTokenType.EOF]
]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans(`<script>a</script>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<script'], [HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.RAW_TEXT, 'a'], [HtmlTokenType.TAG_CLOSE, '</script>'],
[HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans(`<script>a</script>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<script'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.RAW_TEXT, 'a'],
[HtmlTokenType.TAG_CLOSE, '</script>'],
[HtmlTokenType.EOF, '']
]);
});
});
describe('escapable raw text', () => {
it('should parse text', () => {
expect(tokenizeAndHumanizeParts(`<title>t\ne\rs\r\nt</title>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.TAG_CLOSE, null, 'title'], [HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<title>t\ne\rs\r\nt</title>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 't\ne\ns\nt'],
[HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
});
it('should detect entities', () => {
expect(tokenizeAndHumanizeParts(`<title>&amp;</title>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, '&'], [HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<title>&amp;</title>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, '&'],
[HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
});
it('should ignore other opening tags', () => {
expect(tokenizeAndHumanizeParts(`<title>a<div></title>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a<div>'], [HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<title>a<div></title>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a<div>'],
[HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
});
it('should ignore other closing tags', () => {
expect(tokenizeAndHumanizeParts(`<title>a</test></title>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'], [HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a</test>'], [HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
expect(tokenizeAndHumanizeParts(`<title>a</test></title>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, null, 'title'],
[HtmlTokenType.TAG_OPEN_END],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a</test>'],
[HtmlTokenType.TAG_CLOSE, null, 'title'],
[HtmlTokenType.EOF]
]);
});
it('should store the locations', () => {
expect(tokenizeAndHumanizeSourceSpans(`<title>a</title>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<title'], [HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a'], [HtmlTokenType.TAG_CLOSE, '</title>'],
[HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans(`<title>a</title>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<title'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.ESCAPABLE_RAW_TEXT, 'a'],
[HtmlTokenType.TAG_CLOSE, '</title>'],
[HtmlTokenType.EOF, '']
]);
});
});
describe('errors', () => {
it('should include 2 lines of context in message', () => {
let src = '111\n222\n333\nE\n444\n555\n666\n';
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 span = new ParseSourceSpan(location, location);
@ -485,10 +590,14 @@ export function main() {
describe('unicode characters', () => {
it('should support unicode characters', () => {
expect(tokenizeAndHumanizeSourceSpans(`<p>İ</p>`)).toEqual([
[HtmlTokenType.TAG_OPEN_START, '<p'], [HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.TEXT, 'İ'], [HtmlTokenType.TAG_CLOSE, '</p>'], [HtmlTokenType.EOF, '']
]);
expect(tokenizeAndHumanizeSourceSpans(`<p>İ</p>`))
.toEqual([
[HtmlTokenType.TAG_OPEN_START, '<p'],
[HtmlTokenType.TAG_OPEN_END, '>'],
[HtmlTokenType.TEXT, 'İ'],
[HtmlTokenType.TAG_CLOSE, '</p>'],
[HtmlTokenType.EOF, '']
]);
});
});
@ -517,14 +626,15 @@ function humanizeLineColumn(location: ParseLocation): string {
}
function tokenizeAndHumanizeLineColumn(input: string): any[] {
return tokenizeWithoutErrors(input).map(
token => [<any>token.type, humanizeLineColumn(token.sourceSpan.start)]);
return tokenizeWithoutErrors(input)
.map(token => [<any>token.type, humanizeLineColumn(token.sourceSpan.start)]);
}
function tokenizeAndHumanizeErrors(input: string): any[] {
return tokenizeHtml(input, 'someUrl')
.errors.map(
tokenError =>
[<any>tokenError.tokenType, tokenError.msg,
humanizeLineColumn(tokenError.span.start)]);
.errors.map(tokenError => [
<any>tokenError.tokenType,
tokenError.msg,
humanizeLineColumn(tokenError.span.start)
]);
}

View File

@ -1,8 +1,25 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {HtmlTokenType} from 'angular2/src/compiler/html_lexer';
import {HtmlParser, HtmlParseTreeResult, HtmlTreeError} from 'angular2/src/compiler/html_parser';
import {HtmlAst, HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from 'angular2/src/compiler/html_ast';
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
htmlVisitAll
} from 'angular2/src/compiler/html_ast';
import {ParseError, ParseLocation} from 'angular2/src/compiler/parse_util';
import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './html_ast_spec_utils';
@ -18,36 +35,31 @@ export function main() {
});
it('should parse text nodes inside regular elements', () => {
expect(humanizeDom(parser.parse('<div>a</div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlTextAst, 'a', 1]
]);
expect(humanizeDom(parser.parse('<div>a</div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 0], [HtmlTextAst, 'a', 1]]);
});
it('should parse text nodes inside template elements', () => {
expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp'))).toEqual([
[HtmlElementAst, 'template', 0], [HtmlTextAst, 'a', 1]
]);
expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp')))
.toEqual([[HtmlElementAst, 'template', 0], [HtmlTextAst, 'a', 1]]);
});
it('should parse CDATA', () => {
expect(humanizeDom(parser.parse('<![CDATA[text]]>', 'TestComp'))).toEqual([
[HtmlTextAst, 'text', 0]
]);
expect(humanizeDom(parser.parse('<![CDATA[text]]>', 'TestComp')))
.toEqual([[HtmlTextAst, 'text', 0]]);
});
});
describe('elements', () => {
it('should parse root level elements', () => {
expect(humanizeDom(parser.parse('<div></div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0]
]);
expect(humanizeDom(parser.parse('<div></div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 0]]);
});
it('should parse elements inside of regular elements', () => {
expect(humanizeDom(parser.parse('<div><span></span></div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlElementAst, 'span', 1]
]);
expect(humanizeDom(parser.parse('<div><span></span></div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 0], [HtmlElementAst, 'span', 1]]);
});
it('should parse elements inside of template elements', () => {
@ -78,22 +90,24 @@ export function main() {
});
it('should close void elements on text nodes', () => {
expect(humanizeDom(parser.parse('<p>before<br>after</p>', 'TestComp'))).toEqual([
[HtmlElementAst, 'p', 0],
[HtmlTextAst, 'before', 1],
[HtmlElementAst, 'br', 1],
[HtmlTextAst, 'after', 1],
]);
expect(humanizeDom(parser.parse('<p>before<br>after</p>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'p', 0],
[HtmlTextAst, 'before', 1],
[HtmlElementAst, 'br', 1],
[HtmlTextAst, 'after', 1],
]);
});
it('should support optional end tags', () => {
expect(humanizeDom(parser.parse('<div><p>1<p>2</div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0],
[HtmlElementAst, 'p', 1],
[HtmlTextAst, '1', 2],
[HtmlElementAst, 'p', 1],
[HtmlTextAst, '2', 2],
]);
expect(humanizeDom(parser.parse('<div><p>1<p>2</div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 0],
[HtmlElementAst, 'p', 1],
[HtmlTextAst, '1', 2],
[HtmlElementAst, 'p', 1],
[HtmlTextAst, '2', 2],
]);
});
it('should support nested elements', () => {
@ -112,59 +126,63 @@ export function main() {
'<table><thead><tr head></tr></thead><tr noparent></tr><tbody><tr body></tr></tbody><tfoot><tr foot></tr></tfoot></table>',
'TestComp')))
.toEqual([
[HtmlElementAst, 'table', 0], [HtmlElementAst, 'thead', 1],
[HtmlElementAst, 'tr', 2], [HtmlAttrAst, 'head', ''], [HtmlElementAst, 'tbody', 1],
[HtmlElementAst, 'tr', 2], [HtmlAttrAst, 'noparent', ''],
[HtmlElementAst, 'tbody', 1], [HtmlElementAst, 'tr', 2], [HtmlAttrAst, 'body', ''],
[HtmlElementAst, 'tfoot', 1], [HtmlElementAst, 'tr', 2],
[HtmlElementAst, 'table', 0],
[HtmlElementAst, 'thead', 1],
[HtmlElementAst, 'tr', 2],
[HtmlAttrAst, 'head', ''],
[HtmlElementAst, 'tbody', 1],
[HtmlElementAst, 'tr', 2],
[HtmlAttrAst, 'noparent', ''],
[HtmlElementAst, 'tbody', 1],
[HtmlElementAst, 'tr', 2],
[HtmlAttrAst, 'body', ''],
[HtmlElementAst, 'tfoot', 1],
[HtmlElementAst, 'tr', 2],
[HtmlAttrAst, 'foot', '']
]);
});
it('should not add the requiredParent when the parent is a template', () => {
expect(humanizeDom(parser.parse('<template><tr></tr></template>', 'TestComp'))).toEqual([
[HtmlElementAst, 'template', 0],
[HtmlElementAst, 'tr', 1],
]);
expect(humanizeDom(parser.parse('<template><tr></tr></template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 0],
[HtmlElementAst, 'tr', 1],
]);
});
it('should support explicit mamespace', () => {
expect(humanizeDom(parser.parse('<myns:div></myns:div>', 'TestComp'))).toEqual([
[HtmlElementAst, '@myns:div', 0]
]);
expect(humanizeDom(parser.parse('<myns:div></myns:div>', 'TestComp')))
.toEqual([[HtmlElementAst, '@myns:div', 0]]);
});
it('should support implicit mamespace', () => {
expect(humanizeDom(parser.parse('<svg></svg>', 'TestComp'))).toEqual([
[HtmlElementAst, '@svg:svg', 0]
]);
expect(humanizeDom(parser.parse('<svg></svg>', 'TestComp')))
.toEqual([[HtmlElementAst, '@svg:svg', 0]]);
});
it('should propagate the namespace', () => {
expect(humanizeDom(parser.parse('<myns:div><p></p></myns:div>', 'TestComp'))).toEqual([
[HtmlElementAst, '@myns:div', 0], [HtmlElementAst, '@myns:p', 1]
]);
expect(humanizeDom(parser.parse('<myns:div><p></p></myns:div>', 'TestComp')))
.toEqual([[HtmlElementAst, '@myns:div', 0], [HtmlElementAst, '@myns:p', 1]]);
});
it('should match closing tags case sensitive', () => {
let errors = parser.parse('<DiV><P></p></dIv>', 'TestComp').errors;
expect(errors.length).toEqual(2);
expect(humanizeErrors(errors)).toEqual([
['p', 'Unexpected closing tag "p"', '0:8'],
['dIv', 'Unexpected closing tag "dIv"', '0:12'],
]);
expect(humanizeErrors(errors))
.toEqual([
['p', 'Unexpected closing tag "p"', '0:8'],
['dIv', 'Unexpected closing tag "dIv"', '0:12'],
]);
});
it('should support self closing void elements', () => {
expect(humanizeDom(parser.parse('<input />', 'TestComp'))).toEqual([
[HtmlElementAst, 'input', 0]
]);
expect(humanizeDom(parser.parse('<input />', 'TestComp')))
.toEqual([[HtmlElementAst, 'input', 0]]);
});
it('should support self closing foreign elements', () => {
expect(humanizeDom(parser.parse('<math />', 'TestComp'))).toEqual([
[HtmlElementAst, '@math:math', 0]
]);
expect(humanizeDom(parser.parse('<math />', 'TestComp')))
.toEqual([[HtmlElementAst, '@math:math', 0]]);
});
it('should ignore LF immediately after textarea, pre and listing', () => {
@ -186,43 +204,39 @@ export function main() {
describe('attributes', () => {
it('should parse attributes on regular elements case sensitive', () => {
expect(humanizeDom(parser.parse('<div kEy="v" key2=v2></div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0],
[HtmlAttrAst, 'kEy', 'v'],
[HtmlAttrAst, 'key2', 'v2'],
]);
expect(humanizeDom(parser.parse('<div kEy="v" key2=v2></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 0],
[HtmlAttrAst, 'kEy', 'v'],
[HtmlAttrAst, 'key2', 'v2'],
]);
});
it('should parse attributes without values', () => {
expect(humanizeDom(parser.parse('<div k></div>', 'TestComp'))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'k', '']
]);
expect(humanizeDom(parser.parse('<div k></div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'k', '']]);
});
it('should parse attributes on svg elements case sensitive', () => {
expect(humanizeDom(parser.parse('<svg viewBox="0"></svg>', 'TestComp'))).toEqual([
[HtmlElementAst, '@svg:svg', 0], [HtmlAttrAst, 'viewBox', '0']
]);
expect(humanizeDom(parser.parse('<svg viewBox="0"></svg>', 'TestComp')))
.toEqual([[HtmlElementAst, '@svg:svg', 0], [HtmlAttrAst, 'viewBox', '0']]);
});
it('should parse attributes on template elements', () => {
expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp'))).toEqual([
[HtmlElementAst, 'template', 0], [HtmlAttrAst, 'k', 'v']
]);
expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp')))
.toEqual([[HtmlElementAst, 'template', 0], [HtmlAttrAst, 'k', 'v']]);
});
it('should support mamespace', () => {
expect(humanizeDom(parser.parse('<svg:use xlink:href="Port" />', 'TestComp'))).toEqual([
[HtmlElementAst, '@svg:use', 0], [HtmlAttrAst, '@xlink:href', 'Port']
]);
expect(humanizeDom(parser.parse('<svg:use xlink:href="Port" />', 'TestComp')))
.toEqual([[HtmlElementAst, '@svg:use', 0], [HtmlAttrAst, '@xlink:href', 'Port']]);
});
});
describe('comments', () => {
it('should preserve comments', () => {
expect(humanizeDom(parser.parse('<!-- comment --><div></div>', 'TestComp'))).toEqual([
[HtmlCommentAst, 'comment', 0], [HtmlElementAst, 'div', 0]
]);
expect(humanizeDom(parser.parse('<!-- comment --><div></div>', 'TestComp')))
.toEqual([[HtmlCommentAst, 'comment', 0], [HtmlElementAst, 'div', 0]]);
});
});
@ -261,34 +275,34 @@ export function main() {
it('should report closing tag for void elements', () => {
let errors = parser.parse('<input></input>', 'TestComp').errors;
expect(errors.length).toEqual(1);
expect(humanizeErrors(errors)).toEqual([
['input', 'Void elements do not have end tags "input"', '0:7']
]);
expect(humanizeErrors(errors))
.toEqual([['input', 'Void elements do not have end tags "input"', '0:7']]);
});
it('should report self closing html element', () => {
let errors = parser.parse('<p />', 'TestComp').errors;
expect(errors.length).toEqual(1);
expect(humanizeErrors(errors)).toEqual([
['p', 'Only void and foreign elements can be self closed "p"', '0:0']
]);
expect(humanizeErrors(errors))
.toEqual([['p', 'Only void and foreign elements can be self closed "p"', '0:0']]);
});
it('should report self closing custom element', () => {
let errors = parser.parse('<my-cmp />', 'TestComp').errors;
expect(errors.length).toEqual(1);
expect(humanizeErrors(errors)).toEqual([
['my-cmp', 'Only void and foreign elements can be self closed "my-cmp"', '0:0']
]);
expect(humanizeErrors(errors))
.toEqual([
['my-cmp', 'Only void and foreign elements can be self closed "my-cmp"', '0:0']
]);
});
it('should also report lexer errors', () => {
let errors = parser.parse('<!-err--><div></p></div>', 'TestComp').errors;
expect(errors.length).toEqual(2);
expect(humanizeErrors(errors)).toEqual([
[HtmlTokenType.COMMENT_START, 'Unexpected character "e"', '0:3'],
['p', 'Unexpected closing tag "p"', '0:14']
]);
expect(humanizeErrors(errors))
.toEqual([
[HtmlTokenType.COMMENT_START, 'Unexpected character "e"', '0:3'],
['p', 'Unexpected closing tag "p"', '0:14']
]);
});
});
});

View File

@ -1,6 +1,26 @@
import {TestComponentBuilder, AsyncTestCompleter, ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, beforeEachProviders, inject} from 'angular2/testing_internal';
import {
TestComponentBuilder,
AsyncTestCompleter,
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
beforeEachProviders,
inject
} from 'angular2/testing_internal';
import {HtmlAst, HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, htmlVisitAll} from 'angular2/src/compiler/html_ast';
import {
HtmlAst,
HtmlAstVisitor,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
htmlVisitAll
} from 'angular2/src/compiler/html_ast';
import {LegacyHtmlAstTransformer} from 'angular2/src/compiler/legacy_template';

View File

@ -1,4 +1,17 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {Component, provide} from 'angular2/core';
import {PromiseWrapper} from 'angular2/src/facade/async';
@ -25,10 +38,11 @@ export function main() {
it('compileInHost should compile the template via TemplateCompiler',
inject([AsyncTestCompleter], (async) => {
compiler.compileInHost(SomeComponent).then((hostViewFactoryRef) => {
expect(hostViewFactoryRef.internalHostViewFactory).toBe(someHostViewFactory);
async.done();
});
compiler.compileInHost(SomeComponent)
.then((hostViewFactoryRef) => {
expect(hostViewFactoryRef.internalHostViewFactory).toBe(someHostViewFactory);
async.done();
});
}));
it('should clear the cache', () => {

View File

@ -1,5 +1,5 @@
import {Component} from 'angular2/core';
@Component({styles: <any>('foo'), template: ''})
@Component({styles:<any>('foo'), template: ''})
export class MalformedStylesComponent {
}

View File

@ -1,9 +1,37 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {stringify} from 'angular2/src/facade/lang';
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/linker/interfaces';
import {Component, Directive, ViewEncapsulation, ChangeDetectionStrategy, OnChanges, OnInit, DoCheck, OnDestroy, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, SimpleChange, provide} from 'angular2/core';
import {
Component,
Directive,
ViewEncapsulation,
ChangeDetectionStrategy,
OnChanges,
OnInit,
DoCheck,
OnDestroy,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
SimpleChange,
provide
} from 'angular2/core';
import {TEST_PROVIDERS} from './test_bindings';
import {MODULE_SUFFIX} from 'angular2/src/compiler/util';
@ -65,7 +93,7 @@ export function main() {
.toContain(resolver.getDirectiveMetadata(SomeDirective));
}));
describe('platform directives', () => {
describe("platform directives", () => {
beforeEachProviders(
() => [provide(PLATFORM_DIRECTIVES, {useValue: [ADirective], multi: true})]);

View File

@ -1,4 +1,14 @@
import {beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, it, xit} from 'angular2/testing_internal';
import {
beforeEach,
ddescribe,
xdescribe,
describe,
expect,
iit,
inject,
it,
xit
} from 'angular2/testing_internal';
import {IS_DART} from 'angular2/src/facade/lang';
import {DomElementSchemaRegistry} from 'angular2/src/compiler/schema/dom_element_schema_registry';

View File

@ -2,9 +2,8 @@ import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema
import {isPresent} from 'angular2/src/facade/lang';
export class MockSchemaRegistry implements ElementSchemaRegistry {
constructor(
public existingProperties: {[key: string]: boolean},
public attrPropMapping: {[key: string]: string}) {}
constructor(public existingProperties: {[key: string]: boolean},
public attrPropMapping: {[key: string]: string}) {}
hasProperty(tagName: string, property: string): boolean {
var result = this.existingProperties[property];
return isPresent(result) ? result : true;

View File

@ -72,20 +72,20 @@ export function main() {
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse('[someAttr=someValue][someAttr2]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('[someAttr=someValue][someAttr2]')[0],
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse('[someAttr2][someAttr=someValue]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('[someAttr2][someAttr=someValue]')[0],
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
expect(matcher.match(
CssSelector.parse('[someAttr2=someValue][someAttr]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('[someAttr2=someValue][someAttr]')[0],
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
});
@ -120,20 +120,18 @@ export function main() {
it('should select by element name, class name and attribute name with value', () => {
matcher.addSelectables(s1 = CssSelector.parse('someTag.someClass[someAttr=someValue]'), 1);
expect(matcher.match(
CssSelector.parse('someOtherTag.someOtherClass[someOtherAttr]')[0],
selectableCollector))
expect(matcher.match(CssSelector.parse('someOtherTag.someOtherClass[someOtherAttr]')[0],
selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(
matcher.match(
CssSelector.parse('someTag.someOtherClass[someOtherAttr]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('someTag.someOtherClass[someOtherAttr]')[0],
selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
expect(matcher.match(
CssSelector.parse('someTag.someClass[someOtherAttr]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('someTag.someClass[someOtherAttr]')[0],
selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);
@ -142,9 +140,8 @@ export function main() {
.toEqual(false);
expect(matched).toEqual([]);
expect(
matcher.match(
CssSelector.parse('someTag.someClass[someAttr=someValue]')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('someTag.someClass[someAttr=someValue]')[0],
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
});
@ -205,8 +202,8 @@ export function main() {
matcher.addSelectables(s3 = CssSelector.parse(':not(.someClass)'), 3);
matcher.addSelectables(s4 = CssSelector.parse(':not(.someOtherClass[someAttr])'), 4);
expect(matcher.match(
CssSelector.parse('p[someOtherAttr].someOtherClass')[0], selectableCollector))
expect(matcher.match(CssSelector.parse('p[someOtherAttr].someOtherClass')[0],
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2, s3[0], 3, s4[0], 4]);
});
@ -300,7 +297,7 @@ export function main() {
it('should detect :not without truthy', () => {
var cssSelector = CssSelector.parse(':not([attrname=attrvalue].someclass)')[0];
expect(cssSelector.element).toEqual('*');
expect(cssSelector.element).toEqual("*");
var notSelector = cssSelector.notSelectors[0];
expect(notSelector.attrs).toEqual(['attrname', 'attrvalue']);
@ -310,15 +307,13 @@ export function main() {
});
it('should throw when nested :not', () => {
expect(() => {
CssSelector.parse('sometag:not(:not([attrname=attrvalue].someclass))')[0];
}).toThrowError('Nesting :not is not allowed in a selector');
expect(() => { CssSelector.parse('sometag:not(:not([attrname=attrvalue].someclass))')[0]; })
.toThrowError('Nesting :not is not allowed in a selector');
});
it('should throw when multiple selectors in :not', () => {
expect(() => {
CssSelector.parse('sometag:not(a,b)');
}).toThrowError('Multiple selectors in :not are not supported');
expect(() => { CssSelector.parse('sometag:not(a,b)'); })
.toThrowError('Multiple selectors in :not are not supported');
});
it('should detect lists of selectors', () => {

View File

@ -1,4 +1,14 @@
import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el, normalizeCSS} from 'angular2/testing_internal';
import {
describe,
beforeEach,
it,
expect,
ddescribe,
iit,
SpyObject,
el,
normalizeCSS
} from 'angular2/testing_internal';
import {ShadowCss, processRules, CssRule} from 'angular2/src/compiler/shadow_css';
import {RegExpWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang';
@ -96,7 +106,7 @@ export function main() {
});
it('should support polyfill-next-selector', () => {
var css = s('polyfill-next-selector {content: \'x > y\'} z {}', 'a');
var css = s("polyfill-next-selector {content: 'x > y'} z {}", 'a');
expect(css).toEqual('x[a] > y[a]{}');
css = s('polyfill-next-selector {content: "x > y"} z {}', 'a');
@ -104,7 +114,7 @@ export function main() {
});
it('should support polyfill-unscoped-rule', () => {
var css = s('polyfill-unscoped-rule {content: \'#menu > .bar\';color: blue;}', 'a');
var css = s("polyfill-unscoped-rule {content: '#menu > .bar';color: blue;}", 'a');
expect(StringWrapper.contains(css, '#menu > .bar {;color:blue;}')).toBeTruthy();
css = s('polyfill-unscoped-rule {content: "#menu > .bar";color: blue;}', 'a');
@ -112,16 +122,15 @@ export function main() {
});
it('should support multiple instances polyfill-unscoped-rule', () => {
var css =
s('polyfill-unscoped-rule {content: \'foo\';color: blue;}' +
'polyfill-unscoped-rule {content: \'bar\';color: blue;}',
'a');
var css = s("polyfill-unscoped-rule {content: 'foo';color: blue;}" +
"polyfill-unscoped-rule {content: 'bar';color: blue;}",
'a');
expect(StringWrapper.contains(css, 'foo {;color:blue;}')).toBeTruthy();
expect(StringWrapper.contains(css, 'bar {;color:blue;}')).toBeTruthy();
});
it('should support polyfill-rule', () => {
var css = s('polyfill-rule {content: \':host.foo .bar\';color: blue;}', 'a', 'a-host');
var css = s("polyfill-rule {content: ':host.foo .bar';color: blue;}", 'a', 'a-host');
expect(css).toEqual('[a-host].foo .bar {;color:blue;}');
css = s('polyfill-rule {content: ":host.foo .bar";color:blue;}', 'a', 'a-host');
@ -190,29 +199,26 @@ export function main() {
() => { expect(captureRules('a {b}')).toEqual([new CssRule('a', 'b')]); });
it('should capture css rules with nested rules', () => {
expect(captureRules('a {b {c}} d {e}')).toEqual([
new CssRule('a', 'b {c}'), new CssRule('d', 'e')
]);
expect(captureRules('a {b {c}} d {e}'))
.toEqual([new CssRule('a', 'b {c}'), new CssRule('d', 'e')]);
});
it('should capture multiple rules where some have no body', () => {
expect(captureRules('@import a ; b {c}')).toEqual([
new CssRule('@import a', ''), new CssRule('b', 'c')
]);
expect(captureRules('@import a ; b {c}'))
.toEqual([new CssRule('@import a', ''), new CssRule('b', 'c')]);
});
});
describe('modify rules', () => {
it('should allow to change the selector while preserving whitespaces', () => {
expect(processRules(
'@import a; b {c {d}} e {f}',
(cssRule) => new CssRule(cssRule.selector + '2', cssRule.content)))
expect(processRules('@import a; b {c {d}} e {f}',
(cssRule) => new CssRule(cssRule.selector + '2', cssRule.content)))
.toEqual('@import a2; b2 {c {d}} e2 {f}');
});
it('should allow to change the content', () => {
expect(processRules(
'a {b}', (cssRule) => new CssRule(cssRule.selector, cssRule.content + '2')))
expect(processRules('a {b}',
(cssRule) => new CssRule(cssRule.selector, cssRule.content + '2')))
.toEqual('a {b2}');
});
});

View File

@ -1,4 +1,16 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, TestComponentBuilder} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder
} from 'angular2/testing_internal';
import {SourceModule, moduleRef} from 'angular2/src/compiler/source_module';

View File

@ -1,4 +1,17 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {StaticReflector, StaticReflectorHost} from 'angular2/src/compiler/static_reflector';
@ -21,8 +34,8 @@ export function main() {
let reflector = new StaticReflector(host);
let NgFor = reflector.getStaticType('angular2/src/common/directives/ng_for', 'NgFor');
let ViewContainerRef = reflector.getStaticType(
'angular2/src/core/linker/view_container_ref', 'ViewContainerRef');
let ViewContainerRef = reflector.getStaticType('angular2/src/core/linker/view_container_ref',
'ViewContainerRef');
let TemplateRef =
reflector.getStaticType('angular2/src/core/linker/template_ref', 'TemplateRef');
let IterableDiffers = reflector.getStaticType(
@ -31,9 +44,8 @@ export function main() {
'angular2/src/core/change_detection/change_detector_ref', 'ChangeDetectorRef');
let parameters = reflector.parameters(NgFor);
expect(parameters).toEqual([
ViewContainerRef, TemplateRef, IterableDiffers, ChangeDetectorRef
]);
expect(parameters)
.toEqual([ViewContainerRef, TemplateRef, IterableDiffers, ChangeDetectorRef]);
});
it('should get annotations for HeroDetailComponent', () => {
@ -64,7 +76,7 @@ export function main() {
expect(reflector.simplify('', 1)).toBe(1);
expect(reflector.simplify('', true)).toBe(true);
expect(reflector.simplify('', 'some value')).toBe('some value');
expect(reflector.simplify('', "some value")).toBe("some value");
});
it('should simplify an array into a copy of the array', () => {
@ -84,261 +96,196 @@ export function main() {
it('should simplify &&', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '&&', left: true, right: true})))
.toBe(true);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '&&', left: true, right: false})))
.toBe(false);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '&&', left: false, right: true})))
.toBe(false);
expect(reflector.simplify(
'', ({__symbolic: 'binop', operator: '&&', left: false, right: false})))
.toBe(false);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: true}))).toBe(true);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: false}))).toBe(false);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: true}))).toBe(false);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: false}))).toBe(false);
});
it('should simplify ||', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '||', left: true, right: true})))
.toBe(true);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '||', left: true, right: false})))
.toBe(true);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '||', left: false, right: true})))
.toBe(true);
expect(reflector.simplify(
'', ({__symbolic: 'binop', operator: '||', left: false, right: false})))
.toBe(false);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: true}))).toBe(true);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: false}))).toBe(true);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: true}))).toBe(true);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: false}))).toBe(false);
});
it('should simplify &', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F})))
.toBe(0x22 & 0x0F);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0})))
.toBe(0x22 & 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F}))).toBe(0x22 & 0x0F);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0}))).toBe(0x22 & 0xF0);
});
it('should simplify |', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F})))
.toBe(0x22 | 0x0F);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0})))
.toBe(0x22 | 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
});
it('should simplify ^', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F})))
.toBe(0x22 | 0x0F);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0})))
.toBe(0x22 | 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
});
it('should simplify ==', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '==', left: 0x22, right: 0x22})))
.toBe(0x22 == 0x22);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0})))
.toBe(0x22 == 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0x22}))).toBe(0x22 == 0x22);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0}))).toBe(0x22 == 0xF0);
});
it('should simplify !=', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22})))
.toBe(0x22 != 0x22);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0})))
.toBe(0x22 != 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22}))).toBe(0x22 != 0x22);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0}))).toBe(0x22 != 0xF0);
});
it('should simplify ===', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '===', left: 0x22, right: 0x22})))
.toBe(0x22 === 0x22);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0})))
.toBe(0x22 === 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0x22}))).toBe(0x22 === 0x22);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0}))).toBe(0x22 === 0xF0);
});
it('should simplify !==', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22})))
.toBe(0x22 !== 0x22);
expect(
reflector.simplify('', ({__symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0})))
.toBe(0x22 !== 0xF0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22}))).toBe(0x22 !== 0x22);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0}))).toBe(0x22 !== 0xF0);
});
it('should simplify >', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>', left: 1, right: 1})))
.toBe(1 > 1);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>', left: 1, right: 0})))
.toBe(1 > 0);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>', left: 0, right: 1})))
.toBe(0 > 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 1}))).toBe(1 > 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 0}))).toBe(1 > 0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 0, right: 1}))).toBe(0 > 1);
});
it('should simplify >=', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>=', left: 1, right: 1})))
.toBe(1 >= 1);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>=', left: 1, right: 0})))
.toBe(1 >= 0);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>=', left: 0, right: 1})))
.toBe(0 >= 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 1}))).toBe(1 >= 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 0}))).toBe(1 >= 0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 0, right: 1}))).toBe(0 >= 1);
});
it('should simplify <=', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<=', left: 1, right: 1})))
.toBe(1 <= 1);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<=', left: 1, right: 0})))
.toBe(1 <= 0);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<=', left: 0, right: 1})))
.toBe(0 <= 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 1}))).toBe(1 <= 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 0}))).toBe(1 <= 0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 0, right: 1}))).toBe(0 <= 1);
});
it('should simplify <', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<', left: 1, right: 1})))
.toBe(1 < 1);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<', left: 1, right: 0})))
.toBe(1 < 0);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<', left: 0, right: 1})))
.toBe(0 < 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 1}))).toBe(1 < 1);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 0}))).toBe(1 < 0);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 0, right: 1}))).toBe(0 < 1);
});
it('should simplify <<', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '<<', left: 0x55, right: 2})))
.toBe(0x55 << 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<<', left: 0x55, right: 2}))).toBe(0x55 << 2);
});
it('should simplify >>', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '>>', left: 0x55, right: 2})))
.toBe(0x55 >> 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>>', left: 0x55, right: 2}))).toBe(0x55 >> 2);
});
it('should simplify +', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '+', left: 0x55, right: 2})))
.toBe(0x55 + 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '+', left: 0x55, right: 2}))).toBe(0x55 + 2);
});
it('should simplify -', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '-', left: 0x55, right: 2})))
.toBe(0x55 - 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '-', left: 0x55, right: 2}))).toBe(0x55 - 2);
});
it('should simplify *', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '*', left: 0x55, right: 2})))
.toBe(0x55 * 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '*', left: 0x55, right: 2}))).toBe(0x55 * 2);
});
it('should simplify /', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '/', left: 0x55, right: 2})))
.toBe(0x55 / 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '/', left: 0x55, right: 2}))).toBe(0x55 / 2);
});
it('should simplify %', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'binop', operator: '%', left: 0x55, right: 2})))
.toBe(0x55 % 2);
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '%', left: 0x55, right: 2}))).toBe(0x55 % 2);
});
it('should simplify prefix -', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2);
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2);
});
it('should simplify prefix ~', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2);
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2);
});
it('should simplify prefix !', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'pre', operator: '!', operand: true})))
.toBe(!true);
expect(reflector.simplify('', ({__symbolic: 'pre', operator: '!', operand: false})))
.toBe(!false);
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '!', operand: true}))).toBe(!true);
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '!', operand: false}))).toBe(!false);
});
it('should simpify an array index', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
expect(reflector.simplify('', ({__symbolic: 'index', expression: [1, 2, 3], index: 2})))
expect(reflector.simplify('', ({__symbolic: "index", expression: [1, 2, 3], index: 2})))
.toBe(3);
});
it('should simplify an object index', () => {
let host = new MockReflectorHost();
let reflector = new StaticReflector(host);
let expr = {__symbolic: 'select', expression: {a: 1, b: 2, c: 3}, member: 'b'};
let expr = {__symbolic: "select", expression: {a: 1, b: 2, c: 3}, member: "b"};
expect(reflector.simplify('', expr)).toBe(2);
});
@ -347,8 +294,8 @@ export function main() {
let reflector = new StaticReflector(host);
expect(
reflector.simplify('./cases', ({__symbolic: 'reference', module: './extern', name: 's'})))
.toEqual('s');
reflector.simplify('./cases', ({__symbolic: "reference", module: "./extern", name: "s"})))
.toEqual("s");
});
});
}
@ -356,101 +303,139 @@ export function main() {
class MockReflectorHost implements StaticReflectorHost {
getMetadataFor(moduleId: string): any {
return {
'angular2/src/common/directives/ng_for': {
'__symbolic': 'module',
'module': './ng_for',
'metadata': {
'NgFor': {
'__symbolic': 'class',
'decorators': [{
'__symbolic': 'call',
'expression':
{'__symbolic': 'reference', 'name': 'Directive', 'module': '../../core/metadata'},
'arguments': [{
'selector': '[ngFor][ngForOf]',
'inputs': ['ngForTrackBy', 'ngForOf', 'ngForTemplate']
}]
}],
'members': {
'__ctor__': [{
'__symbolic': 'constructor',
'parameters': [
{
'__symbolic': 'reference',
'module': '../../core/linker/view_container_ref',
'name': 'ViewContainerRef'
},
{
'__symbolic': 'reference',
'module': '../../core/linker/template_ref',
'name': 'TemplateRef'
},
{
'__symbolic': 'reference',
'module': '../../core/change_detection/differs/iterable_differs',
'name': 'IterableDiffers'
},
{
'__symbolic': 'reference',
'module': '../../core/change_detection/change_detector_ref',
'name': 'ChangeDetectorRef'
}
]
}]
}
}
}
},
'angular2/src/core/linker/view_container_ref': {
'module': './view_container_ref',
'metadata': {'ViewContainerRef': {'__symbolic': 'class'}}
},
'angular2/src/core/linker/template_ref':
{'module': './template_ref', 'metadata': {'TemplateRef': {'__symbolic': 'class'}}},
'angular2/src/core/change_detection/differs/iterable_differs': {
'module': './iterable_differs',
'metadata': {'IterableDiffers': {'__symbolic': 'class'}}
},
'angular2/src/core/change_detection/change_detector_ref': {
'module': './change_detector_ref',
'metadata': {'ChangeDetectorRef': {'__symbolic': 'class'}}
},
'./app/hero-detail.component': {
'__symbolic': 'module',
'module': './hero-detail.component',
'metadata': {
'HeroDetailComponent': {
'__symbolic': 'class',
'decorators': [{
'__symbolic': 'call',
'expression': {
'__symbolic': 'reference',
'name': 'Component',
'module': 'angular2/src/core/metadata'
'angular2/src/common/directives/ng_for':
{
"__symbolic": "module",
"module": "./ng_for",
"metadata":
{
"NgFor":
{
"__symbolic": "class",
"decorators":
[
{
"__symbolic": "call",
"expression": {
"__symbolic": "reference",
"name": "Directive",
"module": "../../core/metadata"
},
"arguments":
[
{
"selector": "[ngFor][ngForOf]",
"inputs": ["ngForTrackBy", "ngForOf", "ngForTemplate"]
}
]
}
],
"members":
{
"__ctor__": [
{
"__symbolic": "constructor",
"parameters":
[
{
"__symbolic": "reference",
"module": "../../core/linker/view_container_ref",
"name": "ViewContainerRef"
},
{
"__symbolic": "reference",
"module": "../../core/linker/template_ref",
"name": "TemplateRef"
},
{
"__symbolic": "reference",
"module":
"../../core/change_detection/differs/iterable_differs",
"name": "IterableDiffers"
},
{
"__symbolic": "reference",
"module":
"../../core/change_detection/change_detector_ref",
"name": "ChangeDetectorRef"
}
]
}
]
}
}
}
},
'angular2/src/core/linker/view_container_ref':
{
"module": "./view_container_ref",
"metadata": {"ViewContainerRef": {"__symbolic": "class"}}
},
'arguments': [{
'selector': 'my-hero-detail',
'template':
'\n <div *ngIf="hero">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]="hero.name" placeholder="name"/>\n </div>\n </div>\n'
}]
}],
'members': {
'hero': [{
'__symbolic': 'property',
'decorators': [{
'__symbolic': 'call',
'expression': {
'__symbolic': 'reference',
'name': 'Input',
'module': 'angular2/src/core/metadata'
}
}]
}]
}
}
}
},
'./extern': {'__symbolic': 'module', module: './extern', metadata: {s: 's'}}
}[moduleId];
'angular2/src/core/linker/template_ref':
{"module": "./template_ref", "metadata": {"TemplateRef": {"__symbolic": "class"}}},
'angular2/src/core/change_detection/differs/iterable_differs':
{
"module": "./iterable_differs",
"metadata": {"IterableDiffers": {"__symbolic": "class"}}
},
'angular2/src/core/change_detection/change_detector_ref':
{
"module": "./change_detector_ref",
"metadata": {"ChangeDetectorRef": {"__symbolic": "class"}}
},
'./app/hero-detail.component':
{
"__symbolic": "module",
"module": "./hero-detail.component",
"metadata":
{
"HeroDetailComponent":
{
"__symbolic": "class",
"decorators":
[
{
"__symbolic": "call",
"expression": {
"__symbolic": "reference",
"name": "Component",
"module": "angular2/src/core/metadata"
},
"arguments": [
{
"selector": "my-hero-detail",
"template": "\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n"
}
]
}
],
"members":
{
"hero": [
{
"__symbolic": "property",
"decorators":
[
{
"__symbolic": "call",
"expression":
{
"__symbolic": "reference",
"name": "Input",
"module": "angular2/src/core/metadata"
}
}
]
}
]
}
}
}
},
'./extern': {
"__symbolic": "module", module: './extern', metadata: { s: "s" }
}
}
[moduleId];
}
}

View File

@ -1,14 +1,38 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {provide} from 'angular2/src/core/di';
import {SpyXHR} from './spies';
import {XHR} from 'angular2/src/compiler/xhr';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {CONST_EXPR, isPresent, isBlank, StringWrapper, isArray, IS_DART} from 'angular2/src/facade/lang';
import {
CONST_EXPR,
isPresent,
isBlank,
StringWrapper,
isArray,
IS_DART
} from 'angular2/src/facade/lang';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {evalModule} from './eval_module';
import {StyleCompiler} from 'angular2/src/compiler/style_compiler';
import {CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from 'angular2/src/compiler/directive_metadata';
import {
CompileDirectiveMetadata,
CompileTemplateMetadata,
CompileTypeMetadata
} from 'angular2/src/compiler/directive_metadata';
import {SourceExpression, SourceModule} from 'angular2/src/compiler/source_module';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import {TEST_PROVIDERS} from './test_bindings';
@ -52,8 +76,8 @@ export function main() {
`a {color: green}@import ${IMPORT_REL_STYLESHEET_URL};`;
});
function compile(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation):
Promise<string[]> {
function compile(styles: string[], styleAbsUrls: string[],
encapsulation: ViewEncapsulation): Promise<string[]> {
// Note: Can't use MockXHR as the xhr is called recursively,
// so we can't trigger flush.
xhr.spy('get').andCallFake((url) => {
@ -72,10 +96,11 @@ export function main() {
var encapsulation = ViewEncapsulation.None;
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation).then(styles => {
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
async.done();
});
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation)
.then(styles => {
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
async.done();
});
}));
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
@ -89,8 +114,8 @@ export function main() {
it('should allow to import rules transitively', inject([AsyncTestCompleter], (async) => {
compile(['div {color: red}'], [IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT], encapsulation)
.then(styles => {
expect(styles).toEqual(
['div {color: red}', ['a {color: green}', ['span {color: blue}']]]);
expect(styles)
.toEqual(['div {color: red}', ['a {color: green}', ['span {color: blue}']]]);
async.done();
});
}));
@ -122,8 +147,8 @@ export function main() {
}));
it('should allow to import rules transitively', inject([AsyncTestCompleter], (async) => {
compile(
['div {\ncolor: red;\n}'], [IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT], encapsulation)
compile(['div {\ncolor: red;\n}'], [IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT],
encapsulation)
.then(styles => {
compareStyles(styles, [
'div[_ngcontent-%COMP%] {\ncolor: red;\n}',
@ -138,11 +163,10 @@ export function main() {
});
it('should cache stylesheets for parallel requests', inject([AsyncTestCompleter], (async) => {
PromiseWrapper
.all([
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None),
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
])
PromiseWrapper.all([
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None),
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
])
.then((styleArrays) => {
expect(styleArrays[0]).toEqual([['span {color: blue}']]);
expect(styleArrays[1]).toEqual([['span {color: blue}']]);
@ -152,16 +176,17 @@ export function main() {
}));
it('should cache stylesheets for serial requests', inject([AsyncTestCompleter], (async) => {
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None).then((styles0) => {
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL] = 'span {color: black}';
return compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
.then((styles1) => {
expect(styles0).toEqual([['span {color: blue}']]);
expect(styles1).toEqual([['span {color: blue}']]);
expect(xhrCount).toBe(1);
async.done();
});
});
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
.then((styles0) => {
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL] = 'span {color: black}';
return compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
.then((styles1) => {
expect(styles0).toEqual([['span {color: blue}']]);
expect(styles1).toEqual([['span {color: blue}']]);
expect(xhrCount).toBe(1);
async.done();
});
});
}));
it('should allow to clear the cache', inject([AsyncTestCompleter], (async) => {
@ -180,8 +205,8 @@ export function main() {
});
describe('compileComponentCodeGen', () => {
function compile(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation):
Promise<string[]> {
function compile(styles: string[], styleAbsUrls: string[],
encapsulation: ViewEncapsulation): Promise<string[]> {
var sourceExpression = compiler.compileComponentCodeGen(new CompileTemplateMetadata(
{styles: styles, styleUrls: styleAbsUrls, encapsulation: encapsulation}));
var sourceWithImports = testableExpression(sourceExpression).getSourceWithImports();
@ -192,18 +217,20 @@ export function main() {
var encapsulation = ViewEncapsulation.None;
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation).then(styles => {
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
async.done();
});
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation)
.then(styles => {
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
async.done();
});
}));
it('should compile css rules with newlines and quotes',
inject([AsyncTestCompleter], (async) => {
compile(['div\n{"color": \'red\'}'], [], encapsulation).then(styles => {
expect(styles).toEqual(['div\n{"color": \'red\'}']);
async.done();
});
compile(['div\n{"color": \'red\'}'], [], encapsulation)
.then(styles => {
expect(styles).toEqual(['div\n{"color": \'red\'}']);
async.done();
});
}));
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
@ -252,12 +279,13 @@ export function main() {
}
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
compile('div {color: red;}').then(stylesAndShimStyles => {
var expected = [['div {color: red;}'], ['div[_ngcontent-%COMP%] {color: red;}']];
compareStyles(stylesAndShimStyles[0], expected[0]);
compareStyles(stylesAndShimStyles[1], expected[1]);
async.done();
});
compile('div {color: red;}')
.then(stylesAndShimStyles => {
var expected = [['div {color: red;}'], ['div[_ngcontent-%COMP%] {color: red;}']];
compareStyles(stylesAndShimStyles[0], expected[0]);
compareStyles(stylesAndShimStyles[1], expected[1]);
async.done();
});
}));
it('should allow to import rules with relative paths',
@ -296,7 +324,7 @@ function testableModule(sourceModule: SourceModule): SourceModule {
}
// Needed for Android browsers which add an extra space at the end of some lines
function compareStyles(styles: Array<string|any[]>, expectedStyles: Array<string|any[]>) {
function compareStyles(styles: Array<string | any[]>, expectedStyles: Array<string | any[]>) {
expect(styles.length).toEqual(expectedStyles.length);
for (var i = 0; i < styles.length; i++) {
var style = styles[i];

View File

@ -38,9 +38,8 @@ export function main() {
`;
var styleWithImports = extractStyleUrls(urlResolver, 'http://ng.io', css);
expect(styleWithImports.style.trim()).toEqual('');
expect(styleWithImports.styleUrls).toEqual([
'http://ng.io/3.css', 'http://ng.io/4.css', 'http://ng.io/5.css'
]);
expect(styleWithImports.styleUrls)
.toEqual(['http://ng.io/3.css', 'http://ng.io/4.css', 'http://ng.io/5.css']);
});
it('should extract "@import urls and keep rules in the same line', () => {
@ -57,9 +56,8 @@ export function main() {
`;
var styleWithImports = extractStyleUrls(urlResolver, 'http://ng.io', css);
expect(styleWithImports.style.trim()).toEqual('');
expect(styleWithImports.styleUrls).toEqual([
'http://ng.io/print1.css', 'http://ng.io/print2.css'
]);
expect(styleWithImports.styleUrls)
.toEqual(['http://ng.io/print1.css', 'http://ng.io/print2.css']);
});
it('should leave absolute non-package @import urls intact', () => {

View File

@ -1,10 +1,31 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {Type, isPresent, isBlank, stringify, isString, IS_DART} from 'angular2/src/facade/lang';
import {MapWrapper, SetWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {
MapWrapper,
SetWrapper,
ListWrapper,
StringMapWrapper
} from 'angular2/src/facade/collection';
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
import {TemplateCompiler, NormalizedComponentWithViewDirectives} from 'angular2/src/compiler/template_compiler';
import {
TemplateCompiler,
NormalizedComponentWithViewDirectives
} from 'angular2/src/compiler/template_compiler';
import {CompileDirectiveMetadata} from 'angular2/src/compiler/directive_metadata';
import {evalModule} from './eval_module';
import {SourceModule, moduleRef} from 'angular2/src/compiler/source_module';
@ -19,7 +40,12 @@ import {Locals, ChangeDetectorGenConfig} from 'angular2/src/core/change_detectio
import {Component, Directive, provide, RenderComponentType} from 'angular2/core';
import {TEST_PROVIDERS} from './test_bindings';
import {codeGenValueFn, codeGenFnHeader, codeGenExportVariable, MODULE_SUFFIX} from 'angular2/src/compiler/util';
import {
codeGenValueFn,
codeGenFnHeader,
codeGenExportVariable,
MODULE_SUFFIX
} from 'angular2/src/compiler/util';
import {PipeTransform, WrappedValue, Injectable, Pipe} from 'angular2/core';
@ -42,11 +68,11 @@ export function main() {
var runtimeMetadataResolver: RuntimeMetadataResolver;
beforeEachProviders(() => TEST_PROVIDERS);
beforeEach(inject(
[TemplateCompiler, RuntimeMetadataResolver], (_compiler, _runtimeMetadataResolver) => {
compiler = _compiler;
runtimeMetadataResolver = _runtimeMetadataResolver;
}));
beforeEach(inject([TemplateCompiler, RuntimeMetadataResolver],
(_compiler, _runtimeMetadataResolver) => {
compiler = _compiler;
runtimeMetadataResolver = _runtimeMetadataResolver;
}));
describe('compile templates', () => {
@ -62,96 +88,100 @@ export function main() {
}));
it('should compile host components', inject([AsyncTestCompleter], (async) => {
compile([CompWithBindingsAndStylesAndPipes]).then((humanizedView) => {
expect(humanizedView['styles']).toEqual([]);
expect(humanizedView['elements']).toEqual(['<comp-a>']);
expect(humanizedView['pipes']).toEqual({});
expect(humanizedView['cd']).toEqual(['prop(title)=someHostValue']);
async.done();
});
compile([CompWithBindingsAndStylesAndPipes])
.then((humanizedView) => {
expect(humanizedView['styles']).toEqual([]);
expect(humanizedView['elements']).toEqual(['<comp-a>']);
expect(humanizedView['pipes']).toEqual({});
expect(humanizedView['cd']).toEqual(['prop(title)=someHostValue']);
async.done();
});
}));
it('should compile nested components', inject([AsyncTestCompleter], (async) => {
compile([CompWithBindingsAndStylesAndPipes]).then((humanizedView) => {
var componentView = humanizedView['componentViews'][0];
expect(componentView['styles']).toEqual(['div {color: red}']);
expect(componentView['elements']).toEqual(['<a>']);
expect(componentView['pipes']).toEqual({'uppercase': stringify(UpperCasePipe)});
expect(componentView['cd']).toEqual(['prop(href)=SOMECTXVALUE']);
compile([CompWithBindingsAndStylesAndPipes])
.then((humanizedView) => {
var componentView = humanizedView['componentViews'][0];
expect(componentView['styles']).toEqual(['div {color: red}']);
expect(componentView['elements']).toEqual(['<a>']);
expect(componentView['pipes']).toEqual({'uppercase': stringify(UpperCasePipe)});
expect(componentView['cd']).toEqual(['prop(href)=SOMECTXVALUE']);
async.done();
});
async.done();
});
}));
it('should compile components at various nesting levels',
inject([AsyncTestCompleter], (async) => {
compile([CompWith2NestedComps, Comp1, Comp2]).then((humanizedView) => {
expect(humanizedView['elements']).toEqual(['<comp-with-2nested>']);
expect(humanizedView['componentViews'][0]['elements']).toEqual([
'<comp1>', '<comp2>'
]);
expect(humanizedView['componentViews'][0]['componentViews'][0]['elements']).toEqual([
'<a>', '<comp2>'
]);
expect(humanizedView['componentViews'][0]['componentViews'][1]['elements']).toEqual([
'<b>'
]);
compile([CompWith2NestedComps, Comp1, Comp2])
.then((humanizedView) => {
expect(humanizedView['elements']).toEqual(['<comp-with-2nested>']);
expect(humanizedView['componentViews'][0]['elements'])
.toEqual(['<comp1>', '<comp2>']);
expect(humanizedView['componentViews'][0]['componentViews'][0]['elements'])
.toEqual(['<a>', '<comp2>']);
expect(humanizedView['componentViews'][0]['componentViews'][1]['elements'])
.toEqual(['<b>']);
async.done();
});
async.done();
});
}));
it('should compile recursive components', inject([AsyncTestCompleter], (async) => {
compile([TreeComp]).then((humanizedView) => {
expect(humanizedView['elements']).toEqual(['<tree>']);
expect(humanizedView['componentViews'][0]['embeddedViews'][0]['elements']).toEqual([
'<tree>'
]);
expect(humanizedView['componentViews'][0]['embeddedViews'][0]['componentViews'][0]
['embeddedViews'][0]['elements'])
.toEqual(['<tree>']);
compile([TreeComp])
.then((humanizedView) => {
expect(humanizedView['elements']).toEqual(['<tree>']);
expect(humanizedView['componentViews'][0]['embeddedViews'][0]['elements'])
.toEqual(['<tree>']);
expect(humanizedView['componentViews'][0]['embeddedViews'][0]['componentViews']
[0]['embeddedViews'][0]['elements'])
.toEqual(['<tree>']);
async.done();
});
async.done();
});
}));
it('should compile embedded templates', inject([AsyncTestCompleter], (async) => {
compile([CompWithEmbeddedTemplate]).then((humanizedView) => {
var embeddedView = humanizedView['componentViews'][0]['embeddedViews'][0];
expect(embeddedView['elements']).toEqual(['<a>']);
expect(embeddedView['cd']).toEqual(['prop(href)=someEmbeddedValue']);
compile([CompWithEmbeddedTemplate])
.then((humanizedView) => {
var embeddedView = humanizedView['componentViews'][0]['embeddedViews'][0];
expect(embeddedView['elements']).toEqual(['<a>']);
expect(embeddedView['cd']).toEqual(['prop(href)=someEmbeddedValue']);
async.done();
});
async.done();
});
}));
it('should dedup directives', inject([AsyncTestCompleter], (async) => {
compile([CompWithDupDirectives, TreeComp]).then((humanizedView) => {
expect(humanizedView['componentViews'][0]['componentViews'].length).toBe(1);
async.done();
compile([CompWithDupDirectives, TreeComp])
.then((humanizedView) => {
expect(humanizedView['componentViews'][0]['componentViews'].length).toBe(1);
async.done();
});
});
}));
}
describe('compileHostComponentRuntime', () => {
function compile(components: Type[]): Promise<any[]> {
return compiler.compileHostComponentRuntime(components[0])
.then(
(compiledHostTemplate) => humanizeViewFactory(compiledHostTemplate.viewFactory));
.then((compiledHostTemplate) =>
humanizeViewFactory(compiledHostTemplate.viewFactory));
}
describe('no jit', () => {
beforeEachProviders(() => [provide(ChangeDetectorGenConfig, {
useValue: new ChangeDetectorGenConfig(true, false, false)
})]);
beforeEachProviders(() => [
provide(ChangeDetectorGenConfig,
{useValue: new ChangeDetectorGenConfig(true, false, false)})
]);
runTests(compile);
});
describe('jit', () => {
beforeEachProviders(() => [provide(ChangeDetectorGenConfig, {
useValue: new ChangeDetectorGenConfig(true, false, true)
})]);
beforeEachProviders(() => [
provide(ChangeDetectorGenConfig,
{useValue: new ChangeDetectorGenConfig(true, false, true)})
]);
runTests(compile);
});
@ -173,13 +203,15 @@ export function main() {
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
// Expecting only one xhr...
xhr.expect('package:angular2/test/compiler/compUrl.html', '<a>');
compile([CompWithTemplateUrl]).then((humanizedView0) => {
return compile([CompWithTemplateUrl]).then((humanizedView1) => {
expect(humanizedView0['componentViews'][0]['elements']).toEqual(['<a>']);
expect(humanizedView1['componentViews'][0]['elements']).toEqual(['<a>']);
async.done();
});
});
compile([CompWithTemplateUrl])
.then((humanizedView0) => {
return compile([CompWithTemplateUrl])
.then((humanizedView1) => {
expect(humanizedView0['componentViews'][0]['elements']).toEqual(['<a>']);
expect(humanizedView1['componentViews'][0]['elements']).toEqual(['<a>']);
async.done();
});
});
xhr.flush();
}));
@ -203,20 +235,19 @@ export function main() {
});
describe('compileTemplatesCodeGen', () => {
function normalizeComponent(component: Type):
Promise<NormalizedComponentWithViewDirectives> {
function normalizeComponent(
component: Type): Promise<NormalizedComponentWithViewDirectives> {
var compAndViewDirMetas =
[runtimeMetadataResolver.getDirectiveMetadata(component)].concat(
runtimeMetadataResolver.getViewDirectivesMetadata(component));
var upperCasePipeMeta = runtimeMetadataResolver.getPipeMetadata(UpperCasePipe);
upperCasePipeMeta.type.moduleUrl = `package:${THIS_MODULE_ID}${MODULE_SUFFIX}`;
return PromiseWrapper
.all(compAndViewDirMetas.map(meta => compiler.normalizeDirectiveMetadata(meta)))
.then(
(normalizedCompAndViewDirMetas: CompileDirectiveMetadata[]) =>
new NormalizedComponentWithViewDirectives(
normalizedCompAndViewDirMetas[0], normalizedCompAndViewDirMetas.slice(1),
[upperCasePipeMeta]));
return PromiseWrapper.all(compAndViewDirMetas.map(
meta => compiler.normalizeDirectiveMetadata(meta)))
.then((normalizedCompAndViewDirMetas: CompileDirectiveMetadata[]) =>
new NormalizedComponentWithViewDirectives(
normalizedCompAndViewDirMetas[0],
normalizedCompAndViewDirMetas.slice(1), [upperCasePipeMeta]));
}
function compile(components: Type[]): Promise<any[]> {
@ -224,8 +255,8 @@ export function main() {
.then((normalizedCompWithViewDirMetas: NormalizedComponentWithViewDirectives[]) => {
var sourceModule = compiler.compileTemplatesCodeGen(normalizedCompWithViewDirMetas);
var sourceWithImports =
testableTemplateModule(
sourceModule, normalizedCompWithViewDirMetas[0].component)
testableTemplateModule(sourceModule,
normalizedCompWithViewDirMetas[0].component)
.getSourceWithImports();
return evalModule(sourceWithImports.source, sourceWithImports.imports, null);
});
@ -249,9 +280,8 @@ export function main() {
it('should normalize the template',
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
xhr.expect('package:angular2/test/compiler/compUrl.html', 'loadedTemplate');
compiler
.normalizeDirectiveMetadata(
runtimeMetadataResolver.getDirectiveMetadata(CompWithTemplateUrl))
compiler.normalizeDirectiveMetadata(
runtimeMetadataResolver.getDirectiveMetadata(CompWithTemplateUrl))
.then((meta: CompileDirectiveMetadata) => {
expect(meta.template.template).toEqual('loadedTemplate');
async.done();
@ -390,8 +420,8 @@ export class Comp1 {
export class CompWith2NestedComps {
}
function testableTemplateModule(
sourceModule: SourceModule, normComp: CompileDirectiveMetadata): SourceModule {
function testableTemplateModule(sourceModule: SourceModule,
normComp: CompileDirectiveMetadata): SourceModule {
var testableSource = `
${sourceModule.sourceWithModuleRefs}
${codeGenFnHeader(['_'], '_run')}{
@ -455,11 +485,11 @@ export function humanizeViewFactory(
}
var viewManager = new SpyAppViewManager();
viewManager.spy('createRenderComponentType')
.andCallFake((encapsulation: ViewEncapsulation, styles: Array<string|any[]>) => {
.andCallFake((encapsulation: ViewEncapsulation, styles: Array<string | any[]>) => {
return new RenderComponentType('someId', encapsulation, styles);
});
var view: AppView = viewFactory(
new RecordingRenderer([]), viewManager, containerAppElement, [], null, null, null);
var view: AppView = viewFactory(new RecordingRenderer([]), viewManager, containerAppElement, [],
null, null, null);
return humanizeView(view, cachedResults);
}
@ -471,11 +501,9 @@ class RecordingRenderer extends SpyRenderer {
super();
this.spy('renderComponent')
.andCallFake((componentProto) => new RecordingRenderer(componentProto.styles));
this.spy('setElementProperty').andCallFake((el, prop, value) => {
this.props.push(`prop(${prop})=${value}`);
});
this.spy('createElement').andCallFake((parent, elName) => {
this.elements.push(`<${elName}>`);
});
this.spy('setElementProperty')
.andCallFake((el, prop, value) => { this.props.push(`prop(${prop})=${value}`); });
this.spy('createElement')
.andCallFake((parent, elName) => { this.elements.push(`<${elName}>`); });
}
}

View File

@ -1,6 +1,22 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, TestComponentBuilder, beforeEachProviders} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder,
beforeEachProviders
} from 'angular2/testing_internal';
import {CompileTypeMetadata, CompileTemplateMetadata} from 'angular2/src/compiler/directive_metadata';
import {
CompileTypeMetadata,
CompileTemplateMetadata
} from 'angular2/src/compiler/directive_metadata';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import {TemplateNormalizer} from 'angular2/src/compiler/template_normalizer';
@ -24,133 +40,121 @@ export function main() {
describe('loadTemplate', () => {
describe('inline template', () => {
it('should store the template',
inject(
[AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: 'a',
templateUrl: null,
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl).toEqual('package:some/module/a.js');
async.done();
});
}));
inject([AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: 'a',
templateUrl: null,
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl).toEqual('package:some/module/a.js');
async.done();
});
}));
it('should resolve styles on the annotation against the moduleUrl',
inject(
[AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: '',
templateUrl: null,
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
}));
inject([AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: '',
templateUrl: null,
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
}));
it('should resolve styles in the template against the moduleUrl',
inject(
[AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: '<style>@import test.css</style>',
templateUrl: null,
styles: [],
styleUrls: []
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
}));
inject([AsyncTestCompleter, TemplateNormalizer],
(async, normalizer: TemplateNormalizer) => {
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: '<style>@import test.css</style>',
templateUrl: null,
styles: [],
styleUrls: []
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
}));
});
describe('templateUrl', () => {
it('should load a template from a url that is resolved against moduleUrl',
inject(
[AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect('package:some/module/sometplurl.html', 'a');
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'sometplurl.html',
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl).toEqual('package:some/module/sometplurl.html');
async.done();
});
xhr.flush();
}));
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect('package:some/module/sometplurl.html', 'a');
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'sometplurl.html',
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl)
.toEqual('package:some/module/sometplurl.html');
async.done();
});
xhr.flush();
}));
it('should resolve styles on the annotation against the moduleUrl',
inject(
[AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect('package:some/module/tpl/sometplurl.html', '');
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
xhr.flush();
}));
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect('package:some/module/tpl/sometplurl.html', '');
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: ['test.css']
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
xhr.flush();
}));
it('should resolve styles in the template against the templateUrl',
inject(
[AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect(
'package:some/module/tpl/sometplurl.html', '<style>@import test.css</style>');
normalizer
.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: []
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']);
async.done();
});
xhr.flush();
}));
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
xhr.expect('package:some/module/tpl/sometplurl.html',
'<style>@import test.css</style>');
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: []
}))
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']);
async.done();
});
xhr.flush();
}));
});
it('should throw if no template was specified',
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
expect(
() => normalizer.normalizeTemplate(
dirType,
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []})))
expect(() => normalizer.normalizeTemplate(
dirType, new CompileTemplateMetadata(
{encapsulation: null, styles: [], styleUrls: []})))
.toThrowError('No template specified for component SomeComp');
}));

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,24 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {HtmlParser} from 'angular2/src/compiler/html_parser';
import {preparseElement, PreparsedElementType, PreparsedElement} from 'angular2/src/compiler/template_preparser';
import {
preparseElement,
PreparsedElementType,
PreparsedElement
} from 'angular2/src/compiler/template_preparser';
export function main() {
describe('preparseElement', () => {

View File

@ -1,4 +1,14 @@
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el, inject} from 'angular2/testing_internal';
import {
describe,
it,
expect,
beforeEach,
ddescribe,
iit,
xit,
el,
inject
} from 'angular2/testing_internal';
import {IS_DART} from 'angular2/src/facade/lang';
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
@ -73,47 +83,47 @@ export function main() {
it('should not resolve urls against the baseUrl when the url contains a scheme', () => {
resolver = new UrlResolver('my_packages_dir');
expect(resolver.resolve('base/', 'package:file')).toEqual('my_packages_dir/file');
expect(resolver.resolve('base/', 'http:super_file')).toEqual('http:super_file');
expect(resolver.resolve('base/', './mega_file')).toEqual('base/mega_file');
expect(resolver.resolve("base/", 'package:file')).toEqual('my_packages_dir/file');
expect(resolver.resolve("base/", 'http:super_file')).toEqual('http:super_file');
expect(resolver.resolve("base/", './mega_file')).toEqual('base/mega_file');
});
});
describe('packages', () => {
it('should resolve a url based on the application package', () => {
resolver = new UrlResolver('my_packages_dir');
expect(resolver.resolve(null, 'package:some/dir/file.txt'))
.toEqual('my_packages_dir/some/dir/file.txt');
expect(resolver.resolve(null, 'some/dir/file.txt')).toEqual('some/dir/file.txt');
});
describe('packages',
() => {
it('should resolve a url based on the application package', () => {
resolver = new UrlResolver('my_packages_dir');
expect(resolver.resolve(null, 'package:some/dir/file.txt'))
.toEqual('my_packages_dir/some/dir/file.txt');
expect(resolver.resolve(null, 'some/dir/file.txt')).toEqual('some/dir/file.txt');
});
it('should contain a default value of "/packages" when nothing is provided for DART',
inject([UrlResolver], (resolver: UrlResolver) => {
if (IS_DART) {
expect(resolver.resolve(null, 'package:file')).toEqual('/packages/file');
}
}));
it('should contain a default value of "/packages" when nothing is provided for DART',
inject([UrlResolver], (resolver: UrlResolver) => {
if (IS_DART) {
expect(resolver.resolve(null, 'package:file')).toEqual('/packages/file');
}
}));
it('should contain a default value of "/" when nothing is provided for TS/ESM',
inject([UrlResolver], (resolver: UrlResolver) => {
if (!IS_DART) {
expect(resolver.resolve(null, 'package:file')).toEqual('/file');
}
}));
it('should contain a default value of "/" when nothing is provided for TS/ESM',
inject([UrlResolver], (resolver: UrlResolver) => {
if (!IS_DART) {
expect(resolver.resolve(null, 'package:file')).toEqual('/file');
}
}));
it('should resolve a package value when present within the baseurl', () => {
resolver = new UrlResolver('/my_special_dir');
expect(resolver.resolve('package:some_dir/', 'matias.html'))
.toEqual('/my_special_dir/some_dir/matias.html');
});
})
it('should resolve a package value when present within the baseurl', () => {
resolver = new UrlResolver('/my_special_dir');
expect(resolver.resolve('package:some_dir/', 'matias.html'))
.toEqual('/my_special_dir/some_dir/matias.html');
});
})
describe('corner and error cases', () => {
it('should encode URLs before resolving',
() => {
expect(resolver.resolve('foo/baz', `<p #p>Hello
describe('corner and error cases', () => {
it('should encode URLs before resolving', () => {
expect(resolver.resolve('foo/baz', `<p #p>Hello
</p>`)).toEqual('foo/%3Cp%20#p%3EHello%0A%20%20%20%20%20%20%20%20%3C/p%3E');
});
});
});
});
});
}

View File

@ -1,4 +1,16 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, TestComponentBuilder} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder
} from 'angular2/testing_internal';
import {IS_DART} from 'angular2/src/facade/lang';
import {escapeSingleQuoteString, escapeDoubleQuoteString} from 'angular2/src/compiler/util';

View File

@ -1,4 +1,14 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it,} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
} from 'angular2/testing_internal';
import {MockXHR} from 'angular2/src/compiler/xhr_mock';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {isPresent} from 'angular2/src/facade/lang';