From 917d43e108a5ed8bc458cd70c6a9312aa9757ed8 Mon Sep 17 00:00:00 2001 From: Julie Ralph Date: Fri, 19 Aug 2016 15:46:40 -0700 Subject: [PATCH] refactor(tests): add ComponentFixture tests (#10910) Remove old TestComponentBuilder tests, and keep relevant ComponentFixture tests as component_fixture_spec. --- .../test/test_component_builder_spec.ts | 614 ------------------ .../core/test/component_fixture_spec.ts | 324 +++++++++ .../test/testing_public_browser_spec.ts | 5 +- 3 files changed, 327 insertions(+), 616 deletions(-) delete mode 100644 modules/@angular/compiler/test/test_component_builder_spec.ts create mode 100644 modules/@angular/core/test/component_fixture_spec.ts diff --git a/modules/@angular/compiler/test/test_component_builder_spec.ts b/modules/@angular/compiler/test/test_component_builder_spec.ts deleted file mode 100644 index 79d581a138..0000000000 --- a/modules/@angular/compiler/test/test_component_builder_spec.ts +++ /dev/null @@ -1,614 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {NgIf} from '@angular/common'; -import {Component, Injectable, Input, NgModule, Pipe} from '@angular/core'; -import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, withModule} from '@angular/core/testing'; -import {AsyncTestCompleter, TestComponentBuilder, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; -import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; -import {expect} from '@angular/platform-browser/testing/matchers'; - -import {ViewMetadata} from '../core_private'; - -@Component( - {selector: 'child-comp', template: `Original {{childBinding}}`, directives: []}) -@Injectable() -class ChildComp { - childBinding: string; - constructor() { this.childBinding = 'Child'; } -} - -@Component({selector: 'child-comp', template: `Mock`}) -@Injectable() -class MockChildComp { -} - -@Component({ - selector: 'parent-comp', - template: `Parent()`, - directives: [ChildComp] -}) -@Injectable() -class ParentComp { -} - -@Component({ - selector: 'my-if-comp', - template: `MyIf(More)`, - directives: [NgIf] -}) -@Injectable() -class MyIfComp { - showMore: boolean = false; -} - -@Component({selector: 'child-child-comp', template: `ChildChild`}) -@Injectable() -class ChildChildComp { -} - -@Component({ - selector: 'child-comp', - template: `Original {{childBinding}}()`, - directives: [ChildChildComp] -}) -@Injectable() -class ChildWithChildComp { - childBinding: string; - constructor() { this.childBinding = 'Child'; } -} - -@Component({selector: 'child-child-comp', template: `ChildChild Mock`}) -@Injectable() -class MockChildChildComp { -} - -@Component({selector: 'autodetect-comp', template: `{{text}}`}) -class AutoDetectComp { - text: string = '1'; - - click() { this.text += '1'; } -} - -@Component({selector: 'async-comp', template: `{{text}}`}) -class AsyncComp { - text: string = '1'; - - click() { - Promise.resolve(null).then((_) => { this.text += '1'; }); - } -} - -@Component({selector: 'async-child-comp', template: '{{localText}}'}) -class AsyncChildComp { - localText: string = ''; - - @Input() - set text(value: string) { - Promise.resolve(null).then((_) => { this.localText = value; }); - } -} - -@Component({ - selector: 'async-change-comp', - template: ``, - directives: [AsyncChildComp] -}) -class AsyncChangeComp { - text: string = '1'; - - click() { this.text += '1'; } -} - -@Component({selector: 'async-timeout-comp', template: `{{text}}`}) -class AsyncTimeoutComp { - text: string = '1'; - - click() { - setTimeout(() => { this.text += '1'; }, 10); - } -} - -@Component( - {selector: 'nested-async-timeout-comp', template: `{{text}}`}) -class NestedAsyncTimeoutComp { - text: string = '1'; - - click() { - setTimeout(() => { setTimeout(() => { this.text += '1'; }, 10); }, 10); - } -} - -class FancyService { - value: string = 'real value'; -} - -class MockFancyService extends FancyService { - value: string = 'mocked out value'; -} - -@Component({ - selector: 'my-service-comp', - providers: [FancyService], - template: `injected value: {{fancyService.value}}` -}) -class TestBindingsComp { - constructor(private fancyService: FancyService) {} -} - -@Component({ - selector: 'my-service-comp', - viewProviders: [FancyService], - template: `injected value: {{fancyService.value}}` -}) -class TestViewBindingsComp { - constructor(private fancyService: FancyService) {} -} - -@Component({selector: 'li1', template: `One`}) -class ListDir1 { -} - -@Component({selector: 'li1', template: `Alternate One`}) -class ListDir1Alt { -} - -@Component({selector: 'li2', template: `Two`}) -class ListDir2 { -} - -const LIST_CHILDREN = [ListDir1, ListDir2]; - -@Component({ - selector: 'directive-list-comp', - template: `()()`, - directives: [LIST_CHILDREN] -}) -class DirectiveListComp { -} - - -export function main() { - describe('test component builder', function() { - it('should instantiate a component with valid DOM', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(ChildComp).then((componentFixture) => { - componentFixture.detectChanges(); - - expect(componentFixture.nativeElement).toHaveText('Original Child'); - async.done(); - }); - })); - - it('should allow changing members of the component', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(MyIfComp).then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('MyIf()'); - - componentFixture.componentInstance.showMore = true; - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('MyIf(More)'); - - async.done(); - }); - })); - - it('should override a template', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideTemplate(MockChildComp, 'Mock') - .createAsync(MockChildComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('Mock'); - - async.done(); - }); - })); - - it('should override a view', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideView( - ChildComp, - new ViewMetadata({template: 'Modified {{childBinding}}'})) - .createAsync(ChildComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('Modified Child'); - - async.done(); - }); - })); - - it('should override component dependencies', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideDirective(ParentComp, ChildComp, MockChildComp) - .createAsync(ParentComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('Parent(Mock)'); - - async.done(); - }); - })); - - it('should override items from a list', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideDirective(DirectiveListComp, ListDir1, ListDir1Alt) - .createAsync(DirectiveListComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('(Alternate One)(Two)'); - - async.done(); - }); - })); - - it('should override child component\'s dependencies', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp) - .overrideDirective(ChildWithChildComp, ChildChildComp, MockChildChildComp) - .createAsync(ParentComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement) - .toHaveText('Parent(Original Child(ChildChild Mock))'); - - async.done(); - }); - })); - - it('should override a provider', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideProviders( - TestBindingsComp, [{provide: FancyService, useClass: MockFancyService}]) - .createAsync(TestBindingsComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement) - .toHaveText('injected value: mocked out value'); - async.done(); - }); - })); - - - it('should override a viewBinding', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.overrideViewProviders( - TestViewBindingsComp, [{provide: FancyService, useClass: MockFancyService}]) - .createAsync(TestViewBindingsComp) - .then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement) - .toHaveText('injected value: mocked out value'); - async.done(); - }); - })); - - it('should create components synchronously', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - let componentFixture = - tcb.overrideTemplate(MockChildComp, 'Mock').createSync(MockChildComp); - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('Mock'); - })); - - describe('ComponentFixture', () => { - it('should auto detect changes if autoDetectChanges is called', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AutoDetectComp).then((componentFixture) => { - expect(componentFixture.ngZone).not.toBeNull(); - componentFixture.autoDetectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - - expect(componentFixture.isStable()).toBe(true); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - })); - - it('should auto detect changes if ComponentFixtureAutoDetect is provided as true', - withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}) - .inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AutoDetectComp).then((componentFixture) => { - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - })); - - it('should signal through whenStable when the fixture is stable (autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncComp).then((componentFixture) => { - componentFixture.autoDetectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become stable - // before checking for new value. - expect(componentFixture.isStable()).toBe(false); - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should signal through isStable when the fixture is stable (no autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncComp).then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become stable - // before checking. - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should wait for macroTask(setTimeout) while checking for whenStable ' + - '(autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncTimeoutComp).then((componentFixture) => { - componentFixture.autoDetectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become - // stable before checking for new value. - expect(componentFixture.isStable()).toBe(false); - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should wait for macroTask(setTimeout) while checking for whenStable ' + - '(no autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncTimeoutComp).then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become - // stable before checking for new value. - expect(componentFixture.isStable()).toBe(false); - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' + - '(autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(NestedAsyncTimeoutComp).then((componentFixture) => { - componentFixture.autoDetectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become - // stable before checking for new value. - expect(componentFixture.isStable()).toBe(false); - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' + - '(no autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(NestedAsyncTimeoutComp).then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - expect(componentFixture.nativeElement).toHaveText('1'); - - // Component is updated asynchronously. Wait for the fixture to become - // stable before checking for new value. - expect(componentFixture.isStable()).toBe(false); - componentFixture.whenStable().then((waited) => { - expect(waited).toBe(true); - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - })); - - it('should stabilize after async task in change detection (autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncChangeComp).then((componentFixture) => { - componentFixture.autoDetectChanges(); - componentFixture.whenStable().then((_) => { - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - - componentFixture.whenStable().then((_) => { - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - }); - })); - - it('should stabilize after async task in change detection(no autoDetectChanges)', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(AsyncChangeComp).then((componentFixture) => { - componentFixture.detectChanges(); - componentFixture.whenStable().then((_) => { - // Run detectChanges again so that stabilized value is reflected in the - // DOM. - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('1'); - - let element = componentFixture.debugElement.children[0]; - dispatchEvent(element.nativeElement, 'click'); - componentFixture.detectChanges(); - - componentFixture.whenStable().then((_) => { - // Run detectChanges again so that stabilized value is reflected in - // the DOM. - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('11'); - async.done(); - }); - }); - }); - })); - - describe('No NgZone', () => { - beforeEachProviders(() => [{provide: ComponentFixtureNoNgZone, useValue: true}]); - - it('calling autoDetectChanges raises an error', () => { - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - tcb.createAsync(ChildComp).then((componentFixture) => { - expect(() => { componentFixture.autoDetectChanges(); }) - .toThrow( - 'Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set!!'); - async.done(); - }); - }); - }); - - it('should instantiate a component with valid DOM', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(ChildComp).then((componentFixture) => { - expect(componentFixture.ngZone).toBeNull(); - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('Original Child'); - async.done(); - }); - })); - - it('should allow changing members of the component', - inject( - [TestComponentBuilder, AsyncTestCompleter], - (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { - - tcb.createAsync(MyIfComp).then((componentFixture) => { - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('MyIf()'); - - componentFixture.componentInstance.showMore = true; - componentFixture.detectChanges(); - expect(componentFixture.nativeElement).toHaveText('MyIf(More)'); - - async.done(); - }); - })); - }); - - }); - }); -} diff --git a/modules/@angular/core/test/component_fixture_spec.ts b/modules/@angular/core/test/component_fixture_spec.ts new file mode 100644 index 0000000000..da20c00637 --- /dev/null +++ b/modules/@angular/core/test/component_fixture_spec.ts @@ -0,0 +1,324 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Component, Injectable, Input} from '@angular/core'; +import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBed, async, withModule} from '@angular/core/testing'; +import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; +import {expect} from '@angular/platform-browser/testing/matchers'; + +@Component({selector: 'simple-comp', template: `Original {{simpleBinding}}`}) +@Injectable() +class SimpleComp { + simpleBinding: string; + constructor() { this.simpleBinding = 'Simple'; } +} + +@Component({ + selector: 'my-if-comp', + template: `MyIf(More)`, +}) +@Injectable() +class MyIfComp { + showMore: boolean = false; +} + +@Component({selector: 'autodetect-comp', template: `{{text}}`}) +class AutoDetectComp { + text: string = '1'; + + click() { this.text += '1'; } +} + +@Component({selector: 'async-comp', template: `{{text}}`}) +class AsyncComp { + text: string = '1'; + + click() { + Promise.resolve(null).then((_) => { this.text += '1'; }); + } +} + +@Component({selector: 'async-child-comp', template: '{{localText}}'}) +class AsyncChildComp { + localText: string = ''; + + @Input() + set text(value: string) { + Promise.resolve(null).then((_) => { this.localText = value; }); + } +} + +@Component({ + selector: 'async-change-comp', + template: `` +}) +class AsyncChangeComp { + text: string = '1'; + + click() { this.text += '1'; } +} + +@Component({selector: 'async-timeout-comp', template: `{{text}}`}) +class AsyncTimeoutComp { + text: string = '1'; + + click() { + setTimeout(() => { this.text += '1'; }, 10); + } +} + +@Component( + {selector: 'nested-async-timeout-comp', template: `{{text}}`}) +class NestedAsyncTimeoutComp { + text: string = '1'; + + click() { + setTimeout(() => { setTimeout(() => { this.text += '1'; }, 10); }, 10); + } +} + +export function main() { + describe('ComponentFixture', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AutoDetectComp, AsyncComp, AsyncTimeoutComp, NestedAsyncTimeoutComp, AsyncChangeComp, + MyIfComp, SimpleComp, AsyncChildComp + ] + }); + })); + + it('should auto detect changes if autoDetectChanges is called', () => { + + let componentFixture = TestBed.createComponent(AutoDetectComp); + expect(componentFixture.ngZone).not.toBeNull(); + componentFixture.autoDetectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + + expect(componentFixture.isStable()).toBe(true); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + + it('should auto detect changes if ComponentFixtureAutoDetect is provided as true', + withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}, () => { + + let componentFixture = TestBed.createComponent(AutoDetectComp); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + + expect(componentFixture.nativeElement).toHaveText('11'); + })); + + fit('should signal through whenStable when the fixture is stable (autoDetectChanges)', + async(() => { + let componentFixture = TestBed.createComponent(AsyncComp); + componentFixture.autoDetectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become stable + // before checking for new value. + expect(componentFixture.isStable()).toBe(false); + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should signal through isStable when the fixture is stable (no autoDetectChanges)', + async(() => { + let componentFixture = TestBed.createComponent(AsyncComp); + + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become stable + // before checking. + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should wait for macroTask(setTimeout) while checking for whenStable ' + + '(autoDetectChanges)', + async(() => { + let componentFixture = TestBed.createComponent(AsyncTimeoutComp); + componentFixture.autoDetectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become + // stable before checking for new value. + expect(componentFixture.isStable()).toBe(false); + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should wait for macroTask(setTimeout) while checking for whenStable ' + + '(no autoDetectChanges)', + async(() => { + + let componentFixture = TestBed.createComponent(AsyncTimeoutComp); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become + // stable before checking for new value. + expect(componentFixture.isStable()).toBe(false); + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' + + '(autoDetectChanges)', + async(() => { + + let componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp); + + componentFixture.autoDetectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become + // stable before checking for new value. + expect(componentFixture.isStable()).toBe(false); + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' + + '(no autoDetectChanges)', + async(() => { + + let componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + expect(componentFixture.nativeElement).toHaveText('1'); + + // Component is updated asynchronously. Wait for the fixture to become + // stable before checking for new value. + expect(componentFixture.isStable()).toBe(false); + componentFixture.whenStable().then((waited) => { + expect(waited).toBe(true); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + })); + + it('should stabilize after async task in change detection (autoDetectChanges)', async(() => { + + let componentFixture = TestBed.createComponent(AsyncChangeComp); + + componentFixture.autoDetectChanges(); + componentFixture.whenStable().then((_) => { + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + + componentFixture.whenStable().then( + (_) => { expect(componentFixture.nativeElement).toHaveText('11'); }); + }); + })); + + it('should stabilize after async task in change detection(no autoDetectChanges)', async(() => { + + let componentFixture = TestBed.createComponent(AsyncChangeComp); + componentFixture.detectChanges(); + componentFixture.whenStable().then((_) => { + // Run detectChanges again so that stabilized value is reflected in the + // DOM. + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('1'); + + let element = componentFixture.debugElement.children[0]; + dispatchEvent(element.nativeElement, 'click'); + componentFixture.detectChanges(); + + componentFixture.whenStable().then((_) => { + // Run detectChanges again so that stabilized value is reflected in + // the DOM. + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('11'); + }); + }); + })); + + describe('No NgZone', () => { + beforeEach(() => { + TestBed.configureTestingModule( + {providers: [{provide: ComponentFixtureNoNgZone, useValue: true}]}); + }); + + it('calling autoDetectChanges raises an error', () => { + + let componentFixture = TestBed.createComponent(SimpleComp); + expect(() => { + componentFixture.autoDetectChanges(); + }).toThrowError(/Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set/); + }); + + it('should instantiate a component with valid DOM', async(() => { + + let componentFixture = TestBed.createComponent(SimpleComp); + + expect(componentFixture.ngZone).toBeNull(); + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('Original Simple'); + })); + + it('should allow changing members of the component', async(() => { + + let componentFixture = TestBed.createComponent(MyIfComp); + + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('MyIf()'); + + componentFixture.componentInstance.showMore = true; + componentFixture.detectChanges(); + expect(componentFixture.nativeElement).toHaveText('MyIf(More)'); + + })); + }); + + }); +} diff --git a/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts b/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts index dac79a62dd..03a26ab5ba 100644 --- a/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts +++ b/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts @@ -118,7 +118,7 @@ export function main() { }, 10000); }); - describe('test component builder', function() { + describe('TestBed createComponent', function() { it('should allow an external templateUrl', async(() => { TestBed.configureTestingModule({declarations: [ExternalTemplateComp]}); TestBed.compileComponents().then(() => { @@ -128,7 +128,8 @@ export function main() { .toEqual('from external template\n'); }); }), - 10000); // Long timeout here because this test makes an actual ResourceLoader, and is slow + 10000); // Long timeout here because this test makes an actual ResourceLoader request, and + // is slow // on Edge. }); });