refactor(common): cleanup directive tests

This commit is contained in:
Victor Berchet 2016-09-08 20:37:20 -07:00
parent c649a5c5ab
commit 82f30e09f0
7 changed files with 475 additions and 538 deletions

View File

@ -8,150 +8,135 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component, ContentChild, TemplateRef} from '@angular/core'; import {Component, ContentChild, TemplateRef} from '@angular/core';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {ListWrapper} from '../../src/facade/collection';
let thisArg: any; let thisArg: any;
export function main() { export function main() {
describe('ngFor', () => { describe('ngFor', () => {
const TEMPLATE = let fixture: ComponentFixture<any>;
'<div><span template="ngFor let item of items">{{item.toString()}};</span></div>';
function getComponent(): TestComponent { return fixture.componentInstance; }
function detectChangesAndExpectText(text: string): void {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText(text);
}
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule( TestBed.configureTestingModule({
{declarations: [TestComponent, ComponentUsingTestComponent], imports: [CommonModule]}); declarations: [
TestComponent,
ComponentUsingTestComponent,
],
imports: [CommonModule],
});
}); });
it('should reflect initial elements', async(() => { it('should reflect initial elements', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); detectChangesAndExpectText('1;2;');
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
})); }));
it('should reflect added elements', async(() => { it('should reflect added elements', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
getComponent().items.push(3);
(<number[]>fixture.debugElement.componentInstance.items).push(3); detectChangesAndExpectText('1;2;3;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
})); }));
it('should reflect removed elements', async(() => { it('should reflect removed elements', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
getComponent().items.splice(1, 1);
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 1); detectChangesAndExpectText('1;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('1;');
})); }));
it('should reflect moved elements', async(() => { it('should reflect moved elements', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
getComponent().items.splice(0, 1);
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0); getComponent().items.push(1);
(<number[]>fixture.debugElement.componentInstance.items).push(1); detectChangesAndExpectText('2;1;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('2;1;');
})); }));
it('should reflect a mix of all changes (additions/removals/moves)', async(() => { it('should reflect a mix of all changes (additions/removals/moves)', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5]; getComponent().items = [0, 1, 2, 3, 4, 5];
fixture.detectChanges(); fixture.detectChanges();
fixture.debugElement.componentInstance.items = [6, 2, 7, 0, 4, 8]; getComponent().items = [6, 2, 7, 0, 4, 8];
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('6;2;7;0;4;8;'); detectChangesAndExpectText('6;2;7;0;4;8;');
})); }));
it('should iterate over an array of objects', async(() => { it('should iterate over an array of objects', async(() => {
const template = '<ul><li template="ngFor let item of items">{{item["name"]}};</li></ul>'; const template = '<ul><li template="ngFor let item of items">{{item["name"]}};</li></ul>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
// INIT // INIT
fixture.debugElement.componentInstance.items = [{'name': 'misko'}, {'name': 'shyam'}]; getComponent().items = [{'name': 'misko'}, {'name': 'shyam'}];
fixture.detectChanges(); detectChangesAndExpectText('misko;shyam;');
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;');
// GROW // GROW
(<any[]>fixture.debugElement.componentInstance.items).push({'name': 'adam'}); getComponent().items.push({'name': 'adam'});
fixture.detectChanges(); detectChangesAndExpectText('misko;shyam;adam;');
expect(fixture.debugElement.nativeElement).toHaveText('misko;shyam;adam;');
// SHRINK // SHRINK
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 2); getComponent().items.splice(2, 1);
ListWrapper.removeAt(fixture.debugElement.componentInstance.items, 0); getComponent().items.splice(0, 1);
fixture.detectChanges(); detectChangesAndExpectText('shyam;');
expect(fixture.debugElement.nativeElement).toHaveText('shyam;');
})); }));
it('should gracefully handle nulls', async(() => { it('should gracefully handle nulls', async(() => {
const template = '<ul><li template="ngFor let item of null">{{item}};</li></ul>'; const template = '<ul><li template="ngFor let item of null">{{item}};</li></ul>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); detectChangesAndExpectText('');
expect(fixture.debugElement.nativeElement).toHaveText('');
})); }));
it('should gracefully handle ref changing to null and back', async(() => { it('should gracefully handle ref changing to null and back', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
fixture.debugElement.componentInstance.items = null; detectChangesAndExpectText('1;2;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.items = [1, 2, 3]; getComponent().items = null;
fixture.detectChanges(); detectChangesAndExpectText('');
expect(fixture.debugElement.nativeElement).toHaveText('1;2;3;');
getComponent().items = [1, 2, 3];
detectChangesAndExpectText('1;2;3;');
})); }));
it('should throw on non-iterable ref and suggest using an array', async(() => { it('should throw on non-iterable ref and suggest using an array', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = 'whaaa'; getComponent().items = <any>'whaaa';
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
/Cannot find a differ supporting object 'whaaa' of type 'string'. NgFor only supports binding to Iterables such as Arrays/); /Cannot find a differ supporting object 'whaaa' of type 'string'. NgFor only supports binding to Iterables such as Arrays/);
})); }));
it('should throw on ref changing to string', async(() => { it('should throw on ref changing to string', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('1;2;');
fixture.debugElement.componentInstance.items = 'whaaa'; detectChangesAndExpectText('1;2;');
getComponent().items = <any>'whaaa';
expect(() => fixture.detectChanges()).toThrowError(); expect(() => fixture.detectChanges()).toThrowError();
})); }));
it('should works with duplicates', async(() => { it('should works with duplicates', async(() => {
TestBed.overrideComponent(TestComponent, {set: {template: TEMPLATE}}); fixture = createTestComponent();
let fixture = TestBed.createComponent(TestComponent);
var a = new Foo(); const a = new Foo();
fixture.debugElement.componentInstance.items = [a, a]; getComponent().items = [a, a];
fixture.detectChanges(); detectChangesAndExpectText('foo;foo;');
expect(fixture.debugElement.nativeElement).toHaveText('foo;foo;');
})); }));
it('should repeat over nested arrays', async(() => { it('should repeat over nested arrays', async(() => {
@ -162,18 +147,13 @@ export function main() {
'</div>|' + '</div>|' +
'</div>' + '</div>' +
'</div>'; '</div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']]; getComponent().items = [['a', 'b'], ['c']];
fixture.detectChanges(); detectChangesAndExpectText('a-2;b-2;|c-1;|');
fixture.detectChanges();
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;|c-1;|');
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']]; getComponent().items = [['e'], ['f', 'g']];
fixture.detectChanges(); detectChangesAndExpectText('e-1;|f-2;g-2;|');
expect(fixture.debugElement.nativeElement).toHaveText('e-1;|f-2;g-2;|');
})); }));
it('should repeat over nested arrays with no intermediate element', async(() => { it('should repeat over nested arrays with no intermediate element', async(() => {
@ -181,16 +161,13 @@ export function main() {
'<div template="ngFor let subitem of item">' + '<div template="ngFor let subitem of item">' +
'{{subitem}}-{{item.length}};' + '{{subitem}}-{{item.length}};' +
'</div></template></div>'; '</div></template></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [['a', 'b'], ['c']]; getComponent().items = [['a', 'b'], ['c']];
fixture.detectChanges(); detectChangesAndExpectText('a-2;b-2;c-1;');
expect(fixture.debugElement.nativeElement).toHaveText('a-2;b-2;c-1;');
fixture.debugElement.componentInstance.items = [['e'], ['f', 'g']]; getComponent().items = [['e'], ['f', 'g']];
fixture.detectChanges(); detectChangesAndExpectText('e-1;f-2;g-2;');
expect(fixture.debugElement.nativeElement).toHaveText('e-1;f-2;g-2;');
})); }));
it('should repeat over nested ngIf that are the last node in the ngFor temlate', async(() => { it('should repeat over nested ngIf that are the last node in the ngFor temlate', async(() => {
@ -198,97 +175,77 @@ export function main() {
`<div><template ngFor let-item [ngForOf]="items" let-i="index"><div>{{i}}|</div>` + `<div><template ngFor let-item [ngForOf]="items" let-i="index"><div>{{i}}|</div>` +
`<div *ngIf="i % 2 == 0">even|</div></template></div>`; `<div *ngIf="i % 2 == 0">even|</div></template></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
const el = fixture.debugElement.nativeElement;
const items = [1]; const items = [1];
fixture.debugElement.componentInstance.items = items; getComponent().items = items;
fixture.detectChanges(); detectChangesAndExpectText('0|even|');
expect(el).toHaveText('0|even|');
items.push(1); items.push(1);
fixture.detectChanges(); detectChangesAndExpectText('0|even|1|');
expect(el).toHaveText('0|even|1|');
items.push(1); items.push(1);
fixture.detectChanges(); detectChangesAndExpectText('0|even|1|2|even|');
expect(el).toHaveText('0|even|1|2|even|');
})); }));
it('should display indices correctly', async(() => { it('should display indices correctly', async(() => {
const template = const template =
'<div><span template="ngFor: let item of items; let i=index">{{i.toString()}}</span></div>'; '<div><span template="ngFor: let item of items; let i=index">{{i.toString()}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; getComponent().items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
fixture.detectChanges(); detectChangesAndExpectText('0123456789');
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
fixture.debugElement.componentInstance.items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0]; getComponent().items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0];
fixture.detectChanges(); detectChangesAndExpectText('0123456789');
expect(fixture.debugElement.nativeElement).toHaveText('0123456789');
})); }));
it('should display first item correctly', async(() => { it('should display first item correctly', async(() => {
const template = const template =
'<div><span template="ngFor: let item of items; let isFirst=first">{{isFirst.toString()}}</span></div>'; '<div><span template="ngFor: let item of items; let isFirst=first">{{isFirst.toString()}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2]; getComponent().items = [0, 1, 2];
fixture.detectChanges(); detectChangesAndExpectText('truefalsefalse');
expect(fixture.debugElement.nativeElement).toHaveText('truefalsefalse');
fixture.debugElement.componentInstance.items = [2, 1]; getComponent().items = [2, 1];
fixture.detectChanges(); detectChangesAndExpectText('truefalse');
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
})); }));
it('should display last item correctly', async(() => { it('should display last item correctly', async(() => {
const template = const template =
'<div><span template="ngFor: let item of items; let isLast=last">{{isLast.toString()}}</span></div>'; '<div><span template="ngFor: let item of items; let isLast=last">{{isLast.toString()}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2]; getComponent().items = [0, 1, 2];
fixture.detectChanges(); detectChangesAndExpectText('falsefalsetrue');
expect(fixture.debugElement.nativeElement).toHaveText('falsefalsetrue');
fixture.debugElement.componentInstance.items = [2, 1]; getComponent().items = [2, 1];
fixture.detectChanges(); detectChangesAndExpectText('falsetrue');
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
})); }));
it('should display even items correctly', async(() => { it('should display even items correctly', async(() => {
const template = const template =
'<div><span template="ngFor: let item of items; let isEven=even">{{isEven.toString()}}</span></div>'; '<div><span template="ngFor: let item of items; let isEven=even">{{isEven.toString()}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2]; getComponent().items = [0, 1, 2];
fixture.detectChanges(); detectChangesAndExpectText('truefalsetrue');
expect(fixture.debugElement.nativeElement).toHaveText('truefalsetrue');
fixture.debugElement.componentInstance.items = [2, 1]; getComponent().items = [2, 1];
fixture.detectChanges(); detectChangesAndExpectText('truefalse');
expect(fixture.debugElement.nativeElement).toHaveText('truefalse');
})); }));
it('should display odd items correctly', async(() => { it('should display odd items correctly', async(() => {
const template = const template =
'<div><span template="ngFor: let item of items; let isOdd=odd">{{isOdd.toString()}}</span></div>'; '<div><span template="ngFor: let item of items; let isOdd=odd">{{isOdd.toString()}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [0, 1, 2, 3]; getComponent().items = [0, 1, 2, 3];
fixture.detectChanges(); detectChangesAndExpectText('falsetruefalsetrue');
expect(fixture.debugElement.nativeElement).toHaveText('falsetruefalsetrue');
fixture.debugElement.componentInstance.items = [2, 1]; getComponent().items = [2, 1];
fixture.detectChanges(); detectChangesAndExpectText('falsetrue');
expect(fixture.debugElement.nativeElement).toHaveText('falsetrue');
})); }));
it('should allow to use a custom template', async(() => { it('should allow to use a custom template', async(() => {
@ -298,7 +255,7 @@ export function main() {
const cutTemplate = const cutTemplate =
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>'; '<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>';
TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}}); TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}});
let fixture = TestBed.createComponent(ComponentUsingTestComponent); fixture = TestBed.createComponent(ComponentUsingTestComponent);
const testComponent = fixture.debugElement.children[0]; const testComponent = fixture.debugElement.children[0];
testComponent.componentInstance.items = ['a', 'b', 'c']; testComponent.componentInstance.items = ['a', 'b', 'c'];
@ -313,7 +270,7 @@ export function main() {
const cutTemplate = const cutTemplate =
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>'; '<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>';
TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}}); TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}});
let fixture = TestBed.createComponent(ComponentUsingTestComponent); fixture = TestBed.createComponent(ComponentUsingTestComponent);
const testComponent = fixture.debugElement.children[0]; const testComponent = fixture.debugElement.children[0];
testComponent.componentInstance.items = ['a', 'b', 'c']; testComponent.componentInstance.items = ['a', 'b', 'c'];
@ -328,7 +285,7 @@ export function main() {
const cutTemplate = const cutTemplate =
'<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>'; '<test-cmp><li template="let item; let i=index">{{i}}: {{item}};</li></test-cmp>';
TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}}); TestBed.overrideComponent(ComponentUsingTestComponent, {set: {template: cutTemplate}});
let fixture = TestBed.createComponent(ComponentUsingTestComponent); fixture = TestBed.createComponent(ComponentUsingTestComponent);
const testComponent = fixture.debugElement.children[0]; const testComponent = fixture.debugElement.children[0];
testComponent.componentInstance.items = ['a', 'b', 'c']; testComponent.componentInstance.items = ['a', 'b', 'c'];
@ -340,12 +297,11 @@ export function main() {
it('should set the context to the component instance', async(() => { it('should set the context to the component instance', async(() => {
const template = const template =
`<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByContext.bind(this)"></template>`; `<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByContext.bind(this)"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
thisArg = null; thisArg = null;
fixture.detectChanges(); fixture.detectChanges();
expect(thisArg).toBe(fixture.debugElement.componentInstance); expect(thisArg).toBe(getComponent());
})); }));
it('should not replace tracked items', async(() => { it('should not replace tracked items', async(() => {
@ -353,62 +309,53 @@ export function main() {
`<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById" let-i="index"> `<template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById" let-i="index">
<p>{{items[i]}}</p> <p>{{items[i]}}</p>
</template>`; </template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
var buildItemList = () => { const buildItemList = () => {
fixture.debugElement.componentInstance.items = [{'id': 'a'}]; getComponent().items = [{'id': 'a'}];
fixture.detectChanges(); fixture.detectChanges();
return fixture.debugElement.queryAll(By.css('p'))[0]; return fixture.debugElement.queryAll(By.css('p'))[0];
}; };
var firstP = buildItemList(); const firstP = buildItemList();
var finalP = buildItemList(); const finalP = buildItemList();
expect(finalP.nativeElement).toBe(firstP.nativeElement); expect(finalP.nativeElement).toBe(firstP.nativeElement);
})); }));
it('should update implicit local variable on view', async(() => { it('should update implicit local variable on view', async(() => {
const template = const template =
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`; `<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'blue'}]; getComponent().items = [{'id': 'a', 'color': 'blue'}];
fixture.detectChanges(); detectChangesAndExpectText('blue');
expect(fixture.debugElement.nativeElement).toHaveText('blue');
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'red'}]; getComponent().items = [{'id': 'a', 'color': 'red'}];
fixture.detectChanges(); detectChangesAndExpectText('red');
expect(fixture.debugElement.nativeElement).toHaveText('red');
})); }));
it('should move items around and keep them updated ', async(() => { it('should move items around and keep them updated ', async(() => {
const template = const template =
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`; `<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackById">{{item['color']}}</template></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = getComponent().items = [{'id': 'a', 'color': 'blue'}, {'id': 'b', 'color': 'yellow'}];
[{'id': 'a', 'color': 'blue'}, {'id': 'b', 'color': 'yellow'}]; detectChangesAndExpectText('blueyellow');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('blueyellow'); getComponent().items = [{'id': 'b', 'color': 'orange'}, {'id': 'a', 'color': 'red'}];
fixture.debugElement.componentInstance.items = detectChangesAndExpectText('orangered');
[{'id': 'b', 'color': 'orange'}, {'id': 'a', 'color': 'red'}];
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('orangered');
})); }));
it('should handle added and removed items properly when tracking by index', async(() => { it('should handle added and removed items properly when tracking by index', async(() => {
const template = const template =
`<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByIndex">{{item}}</template></div>`; `<div><template ngFor let-item [ngForOf]="items" [ngForTrackBy]="trackByIndex">{{item}}</template></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.items = ['a', 'b', 'c', 'd']; getComponent().items = ['a', 'b', 'c', 'd'];
fixture.detectChanges(); fixture.detectChanges();
fixture.debugElement.componentInstance.items = ['e', 'f', 'g', 'h']; getComponent().items = ['e', 'f', 'g', 'h'];
fixture.detectChanges(); fixture.detectChanges();
fixture.debugElement.componentInstance.items = ['e', 'f', 'h']; getComponent().items = ['e', 'f', 'h'];
fixture.detectChanges(); detectChangesAndExpectText('efh');
expect(fixture.debugElement.nativeElement).toHaveText('efh');
})); }));
}); });
}); });
@ -421,8 +368,7 @@ class Foo {
@Component({selector: 'test-cmp', template: ''}) @Component({selector: 'test-cmp', template: ''})
class TestComponent { class TestComponent {
@ContentChild(TemplateRef) contentTpl: TemplateRef<Object>; @ContentChild(TemplateRef) contentTpl: TemplateRef<Object>;
items: any; items: any[] = [1, 2];
constructor() { this.items = [1, 2]; }
trackById(index: number, item: any): string { return item['id']; } trackById(index: number, item: any): string { return item['id']; }
trackByIndex(index: number, item: any): number { return index; } trackByIndex(index: number, item: any): number { return index; }
trackByContext(): void { thisArg = this; } trackByContext(): void { thisArg = this; }
@ -430,6 +376,12 @@ class TestComponent {
@Component({selector: 'outer-cmp', template: ''}) @Component({selector: 'outer-cmp', template: ''})
class ComponentUsingTestComponent { class ComponentUsingTestComponent {
items: any; items: any = [1, 2];
constructor() { this.items = [1, 2]; } }
const TEMPLATE = '<div><span template="ngFor let item of items">{{item.toString()}};</span></div>';
function createTestComponent(template: string = TEMPLATE): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.createComponent(TestComponent);
} }

View File

@ -8,99 +8,94 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
export function main() { export function main() {
describe('ngIf directive', () => { describe('ngIf directive', () => {
let fixture: ComponentFixture<any>;
function getComponent(): TestComponent { return fixture.componentInstance; }
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({declarations: [TestComponent], imports: [CommonModule]}); TestBed.configureTestingModule({
declarations: [TestComponent],
imports: [CommonModule],
});
}); });
it('should work in a template attribute', async(() => { it('should work in a template attribute', async(() => {
const template = '<div><span template="ngIf booleanCondition">hello</span></div>'; const template = '<div><span template="ngIf booleanCondition">hello</span></div>';
fixture = createTestComponent(template);
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('hello');
expect(fixture.debugElement.nativeElement).toHaveText('hello');
})); }));
it('should work in a template element', async(() => { it('should work in a template element', async(() => {
const template = const template =
'<div><template [ngIf]="booleanCondition"><span>hello2</span></template></div>'; '<div><template [ngIf]="booleanCondition"><span>hello2</span></template></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('hello2');
expect(fixture.debugElement.nativeElement).toHaveText('hello2');
})); }));
it('should toggle node when condition changes', async(() => { it('should toggle node when condition changes', async(() => {
const template = '<div><span template="ngIf booleanCondition">hello</span></div>'; const template = '<div><span template="ngIf booleanCondition">hello</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent); getComponent().booleanCondition = false;
fixture.debugElement.componentInstance.booleanCondition = false;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(0);
.toEqual(0); expect(fixture.nativeElement).toHaveText('');
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.booleanCondition = true; getComponent().booleanCondition = true;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('hello');
expect(fixture.debugElement.nativeElement).toHaveText('hello');
fixture.debugElement.componentInstance.booleanCondition = false; getComponent().booleanCondition = false;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(0);
.toEqual(0); expect(fixture.nativeElement).toHaveText('');
expect(fixture.debugElement.nativeElement).toHaveText('');
})); }));
it('should handle nested if correctly', async(() => { it('should handle nested if correctly', async(() => {
const template = const template =
'<div><template [ngIf]="booleanCondition"><span *ngIf="nestedBooleanCondition">hello</span></template></div>'; '<div><template [ngIf]="booleanCondition"><span *ngIf="nestedBooleanCondition">hello</span></template></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.booleanCondition = false;
fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length)
.toEqual(0);
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.booleanCondition = true; getComponent().booleanCondition = false;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(0);
.toEqual(1); expect(fixture.nativeElement).toHaveText('');
expect(fixture.debugElement.nativeElement).toHaveText('hello');
fixture.debugElement.componentInstance.nestedBooleanCondition = false; getComponent().booleanCondition = true;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(0); expect(fixture.nativeElement).toHaveText('hello');
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.nestedBooleanCondition = true; getComponent().nestedBooleanCondition = false;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(0);
.toEqual(1); expect(fixture.nativeElement).toHaveText('');
expect(fixture.debugElement.nativeElement).toHaveText('hello');
fixture.debugElement.componentInstance.booleanCondition = false; getComponent().nestedBooleanCondition = true;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(0); expect(fixture.nativeElement).toHaveText('hello');
expect(fixture.debugElement.nativeElement).toHaveText('');
getComponent().booleanCondition = false;
fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(0);
expect(fixture.nativeElement).toHaveText('');
})); }));
it('should update several nodes with if', async(() => { it('should update several nodes with if', async(() => {
@ -110,59 +105,52 @@ export function main() {
'<span template="ngIf functionCondition(stringCondition, numberCondition)">helloFunction</span>' + '<span template="ngIf functionCondition(stringCondition, numberCondition)">helloFunction</span>' +
'</div>'; '</div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(3);
.toEqual(3); expect(getDOM().getText(fixture.nativeElement))
expect(getDOM().getText(fixture.debugElement.nativeElement))
.toEqual('helloNumberhelloStringhelloFunction'); .toEqual('helloNumberhelloStringhelloFunction');
fixture.debugElement.componentInstance.numberCondition = 0; getComponent().numberCondition = 0;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('helloString');
expect(fixture.debugElement.nativeElement).toHaveText('helloString');
fixture.debugElement.componentInstance.numberCondition = 1; getComponent().numberCondition = 1;
fixture.debugElement.componentInstance.stringCondition = 'bar'; getComponent().stringCondition = 'bar';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('helloNumber');
expect(fixture.debugElement.nativeElement).toHaveText('helloNumber');
})); }));
it('should not add the element twice if the condition goes from true to true (JS)', it('should not add the element twice if the condition goes from true to true (JS)',
async(() => { async(() => {
const template = '<div><span template="ngIf numberCondition">hello</span></div>'; const template = '<div><span template="ngIf numberCondition">hello</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length)
.toEqual(1);
expect(fixture.debugElement.nativeElement).toHaveText('hello');
fixture.debugElement.componentInstance.numberCondition = 2;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length) expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
.toEqual(1); expect(fixture.nativeElement).toHaveText('hello');
expect(fixture.debugElement.nativeElement).toHaveText('hello');
getComponent().numberCondition = 2;
fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.nativeElement, 'span').length).toEqual(1);
expect(fixture.nativeElement).toHaveText('hello');
})); }));
it('should not recreate the element if the condition goes from true to true (JS)', async(() => { it('should not recreate the element if the condition goes from true to true (JS)', async(() => {
const template = '<div><span template="ngIf numberCondition">hello</span></div>'; const template = '<div><span template="ngIf numberCondition">hello</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
getDOM().addClass(
getDOM().querySelector(fixture.debugElement.nativeElement, 'span'), 'foo');
fixture.debugElement.componentInstance.numberCondition = 2;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().hasClass( getDOM().addClass(getDOM().querySelector(fixture.nativeElement, 'span'), 'foo');
getDOM().querySelector(fixture.debugElement.nativeElement, 'span'), 'foo'))
getComponent().numberCondition = 2;
fixture.detectChanges();
expect(getDOM().hasClass(getDOM().querySelector(fixture.nativeElement, 'span'), 'foo'))
.toBe(true); .toBe(true);
})); }));
}); });
@ -170,16 +158,14 @@ export function main() {
@Component({selector: 'test-cmp', template: ''}) @Component({selector: 'test-cmp', template: ''})
class TestComponent { class TestComponent {
booleanCondition: boolean; booleanCondition: boolean = true;
nestedBooleanCondition: boolean; nestedBooleanCondition: boolean = true;
numberCondition: number; numberCondition: number = 1;
stringCondition: string; stringCondition: string = 'foo';
functionCondition: Function; functionCondition: Function = (s: any, n: any): boolean => s == 'foo' && n == 1;
constructor() { }
this.booleanCondition = true;
this.nestedBooleanCondition = true; function createTestComponent(template: string): ComponentFixture<TestComponent> {
this.numberCondition = 1; return TestBed.overrideComponent(TestComponent, {set: {template: template}})
this.stringCondition = 'foo'; .createComponent(TestComponent);
this.functionCondition = function(s: any, n: any): boolean { return s == 'foo' && n == 1; };
}
} }

View File

@ -8,11 +8,21 @@
import {CommonModule, NgLocalization} from '@angular/common'; import {CommonModule, NgLocalization} from '@angular/common';
import {Component, Injectable} from '@angular/core'; import {Component, Injectable} from '@angular/core';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
export function main() { export function main() {
describe('switch', () => { describe('switch', () => {
let fixture: ComponentFixture<any>;
function getComponent(): TestComponent { return fixture.componentInstance; }
function detectChangesAndExpectText<T>(text: string): void {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText(text);
}
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@ -23,104 +33,95 @@ export function main() {
}); });
it('should display the template according to the exact value', async(() => { it('should display the template according to the exact value', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngPlural]="switchValue">' + '<ul [ngPlural]="switchValue">' +
'<template ngPluralCase="=0"><li>you have no messages.</li></template>' + '<template ngPluralCase="=0"><li>you have no messages.</li></template>' +
'<template ngPluralCase="=1"><li>you have one message.</li></template>' + '<template ngPluralCase="=1"><li>you have one message.</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 0;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('you have no messages.');
fixture.debugElement.componentInstance.switchValue = 1; getComponent().switchValue = 0;
fixture.detectChanges(); detectChangesAndExpectText('you have no messages.');
expect(fixture.debugElement.nativeElement).toHaveText('you have one message.');
getComponent().switchValue = 1;
detectChangesAndExpectText('you have one message.');
})); }));
// https://github.com/angular/angular/issues/9868 // https://github.com/angular/angular/issues/9868
// https://github.com/angular/angular/issues/9882 // https://github.com/angular/angular/issues/9882
it('should not throw when ngPluralCase contains expressions', async(() => { it('should not throw when ngPluralCase contains expressions', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngPlural]="switchValue">' + '<ul [ngPlural]="switchValue">' +
'<template ngPluralCase="=0"><li>{{ switchValue }}</li></template>' + '<template ngPluralCase="=0"><li>{{ switchValue }}</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 0; getComponent().switchValue = 0;
expect(() => fixture.detectChanges()).not.toThrow(); expect(() => fixture.detectChanges()).not.toThrow();
})); }));
it('should be applicable to <ng-container> elements', async(() => { it('should be applicable to <ng-container> elements', async(() => {
var template = '<div>' + const template = '<div>' +
'<ng-container [ngPlural]="switchValue">' + '<ng-container [ngPlural]="switchValue">' +
'<template ngPluralCase="=0">you have no messages.</template>' + '<template ngPluralCase="=0">you have no messages.</template>' +
'<template ngPluralCase="=1">you have one message.</template>' + '<template ngPluralCase="=1">you have one message.</template>' +
'</ng-container></div>'; '</ng-container></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 0;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('you have no messages.');
fixture.debugElement.componentInstance.switchValue = 1; getComponent().switchValue = 0;
fixture.detectChanges(); detectChangesAndExpectText('you have no messages.');
expect(fixture.debugElement.nativeElement).toHaveText('you have one message.');
getComponent().switchValue = 1;
detectChangesAndExpectText('you have one message.');
})); }));
it('should display the template according to the category', async(() => { it('should display the template according to the category', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngPlural]="switchValue">' + '<ul [ngPlural]="switchValue">' +
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' + '<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
'<template ngPluralCase="many"><li>you have many messages.</li></template>' + '<template ngPluralCase="many"><li>you have many messages.</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 2;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('you have a few messages.');
fixture.debugElement.componentInstance.switchValue = 8; getComponent().switchValue = 2;
fixture.detectChanges(); detectChangesAndExpectText('you have a few messages.');
expect(fixture.debugElement.nativeElement).toHaveText('you have many messages.');
getComponent().switchValue = 8;
detectChangesAndExpectText('you have many messages.');
})); }));
it('should default to other when no matches are found', async(() => { it('should default to other when no matches are found', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngPlural]="switchValue">' + '<ul [ngPlural]="switchValue">' +
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' + '<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
'<template ngPluralCase="other"><li>default message.</li></template>' + '<template ngPluralCase="other"><li>default message.</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 100; getComponent().switchValue = 100;
fixture.detectChanges(); detectChangesAndExpectText('default message.');
expect(fixture.debugElement.nativeElement).toHaveText('default message.');
})); }));
it('should prioritize value matches over category matches', async(() => { it('should prioritize value matches over category matches', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngPlural]="switchValue">' + '<ul [ngPlural]="switchValue">' +
'<template ngPluralCase="few"><li>you have a few messages.</li></template>' + '<template ngPluralCase="few"><li>you have a few messages.</li></template>' +
'<template ngPluralCase="=2">you have two messages.</template>' + '<template ngPluralCase="=2">you have two messages.</template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.switchValue = 2;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('you have two messages.');
fixture.debugElement.componentInstance.switchValue = 3; getComponent().switchValue = 2;
fixture.detectChanges(); detectChangesAndExpectText('you have two messages.');
expect(fixture.debugElement.nativeElement).toHaveText('you have a few messages.');
getComponent().switchValue = 3;
detectChangesAndExpectText('you have a few messages.');
})); }));
}); });
} }
@ -131,6 +132,7 @@ class TestLocalization extends NgLocalization {
if (value > 1 && value < 4) { if (value > 1 && value < 4) {
return 'few'; return 'few';
} }
if (value >= 4 && value < 10) { if (value >= 4 && value < 10) {
return 'many'; return 'many';
} }
@ -143,3 +145,8 @@ class TestLocalization extends NgLocalization {
class TestComponent { class TestComponent {
switchValue: number = null; switchValue: number = null;
} }
function createTestComponent(template: string): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.createComponent(TestComponent);
}

View File

@ -10,69 +10,70 @@ import {CommonModule} from '@angular/common';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
function expectNativeEl(fixture: ComponentFixture<any>) {
return <any>expect(fixture.debugElement.children[0].nativeElement);
}
export function main() { export function main() {
describe('binding to CSS styles', () => { describe('NgStyle', () => {
let fixture: ComponentFixture<any>;
function getComponent(): TestComponent { return fixture.componentInstance; }
function expectNativeEl(fixture: ComponentFixture<any>): any {
return expect(fixture.debugElement.children[0].nativeElement);
}
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({declarations: [TestComponent], imports: [CommonModule]}); TestBed.configureTestingModule({declarations: [TestComponent], imports: [CommonModule]});
}); });
it('should add styles specified in an object literal', async(() => { it('should add styles specified in an object literal', async(() => {
var template = `<div [ngStyle]="{'max-width': '40px'}"></div>`; const template = `<div [ngStyle]="{'max-width': '40px'}"></div>`;
fixture = createTestComponent(template);
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'});
})); }));
it('should add and change styles specified in an object expression', async(() => { it('should add and change styles specified in an object expression', async(() => {
var template = `<div [ngStyle]="expr"></div>`; const template = `<div [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent); let expr: {[k: string]: string};
var expr: Map<string, any>;
fixture.debugElement.componentInstance.expr = {'max-width': '40px'}; getComponent().expr = {'max-width': '40px'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'});
expr = fixture.debugElement.componentInstance.expr; expr = getComponent().expr;
(expr as any)['max-width'] = '30%'; expr['max-width'] = '30%';
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '30%'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '30%'});
})); }));
it('should add and remove styles specified using style.unit notation', async(() => { it('should add and remove styles specified using style.unit notation', async(() => {
var template = `<div [ngStyle]="{'max-width.px': expr}"></div>`; const template = `<div [ngStyle]="{'max-width.px': expr}"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = '40'; getComponent().expr = '40';
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'});
fixture.debugElement.componentInstance.expr = null; getComponent().expr = null;
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).not.toHaveCssStyle('max-width'); expectNativeEl(fixture).not.toHaveCssStyle('max-width');
})); }));
it('should update styles using style.unit notation when unit changes', async(() => { it('should update styles using style.unit notation when unit changes', async(() => {
var template = `<div [ngStyle]="expr"></div>`; const template = `<div [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = {'max-width.px': '40'}; getComponent().expr = {'max-width.px': '40'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'});
fixture.debugElement.componentInstance.expr = {'max-width.em': '40'}; getComponent().expr = {'max-width.em': '40'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40em'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40em'});
})); }));
@ -81,9 +82,9 @@ export function main() {
it('should change styles specified in an object expression', async(() => { it('should change styles specified in an object expression', async(() => {
const template = `<div [ngStyle]="expr"></div>`; const template = `<div [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = { getComponent().expr = {
// height, width order is important here // height, width order is important here
height: '10px', height: '10px',
width: '10px' width: '10px'
@ -92,7 +93,7 @@ export function main() {
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'height': '10px', 'width': '10px'}); expectNativeEl(fixture).toHaveCssStyle({'height': '10px', 'width': '10px'});
fixture.debugElement.componentInstance.expr = { getComponent().expr = {
// width, height order is important here // width, height order is important here
width: '5px', width: '5px',
height: '5px', height: '5px',
@ -103,29 +104,29 @@ export function main() {
})); }));
it('should remove styles when deleting a key in an object expression', async(() => { it('should remove styles when deleting a key in an object expression', async(() => {
var template = `<div [ngStyle]="expr"></div>`; const template = `<div [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = {'max-width': '40px'}; getComponent().expr = {'max-width': '40px'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px'});
delete fixture.debugElement.componentInstance.expr['max-width']; delete getComponent().expr['max-width'];
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).not.toHaveCssStyle('max-width'); expectNativeEl(fixture).not.toHaveCssStyle('max-width');
})); }));
it('should co-operate with the style attribute', async(() => { it('should co-operate with the style attribute', async(() => {
var template = `<div style="font-size: 12px" [ngStyle]="expr"></div>`; const template = `<div style="font-size: 12px" [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = {'max-width': '40px'}; getComponent().expr = {'max-width': '40px'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px', 'font-size': '12px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px', 'font-size': '12px'});
delete fixture.debugElement.componentInstance.expr['max-width']; delete getComponent().expr['max-width'];
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).not.toHaveCssStyle('max-width'); expectNativeEl(fixture).not.toHaveCssStyle('max-width');
expectNativeEl(fixture).toHaveCssStyle({'font-size': '12px'}); expectNativeEl(fixture).toHaveCssStyle({'font-size': '12px'});
@ -133,15 +134,15 @@ export function main() {
it('should co-operate with the style.[styleName]="expr" special-case in the compiler', it('should co-operate with the style.[styleName]="expr" special-case in the compiler',
async(() => { async(() => {
var template = `<div [style.font-size.px]="12" [ngStyle]="expr"></div>`; const template = `<div [style.font-size.px]="12" [ngStyle]="expr"></div>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.debugElement.componentInstance.expr = {'max-width': '40px'}; getComponent().expr = {'max-width': '40px'};
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px', 'font-size': '12px'}); expectNativeEl(fixture).toHaveCssStyle({'max-width': '40px', 'font-size': '12px'});
delete fixture.debugElement.componentInstance.expr['max-width']; delete getComponent().expr['max-width'];
fixture.detectChanges(); fixture.detectChanges();
expectNativeEl(fixture).not.toHaveCssStyle('max-width'); expectNativeEl(fixture).not.toHaveCssStyle('max-width');
expectNativeEl(fixture).toHaveCssStyle({'font-size': '12px'}); expectNativeEl(fixture).toHaveCssStyle({'font-size': '12px'});
@ -153,3 +154,8 @@ export function main() {
class TestComponent { class TestComponent {
expr: any; expr: any;
} }
function createTestComponent(template: string): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.createComponent(TestComponent);
}

View File

@ -8,83 +8,86 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
export function main() { export function main() {
describe('switch', () => { describe('NgSwitch', () => {
let fixture: ComponentFixture<any>;
function getComponent(): TestComponent { return fixture.componentInstance; }
function detectChangesAndExpectText(text: string): void {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText(text);
}
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({declarations: [TestComponent], imports: [CommonModule]}); TestBed.configureTestingModule({
declarations: [TestComponent],
imports: [CommonModule],
});
}); });
describe('switch value changes', () => { describe('switch value changes', () => {
it('should switch amongst when values', async(() => { it('should switch amongst when values', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngSwitch]="switchValue">' + '<ul [ngSwitch]="switchValue">' +
'<template ngSwitchCase="a"><li>when a</li></template>' + '<template ngSwitchCase="a"><li>when a</li></template>' +
'<template ngSwitchCase="b"><li>when b</li></template>' + '<template ngSwitchCase="b"><li>when b</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.switchValue = 'a'; detectChangesAndExpectText('');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('when a');
fixture.debugElement.componentInstance.switchValue = 'b'; getComponent().switchValue = 'a';
fixture.detectChanges(); detectChangesAndExpectText('when a');
expect(fixture.debugElement.nativeElement).toHaveText('when b');
getComponent().switchValue = 'b';
detectChangesAndExpectText('when b');
})); }));
// TODO(robwormald): deprecate and remove // TODO(robwormald): deprecate and remove
it('should switch amongst when values using switchCase', async(() => { it('should switch amongst when values using switchCase', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngSwitch]="switchValue">' + '<ul [ngSwitch]="switchValue">' +
'<template ngSwitchCase="a"><li>when a</li></template>' + '<template ngSwitchCase="a"><li>when a</li></template>' +
'<template ngSwitchCase="b"><li>when b</li></template>' + '<template ngSwitchCase="b"><li>when b</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('');
fixture.debugElement.componentInstance.switchValue = 'a'; detectChangesAndExpectText('');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('when a');
fixture.debugElement.componentInstance.switchValue = 'b'; getComponent().switchValue = 'a';
fixture.detectChanges(); detectChangesAndExpectText('when a');
expect(fixture.debugElement.nativeElement).toHaveText('when b');
getComponent().switchValue = 'b';
detectChangesAndExpectText('when b');
})); }));
it('should switch amongst when values with fallback to default', async(() => { it('should switch amongst when values with fallback to default', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngSwitch]="switchValue">' + '<ul [ngSwitch]="switchValue">' +
'<li template="ngSwitchCase \'a\'">when a</li>' + '<li template="ngSwitchCase \'a\'">when a</li>' +
'<li template="ngSwitchDefault">when default</li>' + '<li template="ngSwitchDefault">when default</li>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent); detectChangesAndExpectText('when default');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('when default');
fixture.debugElement.componentInstance.switchValue = 'a'; getComponent().switchValue = 'a';
fixture.detectChanges(); detectChangesAndExpectText('when a');
expect(fixture.debugElement.nativeElement).toHaveText('when a');
fixture.debugElement.componentInstance.switchValue = 'b'; getComponent().switchValue = 'b';
fixture.detectChanges(); detectChangesAndExpectText('when default');
expect(fixture.debugElement.nativeElement).toHaveText('when default');
})); }));
it('should support multiple whens with the same value', async(() => { it('should support multiple whens with the same value', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngSwitch]="switchValue">' + '<ul [ngSwitch]="switchValue">' +
'<template ngSwitchCase="a"><li>when a1;</li></template>' + '<template ngSwitchCase="a"><li>when a1;</li></template>' +
'<template ngSwitchCase="b"><li>when b1;</li></template>' + '<template ngSwitchCase="b"><li>when b1;</li></template>' +
@ -94,53 +97,43 @@ export function main() {
'<template ngSwitchDefault><li>when default2;</li></template>' + '<template ngSwitchDefault><li>when default2;</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent); detectChangesAndExpectText('when default1;when default2;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('when default1;when default2;');
fixture.debugElement.componentInstance.switchValue = 'a'; getComponent().switchValue = 'a';
fixture.detectChanges(); detectChangesAndExpectText('when a1;when a2;');
expect(fixture.debugElement.nativeElement).toHaveText('when a1;when a2;');
fixture.debugElement.componentInstance.switchValue = 'b'; getComponent().switchValue = 'b';
fixture.detectChanges(); detectChangesAndExpectText('when b1;when b2;');
expect(fixture.debugElement.nativeElement).toHaveText('when b1;when b2;');
})); }));
}); });
describe('when values changes', () => { describe('when values changes', () => {
it('should switch amongst when values', async(() => { it('should switch amongst when values', async(() => {
var template = '<div>' + const template = '<div>' +
'<ul [ngSwitch]="switchValue">' + '<ul [ngSwitch]="switchValue">' +
'<template [ngSwitchCase]="when1"><li>when 1;</li></template>' + '<template [ngSwitchCase]="when1"><li>when 1;</li></template>' +
'<template [ngSwitchCase]="when2"><li>when 2;</li></template>' + '<template [ngSwitchCase]="when2"><li>when 2;</li></template>' +
'<template ngSwitchDefault><li>when default;</li></template>' + '<template ngSwitchDefault><li>when default;</li></template>' +
'</ul></div>'; '</ul></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent); getComponent().when1 = 'a';
fixture.debugElement.componentInstance.when1 = 'a'; getComponent().when2 = 'b';
fixture.debugElement.componentInstance.when2 = 'b'; getComponent().switchValue = 'a';
fixture.debugElement.componentInstance.switchValue = 'a'; detectChangesAndExpectText('when 1;');
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
fixture.debugElement.componentInstance.switchValue = 'b'; getComponent().switchValue = 'b';
fixture.detectChanges(); detectChangesAndExpectText('when 2;');
expect(fixture.debugElement.nativeElement).toHaveText('when 2;');
fixture.debugElement.componentInstance.switchValue = 'c'; getComponent().switchValue = 'c';
fixture.detectChanges(); detectChangesAndExpectText('when default;');
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
fixture.debugElement.componentInstance.when1 = 'c'; getComponent().when1 = 'c';
fixture.detectChanges(); detectChangesAndExpectText('when 1;');
expect(fixture.debugElement.nativeElement).toHaveText('when 1;');
fixture.debugElement.componentInstance.when1 = 'd'; getComponent().when1 = 'd';
fixture.detectChanges(); detectChangesAndExpectText('when default;');
expect(fixture.debugElement.nativeElement).toHaveText('when default;');
})); }));
}); });
}); });
@ -148,13 +141,12 @@ export function main() {
@Component({selector: 'test-cmp', template: ''}) @Component({selector: 'test-cmp', template: ''})
class TestComponent { class TestComponent {
switchValue: any; switchValue: any = null;
when1: any; when1: any = null;
when2: any; when2: any = null;
}
constructor() {
this.switchValue = null; function createTestComponent(template: string): ComponentFixture<TestComponent> {
this.when1 = null; return TestBed.overrideComponent(TestComponent, {set: {template: template}})
this.when2 = null; .createComponent(TestComponent);
}
} }

View File

@ -8,155 +8,140 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component, ContentChildren, Directive, NO_ERRORS_SCHEMA, QueryList, TemplateRef} from '@angular/core'; import {Component, ContentChildren, Directive, NO_ERRORS_SCHEMA, QueryList, TemplateRef} from '@angular/core';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
export function main() { export function main() {
describe('insert', () => { describe('NgTemplateOutlet', () => {
let fixture: ComponentFixture<any>;
function setTplRef(value: any): void { fixture.componentInstance.currentTplRef = value; }
function detectChangesAndExpectText(text: string): void {
fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText(text);
}
afterEach(() => { fixture = null; });
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule( TestBed.configureTestingModule({
{declarations: [TestComponent, CaptureTplRefs], imports: [CommonModule]}); declarations: [
TestComponent,
CaptureTplRefs,
],
imports: [CommonModule],
});
}); });
it('should do nothing if templateRef is null', async(() => { it('should do nothing if templateRef is null', async(() => {
const template = `<template [ngTemplateOutlet]="null"></template>`; const template = `<template [ngTemplateOutlet]="null"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}); fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); detectChangesAndExpectText('');
expect(fixture.nativeElement).toHaveText('');
})); }));
it('should insert content specified by TemplateRef', async(() => { it('should insert content specified by TemplateRef', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`; `<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent); detectChangesAndExpectText('');
fixture.detectChanges(); const refs = fixture.debugElement.children[0].references['refs'];
expect(fixture.nativeElement).toHaveText('');
var refs = fixture.debugElement.children[0].references['refs']; setTplRef(refs.tplRefs.first);
detectChangesAndExpectText('foo');
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('foo');
})); }));
it('should clear content if TemplateRef becomes null', async(() => { it('should clear content if TemplateRef becomes null', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`; `<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
var refs = fixture.debugElement.children[0].references['refs']; const refs = fixture.debugElement.children[0].references['refs'];
fixture.componentInstance.currentTplRef = refs.tplRefs.first; setTplRef(refs.tplRefs.first);
fixture.detectChanges(); detectChangesAndExpectText('foo');
expect(fixture.nativeElement).toHaveText('foo');
fixture.componentInstance.currentTplRef = null; setTplRef(null);
fixture.detectChanges(); detectChangesAndExpectText('');
expect(fixture.nativeElement).toHaveText('');
})); }));
it('should swap content if TemplateRef changes', async(() => { it('should swap content if TemplateRef changes', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template>foo</template><template>bar</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`; `<tpl-refs #refs="tplRefs"><template>foo</template><template>bar</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
var refs = fixture.debugElement.children[0].references['refs']; const refs = fixture.debugElement.children[0].references['refs'];
fixture.componentInstance.currentTplRef = refs.tplRefs.first; setTplRef(refs.tplRefs.first);
fixture.detectChanges(); detectChangesAndExpectText('foo');
expect(fixture.nativeElement).toHaveText('foo');
fixture.componentInstance.currentTplRef = refs.tplRefs.last; setTplRef(refs.tplRefs.last);
fixture.detectChanges(); detectChangesAndExpectText('bar');
expect(fixture.nativeElement).toHaveText('bar');
})); }));
it('should display template if context is null', async(() => { it('should display template if context is null', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="null"></template>`; `<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="null"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}); detectChangesAndExpectText('');
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); const refs = fixture.debugElement.children[0].references['refs'];
expect(fixture.nativeElement).toHaveText('');
var refs = fixture.debugElement.children[0].references['refs']; setTplRef(refs.tplRefs.first);
detectChangesAndExpectText('foo');
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('foo');
})); }));
it('should reflect initial context and changes', async(() => { it('should reflect initial context and changes', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template let-foo="foo"><span>{{foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`; `<tpl-refs #refs="tplRefs"><template let-foo="foo"><span>{{foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
var refs = fixture.debugElement.children[0].references['refs'];
fixture.componentInstance.currentTplRef = refs.tplRefs.first;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('bar');
const refs = fixture.debugElement.children[0].references['refs'];
setTplRef(refs.tplRefs.first);
detectChangesAndExpectText('bar');
fixture.componentInstance.context.foo = 'alter-bar'; fixture.componentInstance.context.foo = 'alter-bar';
fixture.detectChanges(); detectChangesAndExpectText('alter-bar');
expect(fixture.debugElement.nativeElement).toHaveText('alter-bar');
})); }));
it('should reflect user defined $implicit property in the context', async(() => { it('should reflect user defined $implicit property in the context', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template let-ctx><span>{{ctx.foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`; `<tpl-refs #refs="tplRefs"><template let-ctx><span>{{ctx.foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
var refs = fixture.debugElement.children[0].references['refs']; const refs = fixture.debugElement.children[0].references['refs'];
fixture.componentInstance.currentTplRef = refs.tplRefs.first; setTplRef(refs.tplRefs.first);
fixture.componentInstance.context = {$implicit: fixture.componentInstance.context}; fixture.componentInstance.context = {$implicit: fixture.componentInstance.context};
fixture.detectChanges(); detectChangesAndExpectText('bar');
expect(fixture.debugElement.nativeElement).toHaveText('bar');
})); }));
it('should reflect context re-binding', async(() => { it('should reflect context re-binding', async(() => {
const template = const template =
`<tpl-refs #refs="tplRefs"><template let-shawshank="shawshank"><span>{{shawshank}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`; `<tpl-refs #refs="tplRefs"><template let-shawshank="shawshank"><span>{{shawshank}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}}) fixture = createTestComponent(template);
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
var refs = fixture.debugElement.children[0].references['refs']; const refs = fixture.debugElement.children[0].references['refs'];
fixture.componentInstance.currentTplRef = refs.tplRefs.first; setTplRef(refs.tplRefs.first);
fixture.componentInstance.context = {shawshank: 'brooks'}; fixture.componentInstance.context = {shawshank: 'brooks'};
fixture.detectChanges(); detectChangesAndExpectText('brooks');
expect(fixture.debugElement.nativeElement).toHaveText('brooks');
fixture.componentInstance.context = {shawshank: 'was here'}; fixture.componentInstance.context = {shawshank: 'was here'};
fixture.detectChanges(); detectChangesAndExpectText('was here');
expect(fixture.debugElement.nativeElement).toHaveText('was here');
})); }));
}); });
} }
@ -172,3 +157,9 @@ class TestComponent {
currentTplRef: TemplateRef<any>; currentTplRef: TemplateRef<any>;
context: any = {foo: 'bar'}; context: any = {foo: 'bar'};
} }
function createTestComponent(template: string): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(TestComponent);
}

View File

@ -8,7 +8,7 @@
import {Component, Directive} from '@angular/core'; import {Component, Directive} from '@angular/core';
import {ElementRef} from '@angular/core/src/linker/element_ref'; import {ElementRef} from '@angular/core/src/linker/element_ref';
import {TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
@ -22,31 +22,29 @@ export function main() {
}); });
it('should not interpolate children', async(() => { it('should not interpolate children', async(() => {
var template = '<div>{{text}}<span ngNonBindable>{{text}}</span></div>'; const template = '<div>{{text}}<span ngNonBindable>{{text}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); const fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement).toHaveText('foo{{text}}'); expect(fixture.nativeElement).toHaveText('foo{{text}}');
})); }));
it('should ignore directives on child nodes', async(() => { it('should ignore directives on child nodes', async(() => {
var template = '<div ngNonBindable><span id=child test-dec>{{text}}</span></div>'; const template = '<div ngNonBindable><span id=child test-dec>{{text}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); const fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
// We must use getDOM().querySelector instead of fixture.query here // We must use getDOM().querySelector instead of fixture.query here
// since the elements inside are not compiled. // since the elements inside are not compiled.
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child'); const span = getDOM().querySelector(fixture.nativeElement, '#child');
expect(getDOM().hasClass(span, 'compiled')).toBeFalsy(); expect(getDOM().hasClass(span, 'compiled')).toBeFalsy();
})); }));
it('should trigger directives on the same node', async(() => { it('should trigger directives on the same node', async(() => {
var template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>'; const template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}}); const fixture = createTestComponent(template);
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); fixture.detectChanges();
var span = getDOM().querySelector(fixture.debugElement.nativeElement, '#child'); const span = getDOM().querySelector(fixture.nativeElement, '#child');
expect(getDOM().hasClass(span, 'compiled')).toBeTruthy(); expect(getDOM().hasClass(span, 'compiled')).toBeTruthy();
})); }));
}); });
@ -62,3 +60,8 @@ class TestComponent {
text: string; text: string;
constructor() { this.text = 'foo'; } constructor() { this.text = 'foo'; }
} }
function createTestComponent(template: string): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.createComponent(TestComponent);
}