feat(ICU): enable ICU extraction even when when in is not used

BREAKING CHANGES:

"{" is used a a delimiter for ICU messages then it could not be used in text nodes.
"{" should be escaped as "{{ '{' }}"

Before:

    <span>some { valid } text</span>

After:

    <span>some { invalid } text<span> <!-- throw parse error -->
    <span>some {{ '{' }} valid } text</span>
This commit is contained in:
Victor Berchet 2016-06-30 14:59:23 -07:00
parent 402fd934d0
commit 3050ae155c
16 changed files with 281 additions and 252 deletions

View File

@ -6,10 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {BaseException} from '../facade/exceptions';
import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst, HtmlTextAst, htmlVisitAll} from '../html_ast';
import {ParseError} from '../parse_util';
import {I18nError} from './shared';
import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, HtmlExpansionAst, HtmlExpansionCaseAst, HtmlTextAst, htmlVisitAll} from './html_ast';
import {ParseError, ParseSourceSpan} from './parse_util';
// http://cldr.unicode.org/index/cldr-spec/plural-rules
const PLURAL_CASES: string[] = ['zero', 'one', 'two', 'few', 'many', 'other'];
@ -46,6 +44,10 @@ export class ExpansionResult {
constructor(public nodes: HtmlAst[], public expanded: boolean, public errors: ParseError[]) {}
}
export class ExpansionError extends ParseError {
constructor(span: ParseSourceSpan, errorMsg: string) { super(span, errorMsg); }
}
/**
* Expand expansion forms (plural, select) to directives
*
@ -74,14 +76,14 @@ class _Expander implements HtmlAstVisitor {
}
visitExpansionCase(ast: HtmlExpansionCaseAst, context: any): any {
throw new BaseException('Should not be reached');
throw new Error('Should not be reached');
}
}
function _expandPluralForm(ast: HtmlExpansionAst, errors: ParseError[]): HtmlElementAst {
const children = ast.cases.map(c => {
if (PLURAL_CASES.indexOf(c.value) == -1 && !c.value.match(/^=\d+$/)) {
errors.push(new I18nError(
errors.push(new ExpansionError(
c.valueSourceSpan,
`Plural cases should be "=<number>" or one of ${PLURAL_CASES.join(", ")}`));
}

View File

@ -14,7 +14,6 @@ import {HtmlToken, HtmlTokenType, tokenizeHtml} from './html_lexer';
import {ParseError, ParseSourceSpan} from './parse_util';
import {getHtmlTagDefinition, getNsPrefix, mergeNsAndName} from './html_tags';
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './interpolation_config';
import {Parser as ExpressionParser} from './expression_parser/parser';
export class HtmlTreeError extends ParseError {
static create(elementName: string, span: ParseSourceSpan, msg: string): HtmlTreeError {
@ -34,9 +33,9 @@ export class HtmlParser {
sourceContent: string, sourceUrl: string, parseExpansionForms: boolean = false,
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG):
HtmlParseTreeResult {
var tokensAndErrors =
const tokensAndErrors =
tokenizeHtml(sourceContent, sourceUrl, parseExpansionForms, interpolationConfig);
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
const treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
return new HtmlParseTreeResult(
treeAndErrors.rootNodes,
(<ParseError[]>tokensAndErrors.errors).concat(treeAndErrors.errors));
@ -82,7 +81,7 @@ class TreeBuilder {
}
private _advance(): HtmlToken {
var prev = this.peek;
const prev = this.peek;
if (this.index < this.tokens.length - 1) {
// Note: there is always an EOF token at the end
this.index++;
@ -104,17 +103,17 @@ class TreeBuilder {
}
private _consumeComment(token: HtmlToken) {
var text = this._advanceIf(HtmlTokenType.RAW_TEXT);
const text = this._advanceIf(HtmlTokenType.RAW_TEXT);
this._advanceIf(HtmlTokenType.COMMENT_END);
var value = isPresent(text) ? text.parts[0].trim() : null;
const value = isPresent(text) ? text.parts[0].trim() : null;
this._addToParent(new HtmlCommentAst(value, token.sourceSpan));
}
private _consumeExpansion(token: HtmlToken) {
let switchValue = this._advance();
const switchValue = this._advance();
let type = this._advance();
let cases: HtmlExpansionCaseAst[] = [];
const type = this._advance();
const cases: HtmlExpansionCaseAst[] = [];
// read =
while (this.peek.type === HtmlTokenType.EXPANSION_CASE_VALUE) {
@ -131,13 +130,13 @@ class TreeBuilder {
}
this._advance();
let mainSourceSpan = new ParseSourceSpan(token.sourceSpan.start, this.peek.sourceSpan.end);
const mainSourceSpan = new ParseSourceSpan(token.sourceSpan.start, this.peek.sourceSpan.end);
this._addToParent(new HtmlExpansionAst(
switchValue.parts[0], type.parts[0], cases, mainSourceSpan, switchValue.sourceSpan));
}
private _parseExpansionCase(): HtmlExpansionCaseAst {
let value = this._advance();
const value = this._advance();
// read {
if (this.peek.type !== HtmlTokenType.EXPANSION_CASE_EXP_START) {
@ -147,30 +146,30 @@ class TreeBuilder {
}
// read until }
let start = this._advance();
const start = this._advance();
let exp = this._collectExpansionExpTokens(start);
const exp = this._collectExpansionExpTokens(start);
if (isBlank(exp)) return null;
let end = this._advance();
const end = this._advance();
exp.push(new HtmlToken(HtmlTokenType.EOF, [], end.sourceSpan));
// parse everything in between { and }
let parsedExp = new TreeBuilder(exp).build();
const parsedExp = new TreeBuilder(exp).build();
if (parsedExp.errors.length > 0) {
this.errors = this.errors.concat(<HtmlTreeError[]>parsedExp.errors);
return null;
}
let sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end);
let expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end);
const sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end);
const expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end);
return new HtmlExpansionCaseAst(
value.parts[0], parsedExp.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan);
}
private _collectExpansionExpTokens(start: HtmlToken): HtmlToken[] {
let exp: HtmlToken[] = [];
let expansionFormStack = [HtmlTokenType.EXPANSION_CASE_EXP_START];
const exp: HtmlToken[] = [];
const expansionFormStack = [HtmlTokenType.EXPANSION_CASE_EXP_START];
while (true) {
if (this.peek.type === HtmlTokenType.EXPANSION_FORM_START ||
@ -213,7 +212,7 @@ class TreeBuilder {
private _consumeText(token: HtmlToken) {
let text = token.parts[0];
if (text.length > 0 && text[0] == '\n') {
let parent = this._getParentElement();
const parent = this._getParentElement();
if (isPresent(parent) && parent.children.length == 0 &&
getHtmlTagDefinition(parent.name).ignoreFirstLf) {
text = text.substring(1);
@ -227,7 +226,7 @@ class TreeBuilder {
private _closeVoidElement(): void {
if (this.elementStack.length > 0) {
let el = ListWrapper.last(this.elementStack);
const el = ListWrapper.last(this.elementStack);
if (getHtmlTagDefinition(el.name).isVoid) {
this.elementStack.pop();
@ -236,14 +235,14 @@ class TreeBuilder {
}
private _consumeStartTag(startTagToken: HtmlToken) {
var prefix = startTagToken.parts[0];
var name = startTagToken.parts[1];
var attrs: HtmlAttrAst[] = [];
const prefix = startTagToken.parts[0];
const name = startTagToken.parts[1];
const attrs: HtmlAttrAst[] = [];
while (this.peek.type === HtmlTokenType.ATTR_NAME) {
attrs.push(this._consumeAttr(this._advance()));
}
var fullName = getElementFullName(prefix, name, this._getParentElement());
var selfClosing = false;
const fullName = getElementFullName(prefix, name, this._getParentElement());
let selfClosing = false;
// Note: There could have been a tokenizer error
// so that we don't get a token for the end tag...
if (this.peek.type === HtmlTokenType.TAG_OPEN_END_VOID) {
@ -258,9 +257,9 @@ class TreeBuilder {
this._advance();
selfClosing = false;
}
var end = this.peek.sourceSpan.start;
let span = new ParseSourceSpan(startTagToken.sourceSpan.start, end);
var el = new HtmlElementAst(fullName, attrs, [], span, span, null);
const end = this.peek.sourceSpan.start;
const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end);
const el = new HtmlElementAst(fullName, attrs, [], span, span, null);
this._pushElement(el);
if (selfClosing) {
this._popElement(fullName);
@ -270,7 +269,7 @@ class TreeBuilder {
private _pushElement(el: HtmlElementAst) {
if (this.elementStack.length > 0) {
var parentEl = ListWrapper.last(this.elementStack);
const parentEl = ListWrapper.last(this.elementStack);
if (getHtmlTagDefinition(parentEl.name).isClosedByChild(el.name)) {
this.elementStack.pop();
}
@ -280,7 +279,7 @@ class TreeBuilder {
const {parent, container} = this._getParentElementSkippingContainers();
if (isPresent(parent) && tagDef.requireExtraParent(parent.name)) {
var newParent = new HtmlElementAst(
const newParent = new HtmlElementAst(
tagDef.parentToAdd, [], [], el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
this._insertBeforeContainer(parent, container, newParent);
}
@ -290,7 +289,7 @@ class TreeBuilder {
}
private _consumeEndTag(endTagToken: HtmlToken) {
var fullName =
const fullName =
getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getParentElement());
if (this._getParentElement()) {
@ -309,7 +308,7 @@ class TreeBuilder {
private _popElement(fullName: string): boolean {
for (let stackIndex = this.elementStack.length - 1; stackIndex >= 0; stackIndex--) {
let el = this.elementStack[stackIndex];
const el = this.elementStack[stackIndex];
if (el.name == fullName) {
ListWrapper.splice(this.elementStack, stackIndex, this.elementStack.length - stackIndex);
return true;
@ -323,11 +322,11 @@ class TreeBuilder {
}
private _consumeAttr(attrName: HtmlToken): HtmlAttrAst {
var fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
var end = attrName.sourceSpan.end;
var value = '';
const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
let end = attrName.sourceSpan.end;
let value = '';
if (this.peek.type === HtmlTokenType.ATTR_VALUE) {
var valueToken = this._advance();
const valueToken = this._advance();
value = valueToken.parts[0];
end = valueToken.sourceSpan.end;
}
@ -358,7 +357,7 @@ class TreeBuilder {
}
private _addToParent(node: HtmlAst) {
var parent = this._getParentElement();
const parent = this._getParentElement();
if (isPresent(parent)) {
parent.children.push(node);
} else {
@ -381,7 +380,7 @@ class TreeBuilder {
} else {
if (parent) {
// replace the container with the new node in the children
let index = parent.children.indexOf(container);
const index = parent.children.indexOf(container);
parent.children[index] = node;
} else {
this.rootNodes.push(node);

View File

@ -14,14 +14,12 @@ import {HtmlAst, HtmlAstVisitor, HtmlAttrAst, HtmlCommentAst, HtmlElementAst, Ht
import {HtmlParseTreeResult, HtmlParser} from '../html_parser';
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../interpolation_config';
import {ParseError, ParseSourceSpan} from '../parse_util';
import {expandNodes} from './expander';
import {Message, id} from './message';
import {I18N_ATTR, I18N_ATTR_PREFIX, I18nError, Part, dedupePhName, extractPhNameFromInterpolation, messageFromAttribute, messageFromI18nAttribute, partition} from './shared';
const _PLACEHOLDER_ELEMENT = 'ph';
const _NAME_ATTR = 'name';
let _PLACEHOLDER_EXPANDED_REGEXP = /<ph(\s)+name=("(\w)+")><\/ph>/gi;
const _PLACEHOLDER_EXPANDED_REGEXP = /<ph(\s)+name=("(\w)+")><\/ph>/gi;
/**
* Creates an i18n-ed version of the parsed template.
@ -72,9 +70,7 @@ export class I18nHtmlParser implements HtmlParser {
return res;
}
const expanded = expandNodes(res.rootNodes);
const nodes = this._recurse(expanded.nodes);
this.errors.push(...expanded.errors);
const nodes = this._recurse(res.rootNodes);
return this.errors.length > 0 ? new HtmlParseTreeResult([], this.errors) :
new HtmlParseTreeResult(nodes, []);

View File

@ -7,33 +7,26 @@
*/
import {Inject, Injectable, OpaqueToken, Optional, SecurityContext} from '@angular/core';
import {Console, MAX_INTERPOLATION_VALUES} from '../core_private';
import {ListWrapper, StringMapWrapper, SetWrapper,} from '../src/facade/collection';
import {RegExpWrapper, isPresent, StringWrapper, isBlank, isArray} from '../src/facade/lang';
import {RegExpWrapper, isPresent, StringWrapper, isBlank} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from './expression_parser/ast';
import {Parser} from './expression_parser/parser';
import {CompileDirectiveMetadata, CompilePipeMetadata, CompileMetadataWithType, CompileTokenMetadata,} from './compile_metadata';
import {HtmlParser} from './html_parser';
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
import {splitNsName, mergeNsAndName} from './html_tags';
import {ParseSourceSpan, ParseError, ParseErrorLevel} from './parse_util';
import {InterpolationConfig} from './interpolation_config';
import {ElementAst, BoundElementPropertyAst, BoundEventAst, ReferenceAst, TemplateAst, TemplateAstVisitor, templateVisitAll, TextAst, BoundTextAst, EmbeddedTemplateAst, AttrAst, NgContentAst, PropertyBindingType, DirectiveAst, BoundDirectivePropertyAst, ProviderAst, ProviderAstType, VariableAst} from './template_ast';
import {CssSelector, SelectorMatcher} from './selector';
import {ElementSchemaRegistry} from './schema/element_schema_registry';
import {preparseElement, PreparsedElementType} from './template_preparser';
import {isStyleUrlResolvable} from './style_url_resolver';
import {HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, HtmlExpansionAst, HtmlExpansionCaseAst, htmlVisitAll} from './html_ast';
import {splitAtColon} from './util';
import {identifierToken, Identifiers} from './identifiers';
import {expandNodes} from './expander';
import {ProviderElementContext, ProviderViewContext} from './provider_parser';
// Group 1 = "bind-"
@ -113,11 +106,18 @@ export class TemplateParser {
if (component.template) {
interpolationConfig = InterpolationConfig.fromArray(component.template.interpolation);
}
const htmlAstWithErrors =
this._htmlParser.parse(template, templateUrl, false, interpolationConfig);
let htmlAstWithErrors =
this._htmlParser.parse(template, templateUrl, true, interpolationConfig);
const errors: ParseError[] = htmlAstWithErrors.errors;
let result: TemplateAst[];
if (errors.length == 0) {
// Transform ICU messages to angular directives
const expandedHtmlAst = expandNodes(htmlAstWithErrors.rootNodes);
errors.push(...expandedHtmlAst.errors);
htmlAstWithErrors = new HtmlParseTreeResult(expandedHtmlAst.nodes, errors);
}
if (htmlAstWithErrors.rootNodes.length > 0) {
const uniqDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
const uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
@ -137,10 +137,12 @@ export class TemplateParser {
if (errors.length > 0) {
return new TemplateParseResult(result, errors);
}
if (isPresent(this.transforms)) {
this.transforms.forEach(
(transform: TemplateAstVisitor) => { result = templateVisitAll(transform, result); });
}
return new TemplateParseResult(result, errors);
}

View File

@ -6,12 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {HtmlAttrAst, HtmlElementAst, HtmlTextAst} from '@angular/compiler/src/html_ast';
import {HtmlParser} from '@angular/compiler/src/html_parser';
import {ExpansionResult, expandNodes} from '@angular/compiler/src/i18n/expander';
import {ParseError} from '@angular/compiler/src/parse_util';
import {humanizeNodes} from '@angular/compiler/test/html_ast_spec_utils';
import {ddescribe, describe, expect, iit, it} from '@angular/core/testing/testing_internal';
import {ddescribe, describe, expect, iit, it} from '../../core/testing/testing_internal';
import {ExpansionResult, expandNodes} from '../src/expander';
import {HtmlAttrAst, HtmlElementAst, HtmlTextAst} from '../src/html_ast';
import {HtmlParser} from '../src/html_parser';
import {ParseError} from '../src/parse_util';
import {humanizeNodes} from './html_ast_spec_utils';
export function main() {
describe('Expander', () => {

View File

@ -30,8 +30,6 @@ var MOCK_SCHEMA_REGISTRY = [{
useValue: new MockSchemaRegistry({'invalidProp': false}, {'mappedAttr': 'mappedProp'})
}];
let zeConsole = console;
export function main() {
var ngIf: CompileDirectiveMetadata;
var parse:
@ -864,19 +862,18 @@ There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"><
});
it('should report duplicate reference names', () => {
expect(() => parse('<div #a></div><div #a></div>', [])) .toThrowError(
`Template parse errors:
expect(() => parse('<div #a></div><div #a></div>', []))
.toThrowError(`Template parse errors:
Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>"): TestComp@0:19`);
});
it(
'should not throw error when there is same reference name in different templates',
() => {
expect(() => parse('<div #a><template #a><span>OK</span></template></div>', []))
.not.toThrowError();
it('should not throw error when there is same reference name in different templates',
() => {
expect(() => parse('<div #a><template #a><span>OK</span></template></div>', []))
.not.toThrowError();
});
});
it('should assign references with empty value to components', () => {
var dirA = CompileDirectiveMetadata.create({
@ -1506,6 +1503,38 @@ The pipe 'test' could not be found ("[ERROR ->]{{a | test}}"): TestComp@0:0`);
});
});
describe('ICU messages', () => {
it('should expand plural messages', () => {
const shortForm = '{ count, plural, =0 {small} many {big} }';
const expandedForm = '<ng-container [ngPlural]="count">' +
'<template ngPluralCase="=0">small</template>' +
'<template ngPluralCase="many">big</template>' +
'</ng-container>';
expect(humanizeTplAst(parse(shortForm, []))).toEqual(humanizeTplAst(parse(expandedForm, [
])));
});
it('should expand other messages', () => {
const shortForm = '{ sex, gender, =f {foo} other {bar} }';
const expandedForm = '<ng-container [ngSwitch]="sex">' +
'<template ngSwitchCase="=f">foo</template>' +
'<template ngSwitchCase="other">bar</template>' +
'</ng-container>';
expect(humanizeTplAst(parse(shortForm, []))).toEqual(humanizeTplAst(parse(expandedForm, [
])));
});
it('should be possible to escape ICU messages', () => {
const escapedForm = 'escaped {{ "{" }} }';
expect(humanizeTplAst(parse(escapedForm, []))).toEqual([
[BoundTextAst, 'escaped {{ "{" }} }'],
]);
});
});
});
}

View File

@ -58,7 +58,7 @@ export function main() {
]).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('outer { hello }');
expect(el).toHaveText('outer [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('');
async.done();
});
@ -95,9 +95,9 @@ export function main() {
var position = 0;
var flipped = false;
var history = [
['/parent/child', 'root { parent { hello } }', '/super-parent/child'],
['/super-parent/child', 'root { super-parent { hello2 } }', '/parent/child'],
['/parent/child', 'root { parent { hello } }', false]
['/parent/child', 'root [ parent [ hello ] ]', '/super-parent/child'],
['/super-parent/child', 'root [ super-parent [ hello2 ] ]', '/parent/child'],
['/parent/child', 'root [ parent [ hello ] ]', false]
];
router.subscribe((_: any /** TODO #9100 */) => {
@ -147,7 +147,7 @@ export function main() {
var router = fixture.debugElement.componentInstance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(fixture.debugElement.nativeElement)
.toHaveText('root { parent { hello } }');
.toHaveText('root [ parent [ hello ] ]');
expect(fixture.debugElement.componentInstance.location.path())
.toEqual('/parent/child');
async.done();
@ -168,7 +168,7 @@ export function main() {
var router = fixture.debugElement.componentInstance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(fixture.debugElement.nativeElement)
.toHaveText('root { parent { hello } }');
.toHaveText('root [ parent [ hello ] ]');
expect(fixture.debugElement.componentInstance.location.path())
.toEqual('/my/app/parent/child');
async.done();
@ -252,7 +252,7 @@ class Hello2Cmp {
@Component({
selector: 'app-cmp',
template: `outer { <router-outlet></router-outlet> }`,
template: `outer [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([new Route({path: '/', component: HelloCmp})])
@ -288,7 +288,7 @@ class AppWithOutletListeners {
@Component({
selector: 'parent-cmp',
template: `parent { <router-outlet></router-outlet> }`,
template: `parent [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([new Route({path: '/child', component: HelloCmp})])
@ -297,7 +297,7 @@ class ParentCmp {
@Component({
selector: 'super-parent-cmp',
template: `super-parent { <router-outlet></router-outlet> }`,
template: `super-parent [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([new Route({path: '/child', component: Hello2Cmp})])
@ -306,7 +306,7 @@ class SuperParentCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([
@ -340,7 +340,7 @@ class BrokenCmp {
@Component({
selector: 'app-cmp',
template: `outer { <router-outlet></router-outlet> }`,
template: `outer [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([new Route({path: '/cause-error', component: BrokenCmp})])

View File

@ -261,27 +261,27 @@ function asyncRoutesWithSyncChildrenWithoutDefaultRoutes() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigateByUrl('/a/b'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigate(['/Parent', 'Child']))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -289,7 +289,7 @@ function asyncRoutesWithSyncChildrenWithoutDefaultRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
@ -306,18 +306,18 @@ function asyncRoutesWithSyncChildrenWithoutDefaultRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentCmpLoader, name: 'Parent'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer { }');
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('nav to child | outer { inner { hello } }');
.toHaveText('nav to child | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -343,27 +343,27 @@ function asyncRoutesWithSyncChildrenWithDefaultRoutes() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigateByUrl('/a'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigate(['/Parent']))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -371,7 +371,7 @@ function asyncRoutesWithSyncChildrenWithDefaultRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Parent']">link to inner</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})]))
@ -388,19 +388,19 @@ function asyncRoutesWithSyncChildrenWithDefaultRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Parent']">link to inner</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: parentWithDefaultCmpLoader, name: 'Parent'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('link to inner | outer { }');
.toHaveText('link to inner | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('link to inner | outer { inner { hello } }');
.toHaveText('link to inner | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -426,27 +426,27 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigateByUrl('/a/b'))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(rootTC.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigate(['/Parent', 'Child']))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(rootTC.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -454,7 +454,7 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})]))
@ -471,18 +471,18 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithoutDefaultRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncParentCmpLoader, name: 'Parent'})]))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer { }');
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement)
.toHaveText('nav to child | outer { inner { hello } }');
.toHaveText('nav to child | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -508,27 +508,27 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigateByUrl('/a'))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(rootTC.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})]))
.then((_) => rtr.navigate(['/Parent']))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(rootTC.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -536,7 +536,7 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})]))
@ -553,18 +553,18 @@ function asyncRoutesWithAsyncChildrenWithoutParamsWithDefaultRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['Parent']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {rootTC = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/a/...', loader: asyncDefaultParentCmpLoader, name: 'Parent'})]))
.then((_) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer { }');
expect(rootTC.debugElement.nativeElement).toHaveText('nav to child | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
rootTC.detectChanges();
expect(rootTC.debugElement.nativeElement)
.toHaveText('nav to child | outer { inner { hello } }');
.toHaveText('nav to child | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -590,7 +590,7 @@ function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `{ <router-outlet></router-outlet> }`)
compile(tcb, `[ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})]))
@ -598,13 +598,13 @@ function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('{ team angular | user { hello matias } }');
.toHaveText('[ team angular | user [ hello matias ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `{ <router-outlet></router-outlet> }`)
compile(tcb, `[ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})]))
@ -612,7 +612,7 @@ function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('{ team angular | user { hello matias } }');
.toHaveText('[ team angular | user [ hello matias ] ]');
async.done();
});
}));
@ -620,7 +620,7 @@ function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})]))
@ -637,18 +637,18 @@ function asyncRoutesWithAsyncChildrenWithParamsWithoutDefaultRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute(
{path: '/team/:id/...', loader: asyncTeamLoader, name: 'Team'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias { }');
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('nav to matias { team angular | user { hello matias } }');
.toHaveText('nav to matias [ team angular | user [ hello matias ] ]');
expect(location.urlChanges).toEqual(['/team/angular/user/matias']);
async.done();
});

View File

@ -37,7 +37,7 @@ function auxRoutes() {
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -46,7 +46,7 @@ function auxRoutes() {
.then((_) => rtr.navigateByUrl('/(modal)'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('main {} | aux {modal}');
expect(fixture.debugElement.nativeElement).toHaveText('main [] | aux [modal]');
async.done();
});
}));
@ -55,7 +55,7 @@ function auxRoutes() {
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -64,7 +64,7 @@ function auxRoutes() {
.then((_) => rtr.navigate(['/', ['Modal']]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('main {} | aux {modal}');
expect(fixture.debugElement.nativeElement).toHaveText('main [] | aux [modal]');
async.done();
});
}));
@ -72,7 +72,7 @@ function auxRoutes() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`<a [routerLink]="['/', ['Modal']]">open modal</a> | main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -91,7 +91,7 @@ function auxRoutes() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/', ['Modal']]">open modal</a> | <a [routerLink]="['/Hello']">hello</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`<a [routerLink]="['/', ['Modal']]">open modal</a> | <a [routerLink]="['/Hello']">hello</a> | main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -100,7 +100,7 @@ function auxRoutes() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('open modal | hello | main {} | aux {}');
.toHaveText('open modal | hello | main [] | aux []');
var navCount = 0;
@ -109,7 +109,7 @@ function auxRoutes() {
fixture.detectChanges();
if (navCount == 1) {
expect(fixture.debugElement.nativeElement)
.toHaveText('open modal | hello | main {} | aux {modal}');
.toHaveText('open modal | hello | main [] | aux [modal]');
expect(location.urlChanges).toEqual(['/(modal)']);
expect(getHref(getLinkElement(fixture, 0))).toEqual('/(modal)');
expect(getHref(getLinkElement(fixture, 1))).toEqual('/hello(modal)');
@ -118,7 +118,7 @@ function auxRoutes() {
clickOnElement(getLinkElement(fixture, 1));
} else if (navCount == 2) {
expect(fixture.debugElement.nativeElement)
.toHaveText('open modal | hello | main {hello} | aux {modal}');
.toHaveText('open modal | hello | main [hello] | aux [modal]');
expect(location.urlChanges).toEqual(['/(modal)', '/hello(modal)']);
expect(getHref(getLinkElement(fixture, 0))).toEqual('/hello(modal)');
expect(getHref(getLinkElement(fixture, 1))).toEqual('/hello(modal)');
@ -150,7 +150,7 @@ function auxRoutesWithAPrimaryRoute() {
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -159,7 +159,7 @@ function auxRoutesWithAPrimaryRoute() {
.then((_) => rtr.navigateByUrl('/hello(modal)'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('main {hello} | aux {modal}');
expect(fixture.debugElement.nativeElement).toHaveText('main [hello] | aux [modal]');
async.done();
});
}));
@ -168,7 +168,7 @@ function auxRoutesWithAPrimaryRoute() {
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -177,7 +177,7 @@ function auxRoutesWithAPrimaryRoute() {
.then((_) => rtr.navigate(['/Hello', ['Modal']]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('main {hello} | aux {modal}');
expect(fixture.debugElement.nativeElement).toHaveText('main [hello] | aux [modal]');
async.done();
});
}));
@ -185,7 +185,7 @@ function auxRoutesWithAPrimaryRoute() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -204,7 +204,7 @@ function auxRoutesWithAPrimaryRoute() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main {<router-outlet></router-outlet>} | aux {<router-outlet name="modal"></router-outlet>}`)
`<a [routerLink]="['/Hello', ['Modal']]">open modal</a> | main [<router-outlet></router-outlet>] | aux [<router-outlet name="modal"></router-outlet>]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([
new Route({path: '/hello', component: HelloCmp, name: 'Hello'}),
@ -213,12 +213,12 @@ function auxRoutesWithAPrimaryRoute() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('open modal | main {} | aux {}');
.toHaveText('open modal | main [] | aux []');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('open modal | main {hello} | aux {modal}');
.toHaveText('open modal | main [hello] | aux [modal]');
expect(location.urlChanges).toEqual(['/hello(modal)']);
async.done();
});
@ -246,8 +246,8 @@ class ModalCmp {
@Component({
selector: 'aux-cmp',
template: 'main {<router-outlet></router-outlet>} | ' +
'aux {<router-outlet name="modal"></router-outlet>}',
template: 'main [<router-outlet></router-outlet>] | ' +
'aux [<router-outlet name="modal"></router-outlet>]',
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([

View File

@ -43,7 +43,7 @@ export function userCmpLoader() {
@Component({
selector: 'parent-cmp',
template: `inner { <router-outlet></router-outlet> }`,
template: `inner [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([new Route({path: '/b', component: HelloCmp, name: 'Child'})])
@ -57,7 +57,7 @@ export function parentCmpLoader() {
@Component({
selector: 'parent-cmp',
template: `inner { <router-outlet></router-outlet> }`,
template: `inner [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([new AsyncRoute({path: '/b', loader: helloCmpLoader, name: 'Child'})])
@ -70,7 +70,7 @@ export function asyncParentCmpLoader() {
@Component({
selector: 'parent-cmp',
template: `inner { <router-outlet></router-outlet> }`,
template: `inner [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig(
@ -85,7 +85,7 @@ export function asyncDefaultParentCmpLoader() {
@Component({
selector: 'parent-cmp',
template: `inner { <router-outlet></router-outlet> }`,
template: `inner [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([new Route({path: '/b', component: HelloCmp, name: 'Child', useAsDefault: true})])
@ -99,7 +99,7 @@ export function parentWithDefaultCmpLoader() {
@Component({
selector: 'team-cmp',
template: `team {{id}} | user { <router-outlet></router-outlet> }`,
template: `team {{id}} | user [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([new Route({path: '/user/:name', component: UserCmp, name: 'User'})])
@ -110,7 +110,7 @@ export class TeamCmp {
@Component({
selector: 'team-cmp',
template: `team {{id}} | user { <router-outlet></router-outlet> }`,
template: `team {{id}} | user [ <router-outlet></router-outlet> ]`,
directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([new AsyncRoute({path: '/user/:name', loader: userCmpLoader, name: 'User'})])
@ -140,7 +140,7 @@ export class RedirectToParentCmp {
}
@Component({selector: 'dynamic-loader-cmp', template: `{ <div #viewport></div> }`})
@Component({selector: 'dynamic-loader-cmp', template: `[ <div #viewport></div> ]`})
@RouteConfig([new Route({path: '/', component: HelloCmp})])
export class DynamicLoaderCmp {
private _componentRef: ComponentRef<any> = null;

View File

@ -221,7 +221,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then(
(_) =>
@ -229,13 +229,13 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
.then((_) => rtr.navigateByUrl('/a/b'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then(
(_) =>
@ -243,7 +243,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
.then((_) => rtr.navigate(['/Parent', 'Child']))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -251,7 +251,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then(
(_) =>
@ -269,18 +269,18 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithoutParams() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['Parent', 'Child']">nav to child</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/a/...', component: ParentCmp, name: 'Parent'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer { }');
expect(fixture.debugElement.nativeElement).toHaveText('nav to child | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('nav to child | outer { inner { hello } }');
.toHaveText('nav to child | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -306,7 +306,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `{ <router-outlet></router-outlet> }`)
compile(tcb, `[ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
@ -314,13 +314,13 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('{ team angular | user { hello matias } }');
.toHaveText('[ team angular | user [ hello matias ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `{ <router-outlet></router-outlet> }`)
compile(tcb, `[ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
@ -328,7 +328,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('{ team angular | user { hello matias } }');
.toHaveText('[ team angular | user [ hello matias ] ]');
async.done();
});
}));
@ -336,7 +336,7 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
@ -353,18 +353,18 @@ function syncRoutesWithSyncChildrenWithoutDefaultRoutesWithParams() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Team', {id: 'angular'}, 'User', {name: 'matias'}]">nav to matias</a> [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/team/:id/...', component: TeamCmp, name: 'Team'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias { }');
expect(fixture.debugElement.nativeElement).toHaveText('nav to matias [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('nav to matias { team angular | user { hello matias } }');
.toHaveText('nav to matias [ team angular | user [ hello matias ] ]');
expect(location.urlChanges).toEqual(['/team/angular/user/matias']);
async.done();
});
@ -390,27 +390,27 @@ function syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams() {
}));
it('should navigate by URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
.then((_) => rtr.navigateByUrl('/a'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
it('should navigate by link DSL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, `outer { <router-outlet></router-outlet> }`)
compile(tcb, `outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
.then((_) => rtr.navigate(['/Parent']))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -418,7 +418,7 @@ function syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams() {
it('should generate a link URL', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(
tcb,
`<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Parent']">link to inner</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
@ -435,19 +435,19 @@ function syncRoutesWithSyncChildrenWithDefaultRoutesWithoutParams() {
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(
tcb,
`<a [routerLink]="['/Parent']">link to inner</a> | outer { <router-outlet></router-outlet> }`)
`<a [routerLink]="['/Parent']">link to inner</a> | outer [ <router-outlet></router-outlet> ]`)
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route(
{path: '/a/...', component: ParentWithDefaultCmp, name: 'Parent'})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('link to inner | outer { }');
.toHaveText('link to inner | outer [ ]');
rtr.subscribe((_: any /** TODO #9100 */) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('link to inner | outer { inner { hello } }');
.toHaveText('link to inner | outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/a/b']);
async.done();
});
@ -481,7 +481,7 @@ function syncRoutesWithDynamicComponents() {
.then((_) => rtr.config([new Route({path: '/', component: HelloCmp})]))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('{ }');
expect(fixture.debugElement.nativeElement).toHaveText('[ ]');
return fixture.componentInstance.onSomeAction();
})
.then((_) => {
@ -490,7 +490,7 @@ function syncRoutesWithDynamicComponents() {
})
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
expect(fixture.debugElement.nativeElement).toHaveText('[ hello ]');
return fixture.componentInstance.onSomeAction();
})
@ -502,7 +502,7 @@ function syncRoutesWithDynamicComponents() {
// stable and we don't know when that is, only zones know.
PromiseWrapper.resolve(null).then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('{ hello }');
expect(fixture.debugElement.nativeElement).toHaveText('[ hello ]');
async.done();
});
})}));

View File

@ -71,7 +71,7 @@ export function main() {
});
rtr.navigateByUrl('/parent-activate/child-activate').then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('parent {activate cmp}');
expect(fixture.debugElement.nativeElement).toHaveText('parent [activate cmp]');
expect(log).toEqual([
'parent activate: null -> /parent-activate', 'activate: null -> /child-activate'
]);
@ -106,7 +106,7 @@ export function main() {
if (ev.startsWith('deactivate')) {
completer.resolve(true);
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('parent {deactivate cmp}');
expect(fixture.debugElement.nativeElement).toHaveText('parent [deactivate cmp]');
}
});
rtr.navigateByUrl('/a').then((_) => {
@ -130,14 +130,14 @@ export function main() {
.then((_) => {
fixture.detectChanges();
expect(log).toEqual([]);
expect(fixture.debugElement.nativeElement).toHaveText('reuse {A}');
expect(fixture.debugElement.nativeElement).toHaveText('reuse [A]');
expect(cmpInstanceCount).toBe(1);
})
.then((_) => rtr.navigateByUrl('/on-reuse/2/b'))
.then((_) => {
fixture.detectChanges();
expect(log).toEqual(['reuse: /on-reuse/1 -> /on-reuse/2']);
expect(fixture.debugElement.nativeElement).toHaveText('reuse {B}');
expect(fixture.debugElement.nativeElement).toHaveText('reuse [B]');
expect(cmpInstanceCount).toBe(1);
async.done();
});
@ -153,14 +153,14 @@ export function main() {
.then((_) => {
fixture.detectChanges();
expect(log).toEqual([]);
expect(fixture.debugElement.nativeElement).toHaveText('reuse {A}');
expect(fixture.debugElement.nativeElement).toHaveText('reuse [A]');
expect(cmpInstanceCount).toBe(1);
})
.then((_) => rtr.navigateByUrl('/never-reuse/2/b'))
.then((_) => {
fixture.detectChanges();
expect(log).toEqual([]);
expect(fixture.debugElement.nativeElement).toHaveText('reuse {B}');
expect(fixture.debugElement.nativeElement).toHaveText('reuse [B]');
expect(cmpInstanceCount).toBe(2);
async.done();
});
@ -180,7 +180,7 @@ export function main() {
});
rtr.navigateByUrl('/can-activate/a').then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('routerCanActivate {A}');
expect(fixture.debugElement.nativeElement).toHaveText('routerCanActivate [A]');
expect(log).toEqual(['routerCanActivate: null -> /can-activate']);
async.done();
});
@ -215,7 +215,7 @@ export function main() {
.then((_) => rtr.navigateByUrl('/can-deactivate/a'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate {A}');
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate [A]');
expect(log).toEqual([]);
ObservableWrapper.subscribe<string>(eventBus, (ev) => {
@ -241,7 +241,7 @@ export function main() {
.then((_) => rtr.navigateByUrl('/can-deactivate/a'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate {A}');
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate [A]');
expect(log).toEqual([]);
ObservableWrapper.subscribe<string>(eventBus, (ev) => {
@ -252,7 +252,7 @@ export function main() {
rtr.navigateByUrl('/a').then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate {A}');
expect(fixture.debugElement.nativeElement).toHaveText('routerCanDeactivate [A]');
expect(log).toEqual(['routerCanDeactivate: /can-deactivate -> /a']);
async.done();
});
@ -380,7 +380,7 @@ class ActivateCmp implements OnActivate {
@Component({
selector: 'parent-activate-cmp',
template: `parent {<router-outlet></router-outlet>}`,
template: `parent [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/child-activate', component: ActivateCmp})])
@ -410,7 +410,7 @@ class WaitDeactivateCmp implements OnDeactivate {
@Component({
selector: 'parent-deactivate-cmp',
template: `parent {<router-outlet></router-outlet>}`,
template: `parent [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/child-deactivate', component: WaitDeactivateCmp})])
@ -422,7 +422,7 @@ class ParentDeactivateCmp implements OnDeactivate {
@Component({
selector: 'reuse-cmp',
template: `reuse {<router-outlet></router-outlet>}`,
template: `reuse [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/a', component: A}), new Route({path: '/b', component: B})])
@ -437,7 +437,7 @@ class ReuseCmp implements OnReuse,
@Component({
selector: 'never-reuse-cmp',
template: `reuse {<router-outlet></router-outlet>}`,
template: `reuse [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/a', component: A}), new Route({path: '/b', component: B})])
@ -452,7 +452,7 @@ class NeverReuseCmp implements OnReuse,
@Component({
selector: 'can-activate-cmp',
template: `routerCanActivate {<router-outlet></router-outlet>}`,
template: `routerCanActivate [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/a', component: A}), new Route({path: '/b', component: B})])
@ -468,7 +468,7 @@ class CanActivateCmp {
@Component({
selector: 'can-deactivate-cmp',
template: `routerCanDeactivate {<router-outlet></router-outlet>}`,
template: `routerCanDeactivate [<router-outlet></router-outlet>]`,
directives: [RouterOutlet]
})
@RouteConfig([new Route({path: '/a', component: A}), new Route({path: '/b', component: B})])

View File

@ -72,13 +72,13 @@ export function main() {
it('should navigate to child routes',
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, 'outer { <router-outlet></router-outlet> }')
compile(tcb, 'outer [ <router-outlet></router-outlet> ]')
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route({path: '/a/...', component: ParentCmp})]))
.then((_) => rtr.navigateByUrl('/a/b'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -86,13 +86,13 @@ export function main() {
it('should navigate to child routes that capture an empty path',
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, 'outer { <router-outlet></router-outlet> }')
compile(tcb, 'outer [ <router-outlet></router-outlet> ]')
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route({path: '/a/...', component: ParentCmp})]))
.then((_) => rtr.navigateByUrl('/a'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -101,14 +101,14 @@ export function main() {
inject(
[AsyncTestCompleter, Location],
(async: AsyncTestCompleter, location: any /** TODO #9100 */) => {
compile(tcb, 'outer { <router-outlet></router-outlet> }')
compile(tcb, 'outer [ <router-outlet></router-outlet> ]')
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new Route({path: '/...', component: ParentCmp})]))
.then((_) => rtr.navigateByUrl('/b'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement)
.toHaveText('outer { inner { hello } }');
.toHaveText('outer [ inner [ hello ] ]');
expect(location.urlChanges).toEqual(['/b']);
async.done();
});
@ -116,13 +116,13 @@ export function main() {
it('should navigate to child routes of async routes',
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
compile(tcb, 'outer { <router-outlet></router-outlet> }')
compile(tcb, 'outer [ <router-outlet></router-outlet> ]')
.then((rtc) => {fixture = rtc})
.then((_) => rtr.config([new AsyncRoute({path: '/a/...', loader: parentLoader})]))
.then((_) => rtr.navigateByUrl('/a/b'))
.then((_) => {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]');
async.done();
});
}));
@ -154,14 +154,14 @@ export function main() {
.then((_) => {
fixture.detectChanges();
expect(cmpInstanceCount).toBe(1);
expect(fixture.debugElement.nativeElement).toHaveText('team angular { hello rado }');
expect(fixture.debugElement.nativeElement).toHaveText('team angular [ hello rado ]');
})
.then((_) => rtr.navigateByUrl('/team/angular/user/victor'))
.then((_) => {
fixture.detectChanges();
expect(cmpInstanceCount).toBe(1);
expect(fixture.debugElement.nativeElement)
.toHaveText('team angular { hello victor }');
.toHaveText('team angular [ hello victor ]');
async.done();
});
}));
@ -176,14 +176,14 @@ export function main() {
fixture.detectChanges();
expect(cmpInstanceCount).toBe(1);
expect(childCmpInstanceCount).toBe(1);
expect(fixture.debugElement.nativeElement).toHaveText('team angular { hello rado }');
expect(fixture.debugElement.nativeElement).toHaveText('team angular [ hello rado ]');
})
.then((_) => rtr.navigateByUrl('/team/dart/user/rado'))
.then((_) => {
fixture.detectChanges();
expect(cmpInstanceCount).toBe(2);
expect(childCmpInstanceCount).toBe(2);
expect(fixture.debugElement.nativeElement).toHaveText('team dart { hello rado }');
expect(fixture.debugElement.nativeElement).toHaveText('team dart [ hello rado ]');
async.done();
});
}));
@ -284,7 +284,7 @@ function parentLoader() {
@Component({
selector: 'parent-cmp',
template: `inner { <router-outlet></router-outlet> }`,
template: `inner [ <router-outlet></router-outlet> ]`,
directives: [RouterOutlet],
})
@RouteConfig([
@ -297,7 +297,7 @@ class ParentCmp {
@Component({
selector: 'team-cmp',
template: `team {{id}} { <router-outlet></router-outlet> }`,
template: `team {{id}} [ <router-outlet></router-outlet> ]`,
directives: [RouterOutlet],
})
@RouteConfig([new Route({path: '/user/:name', component: UserCmp})])

View File

@ -440,9 +440,9 @@ function parentCmpLoader() {
@Component({
selector: 'parent-cmp',
template: `{ <a [routerLink]="['./Grandchild']" class="grandchild-link">Grandchild</a>
template: `[ <a [routerLink]="['./Grandchild']" class="grandchild-link">Grandchild</a>
<a [routerLink]="['./BetterGrandchild']" class="better-grandchild-link">Better Grandchild</a>
<router-outlet></router-outlet> }`,
<router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([

View File

@ -59,7 +59,7 @@ export function main() {
bootstrap(HierarchyAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { parent { hello } }');
expect(el).toHaveText('root [ parent [ hello ] ]');
expect(applicationRef.instance.location.path()).toEqual('/parent/child');
async.done();
});
@ -73,7 +73,7 @@ export function main() {
bootstrap(RedirectAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { hello }');
expect(el).toHaveText('root [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('/after');
async.done();
});
@ -87,7 +87,7 @@ export function main() {
bootstrap(AsyncAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { hello }');
expect(el).toHaveText('root [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('/hello');
async.done();
});
@ -101,7 +101,7 @@ export function main() {
bootstrap(AuxAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { hello } aside { hello }');
expect(el).toHaveText('root [ hello ] aside [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('/hello(aside)');
async.done();
});
@ -115,7 +115,7 @@ export function main() {
bootstrap(ConciseAsyncAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { hello }');
expect(el).toHaveText('root [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('/hello');
async.done();
});
@ -129,7 +129,7 @@ export function main() {
bootstrap(ExplicitConstructorAppCmp, testBindings).then((applicationRef) => {
var router = applicationRef.instance.router;
router.subscribe((_: any /** TODO #9100 */) => {
expect(el).toHaveText('root { hello }');
expect(el).toHaveText('root [ hello ]');
expect(applicationRef.instance.location.path()).toEqual('/hello');
async.done();
});
@ -181,7 +181,7 @@ class HelloCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([
@ -197,7 +197,7 @@ function HelloLoader(): Promise<any> {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([
@ -209,7 +209,7 @@ class AsyncAppCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([
@ -222,7 +222,7 @@ class ConciseAsyncAppCmp {
@Component({
selector: 'app-cmp',
template:
`root { <router-outlet></router-outlet> } aside { <router-outlet name="aside"></router-outlet> }`,
`root [ <router-outlet></router-outlet> ] aside [ <router-outlet name="aside"></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([{path: '/hello', component: HelloCmp}, {aux: 'aside', component: HelloCmp}])
@ -232,7 +232,7 @@ class AuxAppCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([
@ -244,7 +244,7 @@ class ExplicitConstructorAppCmp {
@Component({
selector: 'parent-cmp',
template: `parent { <router-outlet></router-outlet> }`,
template: `parent [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([{path: '/child', component: HelloCmp}])
@ -253,7 +253,7 @@ class ParentCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([{path: '/parent/...', component: ParentCmp}])
@ -263,7 +263,7 @@ class HierarchyAppCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([{path: '/hello'}])
@ -272,7 +272,7 @@ class WrongConfigCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([{path: '/child', component: HelloCmp, name: 'child'}])
@ -281,7 +281,7 @@ class BadAliasNameCmp {
@Component({
selector: 'app-cmp',
template: `root { <router-outlet></router-outlet> }`,
template: `root [ <router-outlet></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
@RouteConfig([

View File

@ -1,7 +1,7 @@
import 'rxjs/add/operator/map';
import {Location} from '@angular/common';
import {AppModule, AppModuleFactory, AppModuleFactoryLoader, Compiler, Component, Injectable} from '@angular/core';
import {AppModule, AppModuleFactoryLoader, Component} from '@angular/core';
import {ComponentFixture, TestComponentBuilder} from '@angular/core/testing';
import {addProviders, configureModule, fakeAsync, inject, tick} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers';
@ -118,7 +118,7 @@ describe('Integration', () => {
(<any>location).simulateHashChange('/team/22/user/fedor');
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { user fedor, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ user fedor, right: ]');
})));
it('should update the location when the matched route does not change',
@ -162,7 +162,7 @@ describe('Integration', () => {
advance(fixture);
expect(fixture.debugElement.nativeElement)
.toHaveText('team 22 { user victor, right: simple }');
.toHaveText('team 22 [ user victor, right: simple ]');
})));
it('should deactivate outlets',
@ -186,7 +186,7 @@ describe('Integration', () => {
advance(fixture);
expect(fixture.debugElement.nativeElement)
.toHaveText('team 22 { user victor, right: }');
.toHaveText('team 22 [ user victor, right: ]');
})));
it('should deactivate nested outlets',
@ -394,27 +394,27 @@ describe('Integration', () => {
advance(fixture);
expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)');
expect(fixture.debugElement.nativeElement)
.toHaveText('primary {simple} right {user victor}');
.toHaveText('primary [simple] right [user victor]');
// navigate to the same route with different params (reuse)
router.navigateByUrl('/parent/22/(simple//right:user/fedor)');
advance(fixture);
expect(location.path()).toEqual('/parent/22/(simple//right:user/fedor)');
expect(fixture.debugElement.nativeElement)
.toHaveText('primary {simple} right {user fedor}');
.toHaveText('primary [simple] right [user fedor]');
// navigate to a normal route (check deactivation)
router.navigateByUrl('/user/victor');
advance(fixture);
expect(location.path()).toEqual('/user/victor');
expect(fixture.debugElement.nativeElement).toHaveText('primary {user victor} right {}');
expect(fixture.debugElement.nativeElement).toHaveText('primary [user victor] right []');
// navigate back to a componentless route
router.navigateByUrl('/parent/11/(simple//right:user/victor)');
advance(fixture);
expect(location.path()).toEqual('/parent/11/(simple//right:user/victor)');
expect(fixture.debugElement.nativeElement)
.toHaveText('primary {simple} right {user victor}');
.toHaveText('primary [simple] right [user victor]');
})));
it('should emit an event when an outlet gets activated',
@ -538,14 +538,14 @@ describe('Integration', () => {
router.navigateByUrl('/team/22/link');
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { link, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ link, right: ]');
const native = fixture.debugElement.nativeElement.querySelector('a');
expect(native.getAttribute('href')).toEqual('/team/33/simple');
native.click();
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 33 { simple, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 33 [ simple, right: ]');
})));
it('should update hrefs when query params change',
@ -591,13 +591,13 @@ describe('Integration', () => {
router.navigateByUrl('/team/22/link');
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { link, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ link, right: ]');
const native = fixture.debugElement.nativeElement.querySelector('button');
native.click();
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 33 { simple, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 33 [ simple, right: ]');
})));
it('should support absolute router links',
@ -616,14 +616,14 @@ describe('Integration', () => {
router.navigateByUrl('/team/22/link');
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { link, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ link, right: ]');
const native = fixture.debugElement.nativeElement.querySelector('a');
expect(native.getAttribute('href')).toEqual('/team/33/simple');
native.click();
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 33 { simple, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 33 [ simple, right: ]');
})));
it('should support relative router links',
@ -642,14 +642,14 @@ describe('Integration', () => {
router.navigateByUrl('/team/22/link');
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { link, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ link, right: ]');
const native = fixture.debugElement.nativeElement.querySelector('a');
expect(native.getAttribute('href')).toEqual('/team/22/simple');
native.click();
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { simple, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ simple, right: ]');
})));
it('should support top-level link',
@ -702,7 +702,7 @@ describe('Integration', () => {
native.click();
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { simple, right: }');
expect(fixture.debugElement.nativeElement).toHaveText('team 22 [ simple, right: ]');
expect(location.path()).toEqual('/team/22/simple?q=1#f');
})));
@ -1127,7 +1127,7 @@ describe('Integration', () => {
loader: SpyAppModuleFactoryLoader) => {
@Component({
selector: 'lazy',
template: 'lazy-loaded-parent {<router-outlet></router-outlet>}',
template: 'lazy-loaded-parent [<router-outlet></router-outlet>]',
directives: ROUTER_DIRECTIVES
})
class ParentLazyLoadedComponent {
@ -1160,7 +1160,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy/loaded/child');
expect(fixture.debugElement.nativeElement)
.toHaveText('lazy-loaded-parent {lazy-loaded-child}');
.toHaveText('lazy-loaded-parent [lazy-loaded-child]');
})));
it('error emit an error when cannot load a config',
@ -1287,7 +1287,7 @@ class BlankCmp {
@Component({
selector: 'team-cmp',
template:
`team {{id | async}} { <router-outlet></router-outlet>, right: <router-outlet name="right"></router-outlet> }`,
`team {{id | async}} [ <router-outlet></router-outlet>, right: <router-outlet name="right"></router-outlet> ]`,
directives: ROUTER_DIRECTIVES
})
class TeamCmp {
@ -1376,7 +1376,7 @@ class RootCmp {
@Component({
selector: 'root-cmp',
template:
`primary {<router-outlet></router-outlet>} right {<router-outlet name="right"></router-outlet>}`,
`primary [<router-outlet></router-outlet>] right [<router-outlet name="right"></router-outlet>]`,
directives: [ROUTER_DIRECTIVES],
precompile: [BlankCmp, SimpleCmp, RouteCmp, UserCmp]
})