feat(core): update reference and doc to change `async` to `waitAsync`. (#37583)

The last commit change `async` to `waitForAsync`.
This commit update all usages in the code and also update aio doc.

PR Close #37583
This commit is contained in:
JiaLiPassion 2020-08-01 04:43:18 +09:00 committed by Alex Rickabaugh
parent 8f074296c2
commit 8fbf40bf40
78 changed files with 1363 additions and 1368 deletions

View File

@ -1,31 +1,31 @@
import { TestBed, async } from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { TemplateModule } from './template/template.module';
import { ReactiveModule } from './reactive/reactive.module';
import { TemplateModule } from './template/template.module';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveModule, TemplateModule],
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [ReactiveModule, TemplateModule],
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
expect(app).toBeTruthy();
}));
it('should render title', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
}));
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
}));
});

View File

@ -1,19 +1,18 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
describe('Favorite Color Component', () => {
let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule ],
declarations: [ FavoriteColorComponent ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule(
{imports: [ReactiveFormsModule], declarations: [FavoriteColorComponent]})
.compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
describe('FavoriteColorComponent', () => {
let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ FormsModule ],
declarations: [ FavoriteColorComponent ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({imports: [FormsModule], declarations: [FavoriteColorComponent]})
.compileComponents();
}));
beforeEach(() => {
@ -28,29 +25,29 @@ describe('FavoriteColorComponent', () => {
// #docregion model-to-view
it('should update the favorite color on the input field', fakeAsync(() => {
component.favoriteColor = 'Blue';
component.favoriteColor = 'Blue';
fixture.detectChanges();
fixture.detectChanges();
tick();
tick();
const input = fixture.nativeElement.querySelector('input');
const input = fixture.nativeElement.querySelector('input');
expect(input.value).toBe('Blue');
}));
expect(input.value).toBe('Blue');
}));
// #enddocregion model-to-view
// #docregion view-to-model
it('should update the favorite color in the component', fakeAsync(() => {
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
input.value = 'Red';
input.dispatchEvent(event);
input.value = 'Red';
input.dispatchEvent(event);
fixture.detectChanges();
fixture.detectChanges();
expect(component.favoriteColor).toEqual('Red');
}));
expect(component.favoriteColor).toEqual('Red');
}));
// #enddocregion view-to-model
});

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MyLibComponent } from './my-lib.component';
@ -6,11 +6,8 @@ describe('MyLibComponent', () => {
let component: MyLibComponent;
let fixture: ComponentFixture<MyLibComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyLibComponent ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [MyLibComponent]}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { AppComponent } from './app.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
let de: DebugElement;
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AppComponent ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [AppComponent]}).compileComponents();
}));
beforeEach(() => {
@ -22,12 +19,11 @@ describe('AppComponent', () => {
de = fixture.debugElement.query(By.css('h1'));
});
it('should create component', () => expect(comp).toBeDefined() );
it('should create component', () => expect(comp).toBeDefined());
it('should have expected <h1> text', () => {
fixture.detectChanges();
const h1 = de.nativeElement;
expect(h1.textContent).toMatch(/angular/i,
'<h1> should say something about "Angular"');
expect(h1.textContent).toMatch(/angular/i, '<h1> should say something about "Angular"');
});
});

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion
import { TestBed, async } from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
// #enddocregion
import { AppComponent } from './app-initial.component';
/*
@ -12,29 +12,29 @@ describe('AppComponent', () => {
*/
describe('AppComponent (initial CLI version)', () => {
// #docregion
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
}));
});
// #enddocregion
@ -43,16 +43,13 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture } from '@angular/core/testing';
describe('AppComponent (initial CLI version - as it should be)', () => {
let app: AppComponent;
let de: DebugElement;
let fixture: ComponentFixture<AppComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
declarations: [AppComponent],
});
fixture = TestBed.createComponent(AppComponent);
@ -70,7 +67,6 @@ describe('AppComponent (initial CLI version - as it should be)', () => {
it('should render title in an h1 tag', () => {
fixture.detectChanges();
expect(de.nativeElement.querySelector('h1').textContent)
.toContain('Welcome to app!');
expect(de.nativeElement.querySelector('h1').textContent).toContain('Welcome to app!');
});
});

View File

@ -1,7 +1,7 @@
// For more examples:
// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { asyncData } from '../testing';
@ -21,9 +21,9 @@ import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TwainService } from './twain/twain.service';
import { HeroService, TestHeroService } from './model/testing/test-hero.service';
import { TwainService } from './twain/twain.service';
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
@ -32,54 +32,51 @@ let router: Router;
let location: SpyLocation;
describe('AppComponent & RouterTestingModule', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
providers: [
{ provide: HeroService, useClass: TestHeroService }
]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
providers: [{provide: HeroService, useClass: TestHeroService}]
})
.compileComponents();
}));
it('should navigate to "Dashboard" immediately', fakeAsync(() => {
createComponent();
tick(); // wait for async data to arrive
expectPathToBe('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardComponent);
}));
createComponent();
tick(); // wait for async data to arrive
expectPathToBe('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardComponent);
}));
it('should navigate to "About" on click', fakeAsync(() => {
createComponent();
click(page.aboutLinkDe);
// page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom
createComponent();
click(page.aboutLinkDe);
// page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
it('should navigate to "About" w/ browser location URL change', fakeAsync(() => {
createComponent();
location.simulateHashChange('/about');
// location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
createComponent();
location.simulateHashChange('/about');
// location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
// Can't navigate to lazy loaded modules with this technique
xit('should navigate to "Heroes" on click (not working yet)', fakeAsync(() => {
createComponent();
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
}));
createComponent();
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
}));
});
@ -94,37 +91,37 @@ let loader: SpyNgModuleFactoryLoader;
///////// Can't get lazy loaded Heroes to work yet
xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
})
.compileComponents();
}));
beforeEach(fakeAsync(() => {
createComponent();
loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader;
loader.stubbedModules = { expected: HeroModule };
loader.stubbedModules = {expected: HeroModule};
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
}));
it('should navigate to "Heroes" on click', async(() => {
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
it('should navigate to "Heroes" on click', waitForAsync(() => {
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
it('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => {
location.go('/heroes');
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
location.go('/heroes');
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
});
////// Helpers /////////
@ -134,9 +131,9 @@ xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
* Wait a tick, then detect changes, and tick again
*/
function advance(): void {
tick(); // wait while navigating
fixture.detectChanges(); // update view
tick(); // wait for async data to arrive
tick(); // wait while navigating
fixture.detectChanges(); // update view
tick(); // wait for async data to arrive
}
function createComponent() {
@ -148,8 +145,8 @@ function createComponent() {
router = injector.get(Router);
router.initialNavigation();
spyOn(injector.get(TwainService), 'getQuote')
// fake fast async observable
.and.returnValue(asyncData('Test Quote'));
// fake fast async observable
.and.returnValue(asyncData('Test Quote'));
advance();
page = new Page();
@ -168,14 +165,14 @@ class Page {
constructor() {
const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
this.aboutLinkDe = links[2];
this.aboutLinkDe = links[2];
this.dashboardLinkDe = links[0];
this.heroesLinkDe = links[1];
this.heroesLinkDe = links[1];
// for debugging
this.comp = comp;
this.comp = comp;
this.fixture = fixture;
this.router = router;
this.router = router;
}
}

View File

@ -1,66 +1,70 @@
// #docplaster
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { RouterLinkDirectiveStub } from '../testing';
import { AppComponent } from './app.component';
// #docregion component-stubs
@Component({selector: 'app-banner', template: ''})
class BannerStubComponent {}
class BannerStubComponent {
}
@Component({selector: 'router-outlet', template: ''})
class RouterOutletStubComponent { }
class RouterOutletStubComponent {
}
@Component({selector: 'app-welcome', template: ''})
class WelcomeStubComponent {}
class WelcomeStubComponent {
}
// #enddocregion component-stubs
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
describe('AppComponent & TestModule', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// #docregion testbed-stubs
TestBed.configureTestingModule({
declarations: [
AppComponent,
RouterLinkDirectiveStub,
BannerStubComponent,
RouterOutletStubComponent,
WelcomeStubComponent
]
})
// #enddocregion testbed-stubs
.compileComponents().then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
TestBed
.configureTestingModule({
declarations: [
AppComponent, RouterLinkDirectiveStub, BannerStubComponent, RouterOutletStubComponent,
WelcomeStubComponent
]
})
// #enddocregion testbed-stubs
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
});
//////// Testing w/ NO_ERRORS_SCHEMA //////
describe('AppComponent & NO_ERRORS_SCHEMA', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// #docregion no-errors-schema, mixed-setup
TestBed.configureTestingModule({
declarations: [
AppComponent,
// #enddocregion no-errors-schema
BannerStubComponent,
// #docregion no-errors-schema
RouterLinkDirectiveStub
],
schemas: [ NO_ERRORS_SCHEMA ]
})
// #enddocregion no-errors-schema, mixed-setup
.compileComponents().then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
TestBed
.configureTestingModule({
declarations: [
AppComponent,
// #enddocregion no-errors-schema
BannerStubComponent,
// #docregion no-errors-schema
RouterLinkDirectiveStub
],
schemas: [NO_ERRORS_SCHEMA]
})
// #enddocregion no-errors-schema, mixed-setup
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
});
@ -72,30 +76,23 @@ import { AppModule } from './app.module';
import { AppRoutingModule } from './app-routing.module';
describe('AppComponent & AppModule', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({imports: [AppModule]})
beforeEach(async(() => {
// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(AppModule, {
remove: {imports: [AppRoutingModule]},
add: {declarations: [RouterLinkDirectiveStub, RouterOutletStubComponent]}
})
TestBed.configureTestingModule({
imports: [ AppModule ]
})
.compileComponents()
// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(AppModule, {
remove: {
imports: [ AppRoutingModule ]
},
add: {
declarations: [ RouterLinkDirectiveStub, RouterOutletStubComponent ]
}
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
@ -107,11 +104,10 @@ function tests() {
// #docregion test-setup
beforeEach(() => {
fixture.detectChanges(); // trigger initial data binding
fixture.detectChanges(); // trigger initial data binding
// find DebugElements with an attached RouterLinkStubDirective
linkDes = fixture.debugElement
.queryAll(By.directive(RouterLinkDirectiveStub));
linkDes = fixture.debugElement.queryAll(By.directive(RouterLinkDirectiveStub));
// get attached link directive instances
// using each DebugElement's injector
@ -132,8 +128,8 @@ function tests() {
});
it('can click Heroes link in template', () => {
const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive
const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive
expect(heroesLink.navigatedTo).toBeNull('should not have navigated yet');

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion import-async
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
// #enddocregion import-async
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
@ -14,11 +14,12 @@ describe('BannerComponent (external files)', () => {
describe('Two beforeEach', () => {
// #docregion async-before-each
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
})
.compileComponents(); // compile template and css
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [BannerComponent],
})
.compileComponents(); // compile template and css
}));
// #enddocregion async-before-each
@ -26,7 +27,7 @@ describe('BannerComponent (external files)', () => {
// #docregion sync-before-each
beforeEach(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance; // BannerComponent test instance
component = fixture.componentInstance; // BannerComponent test instance
h1 = fixture.nativeElement.querySelector('h1');
});
// #enddocregion sync-before-each
@ -36,16 +37,17 @@ describe('BannerComponent (external files)', () => {
describe('One beforeEach', () => {
// #docregion one-before-each
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
h1 = fixture.nativeElement.querySelector('h1');
});
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [BannerComponent],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
h1 = fixture.nativeElement.querySelector('h1');
});
}));
// #enddocregion one-before-each
@ -69,4 +71,3 @@ describe('BannerComponent (external files)', () => {
});
}
});

View File

@ -1,14 +1,16 @@
// #docplaster
// #docregion import-by
import { By } from '@angular/platform-browser';
// #enddocregion import-by
// #docregion import-debug-element
import { DebugElement } from '@angular/core';
// #enddocregion import-debug-element
// #docregion v1
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
// #enddocregion v1
import { BannerComponent } from './banner-initial.component';
/*
// #docregion v1
import { BannerComponent } from './banner.component';
@ -17,15 +19,12 @@ describe('BannerComponent', () => {
// #enddocregion v1
*/
describe('BannerComponent (initial CLI generated)', () => {
// #docregion v1
// #docregion v1
let component: BannerComponent;
let fixture: ComponentFixture<BannerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [BannerComponent]}).compileComponents();
}));
beforeEach(() => {
@ -44,9 +43,7 @@ describe('BannerComponent (initial CLI generated)', () => {
describe('BannerComponent (minimal)', () => {
it('should create', () => {
// #docregion configureTestingModule
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
});
TestBed.configureTestingModule({declarations: [BannerComponent]});
// #enddocregion configureTestingModule
// #docregion createComponent
const fixture = TestBed.createComponent(BannerComponent);
@ -65,9 +62,7 @@ describe('BannerComponent (with beforeEach)', () => {
let fixture: ComponentFixture<BannerComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
});
TestBed.configureTestingModule({declarations: [BannerComponent]});
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
});

View File

@ -1,22 +1,21 @@
// #docplaster
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { addMatchers, click } from '../../testing';
import { Hero } from '../model/hero';
import { DashboardHeroComponent } from './dashboard-hero.component';
beforeEach( addMatchers );
beforeEach(addMatchers);
describe('DashboardHeroComponent class only', () => {
// #docregion class-only
it('raises the selected event when clicked', () => {
const comp = new DashboardHeroComponent();
const hero: Hero = { id: 42, name: 'Test' };
const hero: Hero = {id: 42, name: 'Test'};
comp.hero = hero;
comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero));
@ -26,33 +25,31 @@ describe('DashboardHeroComponent class only', () => {
});
describe('DashboardHeroComponent when tested directly', () => {
let comp: DashboardHeroComponent;
let expectedHero: Hero;
let fixture: ComponentFixture<DashboardHeroComponent>;
let heroDe: DebugElement;
let heroEl: HTMLElement;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// #docregion setup, config-testbed
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent ]
})
// #enddocregion setup, config-testbed
.compileComponents();
TestBed
.configureTestingModule({declarations: [DashboardHeroComponent]})
// #enddocregion setup, config-testbed
.compileComponents();
}));
beforeEach(() => {
// #docregion setup
fixture = TestBed.createComponent(DashboardHeroComponent);
comp = fixture.componentInstance;
comp = fixture.componentInstance;
// find the hero's DebugElement and element
heroDe = fixture.debugElement.query(By.css('.hero'));
heroDe = fixture.debugElement.query(By.css('.hero'));
heroEl = heroDe.nativeElement;
// mock the hero supplied by the parent component
expectedHero = { id: 42, name: 'Test Name' };
expectedHero = {id: 42, name: 'Test Name'};
// simulate the parent setting the input property with that hero
comp.hero = expectedHero;
@ -96,8 +93,8 @@ describe('DashboardHeroComponent when tested directly', () => {
let selectedHero: Hero;
comp.selected.subscribe((hero: Hero) => selectedHero = hero);
click(heroDe); // click helper with DebugElement
click(heroEl); // click helper with native element
click(heroDe); // click helper with DebugElement
click(heroEl); // click helper with native element
expect(selectedHero).toBe(expectedHero);
});
@ -111,22 +108,21 @@ describe('DashboardHeroComponent when inside a test host', () => {
let fixture: ComponentFixture<TestHostComponent>;
let heroEl: HTMLElement;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// #docregion test-host-setup
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent, TestHostComponent ]
})
// #enddocregion test-host-setup
.compileComponents();
TestBed
.configureTestingModule({declarations: [DashboardHeroComponent, TestHostComponent]})
// #enddocregion test-host-setup
.compileComponents();
}));
beforeEach(() => {
// #docregion test-host-setup
// create TestHostComponent instead of DashboardHeroComponent
fixture = TestBed.createComponent(TestHostComponent);
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
heroEl = fixture.nativeElement.querySelector('.hero');
fixture.detectChanges(); // trigger initial data binding
heroEl = fixture.nativeElement.querySelector('.hero');
fixture.detectChanges(); // trigger initial data binding
// #enddocregion test-host-setup
});
@ -155,8 +151,10 @@ import { Component } from '@angular/core';
</dashboard-hero>`
})
class TestHostComponent {
hero: Hero = {id: 42, name: 'Test Name' };
hero: Hero = {id: 42, name: 'Test Name'};
selectedHero: Hero;
onSelected(hero: Hero) { this.selectedHero = hero; }
onSelected(hero: Hero) {
this.selectedHero = hero;
}
}
// #enddocregion test-host

View File

@ -1,6 +1,5 @@
// #docplaster
import { async, inject, ComponentFixture, TestBed
} from '@angular/core/testing';
import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
import { addMatchers, asyncData, click } from '../../testing';
import { HeroService } from '../model/hero.service';
@ -12,7 +11,7 @@ import { Router } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { DashboardModule } from './dashboard.module';
beforeEach ( addMatchers );
beforeEach(addMatchers);
let comp: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
@ -21,9 +20,7 @@ let fixture: ComponentFixture<DashboardComponent>;
describe('DashboardComponent (deep)', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ DashboardModule ]
});
TestBed.configureTestingModule({imports: [DashboardModule]});
});
compileAndCreate();
@ -43,10 +40,8 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('DashboardComponent (shallow)', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ DashboardComponent ],
schemas: [NO_ERRORS_SCHEMA]
});
TestBed.configureTestingModule(
{declarations: [DashboardComponent], schemas: [NO_ERRORS_SCHEMA]});
});
compileAndCreate();
@ -63,25 +58,26 @@ describe('DashboardComponent (shallow)', () => {
/** Add TestBed providers, compile, and create DashboardComponent */
function compileAndCreate() {
// #docregion compile-and-create-body
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// #docregion router-spy
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);
TestBed.configureTestingModule({
providers: [
{ provide: HeroService, useValue: heroServiceSpy },
{ provide: Router, useValue: routerSpy }
]
})
// #enddocregion router-spy
.compileComponents().then(() => {
fixture = TestBed.createComponent(DashboardComponent);
comp = fixture.componentInstance;
TestBed
.configureTestingModule({
providers: [
{provide: HeroService, useValue: heroServiceSpy}, {provide: Router, useValue: routerSpy}
]
})
// #enddocregion router-spy
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(DashboardComponent);
comp = fixture.componentInstance;
// getHeroes spy returns observable of test heroes
heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes()));
});
// getHeroes spy returns observable of test heroes
heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes()));
});
// #enddocregion compile-and-create-body
}));
}
@ -93,23 +89,20 @@ function compileAndCreate() {
function tests(heroClick: () => void) {
it('should NOT have heroes before ngOnInit', () => {
expect(comp.heroes.length).toBe(0,
'should not have heroes before ngOnInit');
expect(comp.heroes.length).toBe(0, 'should not have heroes before ngOnInit');
});
it('should NOT have heroes immediately after ngOnInit', () => {
fixture.detectChanges(); // runs initial lifecycle hooks
fixture.detectChanges(); // runs initial lifecycle hooks
expect(comp.heroes.length).toBe(0,
'should not have heroes until service promise resolves');
expect(comp.heroes.length).toBe(0, 'should not have heroes until service promise resolves');
});
describe('after get dashboard heroes', () => {
let router: Router;
// Trigger component so it gets heroes and binds to them
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
router = fixture.debugElement.injector.get(Router);
fixture.detectChanges(); // runs ngOnInit -> getHeroes
fixture.whenStable() // No need for the `lastPromise` hack!
@ -117,8 +110,8 @@ function tests(heroClick: () => void) {
}));
it('should HAVE heroes', () => {
expect(comp.heroes.length).toBeGreaterThan(0,
'should have heroes after service promise resolves');
expect(comp.heroes.length)
.toBeGreaterThan(0, 'should have heroes after service promise resolves');
});
it('should DISPLAY heroes', () => {
@ -130,8 +123,7 @@ function tests(heroClick: () => void) {
// #docregion navigate-test
it('should tell ROUTER to navigate when hero clicked', () => {
heroClick(); // trigger click on first inner <div class="hero">
heroClick(); // trigger click on first inner <div class="hero">
// args passed to router.navigateByUrl() spy
const spy = router.navigateByUrl as jasmine.Spy;
@ -139,10 +131,8 @@ function tests(heroClick: () => void) {
// expecting to navigate to id of the component's first hero
const id = comp.heroes[0].id;
expect(navArgs).toBe('/heroes/' + id,
'should nav to HeroDetail for first hero');
expect(navArgs).toBe('/heroes/' + id, 'should nav to HeroDetail for first hero');
});
// #enddocregion navigate-test
});
}

View File

@ -1,18 +1,23 @@
// tslint:disable-next-line:no-unused-variable
import { async, fakeAsync, tick } from '@angular/core/testing';
import { fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { interval, of } from 'rxjs';
import { delay, take } from 'rxjs/operators';
describe('Angular async helper', () => {
describe('async', () => {
let actuallyDone = false;
beforeEach(() => { actuallyDone = false; });
beforeEach(() => {
actuallyDone = false;
});
afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); });
afterEach(() => {
expect(actuallyDone).toBe(true, 'actuallyDone should be true');
});
it('should run normal test', () => { actuallyDone = true; });
it('should run normal test', () => {
actuallyDone = true;
});
it('should run normal async test', (done: DoneFn) => {
setTimeout(() => {
@ -21,39 +26,50 @@ describe('Angular async helper', () => {
}, 0);
});
it('should run async test with task',
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
it('should run async test with task', waitForAsync(() => {
setTimeout(() => {
actuallyDone = true;
}, 0);
}));
it('should run async test with task', async(() => {
it('should run async test with task', waitForAsync(() => {
const id = setInterval(() => {
actuallyDone = true;
clearInterval(id);
}, 100);
}));
it('should run async test with successful promise', async(() => {
const p = new Promise(resolve => { setTimeout(resolve, 10); });
p.then(() => { actuallyDone = true; });
it('should run async test with successful promise', waitForAsync(() => {
const p = new Promise(resolve => {
setTimeout(resolve, 10);
});
p.then(() => {
actuallyDone = true;
});
}));
it('should run async test with failed promise', async(() => {
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
p.catch(() => { actuallyDone = true; });
it('should run async test with failed promise', waitForAsync(() => {
const p = new Promise((resolve, reject) => {
setTimeout(reject, 10);
});
p.catch(() => {
actuallyDone = true;
});
}));
// Use done. Can also use async or fakeAsync.
it('should run async test with successful delayed Observable', (done: DoneFn) => {
const source = of (true).pipe(delay(10));
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err), done);
});
it('should run async test with successful delayed Observable', async(() => {
const source = of (true).pipe(delay(10));
it('should run async test with successful delayed Observable', waitForAsync(() => {
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
}));
it('should run async test with successful delayed Observable', fakeAsync(() => {
const source = of (true).pipe(delay(10));
const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
tick(10);
@ -64,7 +80,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
let called = false;
setTimeout(() => { called = true; }, 100);
setTimeout(() => {
called = true;
}, 100);
tick(100);
expect(called).toBe(true);
}));
@ -73,7 +91,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-sync
it('should run new macro task callback with delay after call tick with millis',
fakeAsync(() => {
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
const callback = jasmine.createSpy('callback');
nestedTimer(callback);
expect(callback).not.toHaveBeenCalled();
@ -86,7 +106,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-async
it('should not run new macro task callback with delay after call tick with millis',
fakeAsync(() => {
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
const callback = jasmine.createSpy('callback');
nestedTimer(callback);
expect(callback).not.toHaveBeenCalled();
@ -112,7 +134,9 @@ describe('Angular async helper', () => {
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
// to patch rxjs scheduler
let result = null;
of ('hello').pipe(delay(1000)).subscribe(v => { result = v; });
of('hello').pipe(delay(1000)).subscribe(v => {
result = v;
});
expect(result).toBeNull();
tick(1000);
expect(result).toBe('hello');
@ -133,12 +157,18 @@ describe('Angular async helper', () => {
describe('use jasmine.clock()', () => {
// need to config __zone_symbol__fakeAsyncPatchLock flag
// before loading zone.js/dist/zone-testing
beforeEach(() => { jasmine.clock().install(); });
afterEach(() => { jasmine.clock().uninstall(); });
beforeEach(() => {
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should auto enter fakeAsync', () => {
// is in fakeAsync now, don't need to call fakeAsync(testFn)
let called = false;
setTimeout(() => { called = true; }, 100);
setTimeout(() => {
called = true;
}, 100);
jasmine.clock().tick(100);
expect(called).toBe(true);
});
@ -152,7 +182,7 @@ describe('Angular async helper', () => {
}
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
// before loading zone.js/dist/zone-testing
it('should wait until promise.then is called', async(() => {
it('should wait until promise.then is called', waitForAsync(() => {
let finished = false;
new Promise((res, rej) => {
jsonp('localhost:8080/jsonp', () => {
@ -168,5 +198,4 @@ describe('Angular async helper', () => {
}));
});
// #enddocregion async-test-promise-then
});

View File

@ -24,17 +24,18 @@ import { FormsModule } from '@angular/forms';
// Forms symbols imported only for a specific test below
import { NgModel, NgControl } from '@angular/forms';
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick
import {
ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync
} from '@angular/core/testing';
import { addMatchers, newEvent, click } from '../../testing';
export class NotProvided extends ValueService { /* example below */}
beforeEach( addMatchers );
export class NotProvided extends ValueService { /* example below */ }
beforeEach(addMatchers);
describe('demo (with TestBed):', () => {
//////// Service Tests /////////////
//////// Service Tests /////////////
// #docregion ValueService
describe('ValueService', () => {
@ -64,13 +65,13 @@ describe('demo (with TestBed):', () => {
// #enddocregion testbed-get-w-null
});
it('test should wait for ValueService.getPromiseValue', async(() => {
it('test should wait for ValueService.getPromiseValue', waitForAsync(() => {
service.getPromiseValue().then(
value => expect(value).toBe('promise value')
);
}));
it('test should wait for ValueService.getObservableValue', async(() => {
it('test should wait for ValueService.getObservableValue', waitForAsync(() => {
service.getObservableValue().subscribe(
value => expect(value).toBe('observable value')
);
@ -150,7 +151,7 @@ describe('demo (with TestBed):', () => {
TestBed.configureTestingModule({ providers: [ValueService] });
});
beforeEach(async(inject([ValueService], (service: ValueService) => {
beforeEach(waitForAsync(inject([ValueService], (service: ValueService) => {
service.getPromiseValue().then(value => serviceValue = value);
})));
@ -159,11 +160,11 @@ describe('demo (with TestBed):', () => {
});
});
/////////// Component Tests //////////////////
/////////// Component Tests //////////////////
describe('TestBed component tests', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [DemoModule],
@ -235,7 +236,7 @@ describe('demo (with TestBed):', () => {
// #docregion ButtonComp
it('should support clicking a button', () => {
const fixture = TestBed.createComponent(LightswitchComponent);
const btn = fixture.debugElement.query(By.css('button'));
const btn = fixture.debugElement.query(By.css('button'));
const span = fixture.debugElement.query(By.css('span')).nativeElement;
fixture.detectChanges();
@ -248,7 +249,7 @@ describe('demo (with TestBed):', () => {
// #enddocregion ButtonComp
// ngModel is async so we must wait for it with promise-based `whenStable`
it('should support entering text in input box (ngModel)', async(() => {
it('should support entering text in input box (ngModel)', waitForAsync(() => {
const expectedOrigName = 'John';
const expectedNewName = 'Sally';
@ -278,10 +279,10 @@ describe('demo (with TestBed):', () => {
input.dispatchEvent(newEvent('input'));
return fixture.whenStable();
})
.then(() => {
expect(comp.name).toBe(expectedNewName,
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
});
.then(() => {
expect(comp.name).toBe(expectedNewName,
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
});
}));
// fakeAsync version of ngModel input test enables sync test style
@ -327,9 +328,9 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.createComponent(ReversePipeComponent);
fixture.detectChanges();
const comp = fixture.componentInstance;
const comp = fixture.componentInstance;
const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
// simulate user entering new name in input
input.value = inputText;
@ -381,12 +382,12 @@ describe('demo (with TestBed):', () => {
expect(el.styles.color).toBe(comp.color, 'color style');
expect(el.styles.width).toBe(comp.width + 'px', 'width style');
// #enddocregion dom-attributes
// #enddocregion dom-attributes
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
// expect(el.properties['customProperty']).toBe(true, 'customProperty');
// #docregion dom-attributes
// #docregion dom-attributes
});
// #enddocregion dom-attributes
@ -400,10 +401,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [Child1Component],
})
.overrideComponent(Child1Component, {
set: { template: '<span>Fake</span>' }
})
.createComponent(Child1Component);
.overrideComponent(Child1Component, {
set: { template: '<span>Fake</span>' }
})
.createComponent(Child1Component);
fixture.detectChanges();
expect(fixture).toHaveText('Fake');
@ -413,14 +414,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [TestProvidersComponent],
})
.overrideComponent(TestProvidersComponent, {
remove: { providers: [ValueService]},
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
.overrideComponent(TestProvidersComponent, {
remove: { providers: [ValueService] },
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one provider)
// set: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestProvidersComponent);
// Or replace them all (this component has only one provider)
// set: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestProvidersComponent);
fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value', 'text');
@ -436,14 +437,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [TestViewProvidersComponent],
})
.overrideComponent(TestViewProvidersComponent, {
// remove: { viewProviders: [ValueService]},
// add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
.overrideComponent(TestViewProvidersComponent, {
// remove: { viewProviders: [ValueService]},
// add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one viewProvider)
set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestViewProvidersComponent);
// Or replace them all (this component has only one viewProvider)
set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestViewProvidersComponent);
fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value');
@ -453,20 +454,20 @@ describe('demo (with TestBed):', () => {
// TestComponent is parent of TestProvidersComponent
@Component({ template: '<my-service-comp></my-service-comp>' })
class TestComponent {}
class TestComponent { }
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
const fixture = TestBed.configureTestingModule({
declarations: [TestComponent, TestProvidersComponent],
providers: [ValueService]
providers: [ValueService]
})
.overrideComponent(TestComponent, {
set: { providers: [{ provide: ValueService, useValue: {} }] }
})
.overrideComponent(TestProvidersComponent, {
set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }
})
.createComponent(TestComponent);
.overrideComponent(TestComponent, {
set: { providers: [{ provide: ValueService, useValue: {} }] }
})
.overrideComponent(TestProvidersComponent, {
set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }
})
.createComponent(TestComponent);
let testBedProvider: ValueService;
let tcProvider: ValueService;
@ -489,10 +490,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component],
})
.overrideComponent(ShellComponent, {
set: {
selector: 'test-shell',
template: `
.overrideComponent(ShellComponent, {
set: {
selector: 'test-shell',
template: `
<needs-content #nc>
<child-1 #content text="My"></child-1>
<child-2 #content text="dog"></child-2>
@ -501,9 +502,9 @@ describe('demo (with TestBed):', () => {
<div #content>!</div>
</needs-content>
`
}
})
.createComponent(ShellComponent);
}
})
.createComponent(ShellComponent);
fixture.detectChanges();
@ -615,7 +616,7 @@ describe('demo (with TestBed):', () => {
});
// must be async test to see child flow to parent
it('changed child value flows to parent', async(() => {
it('changed child value flows to parent', waitForAsync(() => {
fixture.detectChanges();
getChild();
@ -625,14 +626,14 @@ describe('demo (with TestBed):', () => {
// Wait one JS engine turn!
setTimeout(() => resolve(), 0);
})
.then(() => {
fixture.detectChanges();
.then(() => {
fixture.detectChanges();
expect(child.ngOnChangesCounter).toBe(2,
'expected 2 changes: initial value and changed value');
expect(parent.parentValue).toBe('bar',
'parentValue should eq changed parent value');
});
expect(child.ngOnChangesCounter).toBe(2,
'expected 2 changes: initial value and changed value');
expect(parent.parentValue).toBe('bar',
'parentValue should eq changed parent value');
});
}));

View File

@ -1,8 +1,5 @@
// #docplaster
import {
async, ComponentFixture, fakeAsync, inject, TestBed, tick
} from '@angular/core/testing';
import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { Router } from '@angular/router';
import {
@ -36,59 +33,54 @@ describe('HeroDetailComponent', () => {
function overrideSetup() {
// #docregion hds-spy
class HeroDetailServiceSpy {
testHero: Hero = {id: 42, name: 'Test Hero' };
testHero: Hero = {id: 42, name: 'Test Hero'};
/* emit cloned test hero */
getHero = jasmine.createSpy('getHero').and.callFake(
() => asyncData(Object.assign({}, this.testHero))
);
() => asyncData(Object.assign({}, this.testHero)));
/* emit clone of test hero, with changes merged in */
saveHero = jasmine.createSpy('saveHero').and.callFake(
(hero: Hero) => asyncData(Object.assign(this.testHero, hero))
);
saveHero = jasmine.createSpy('saveHero')
.and.callFake((hero: Hero) => asyncData(Object.assign(this.testHero, hero)));
}
// #enddocregion hds-spy
// the `id` value is irrelevant because ignored by service stub
beforeEach(() => activatedRoute.setParamMap({ id: 99999 }));
beforeEach(() => activatedRoute.setParamMap({id: 99999}));
// #docregion setup-override
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy();
TestBed.configureTestingModule({
imports: [ HeroModule ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: Router, useValue: routerSpy},
TestBed
.configureTestingModule({
imports: [HeroModule],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: Router, useValue: routerSpy},
// #enddocregion setup-override
// HeroDetailService at this level is IRRELEVANT!
{ provide: HeroDetailService, useValue: {} }
// HeroDetailService at this level is IRRELEVANT!
{provide: HeroDetailService, useValue: {}}
// #docregion setup-override
]
})
]
})
// Override component's own provider
// #docregion override-component-method
.overrideComponent(HeroDetailComponent, {
set: {
providers: [
{ provide: HeroDetailService, useClass: HeroDetailServiceSpy }
]
}
})
// #enddocregion override-component-method
// Override component's own provider
// #docregion override-component-method
.overrideComponent(
HeroDetailComponent,
{set: {providers: [{provide: HeroDetailService, useClass: HeroDetailServiceSpy}]}})
// #enddocregion override-component-method
.compileComponents();
.compileComponents();
}));
// #enddocregion setup-override
// #docregion override-tests
let hdsSpy: HeroDetailServiceSpy;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
createComponent();
// get the component's injected HeroDetailServiceSpy
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
@ -103,33 +95,32 @@ function overrideSetup() {
});
it('should save stub hero change', fakeAsync(() => {
const origName = hdsSpy.testHero.name;
const newName = 'New Name';
const origName = hdsSpy.testHero.name;
const newName = 'New Name';
page.nameInput.value = newName;
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
page.nameInput.value = newName;
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
expect(component.hero.name).toBe(newName, 'component hero has new name');
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
expect(component.hero.name).toBe(newName, 'component hero has new name');
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
click(page.saveBtn);
expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once');
click(page.saveBtn);
expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once');
tick(); // wait for async save to complete
expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save');
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
tick(); // wait for async save to complete
expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save');
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
// #enddocregion override-tests
it('fixture injected service is not the component injected service',
// inject gets the service from the fixture
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
// inject gets the service from the fixture
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
// use `fixture.debugElement.injector` to get service from component
const componentService = fixture.debugElement.injector.get(HeroDetailService);
// use `fixture.debugElement.injector` to get service from component
const componentService = fixture.debugElement.injector.get(HeroDetailService);
expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
}));
expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
}));
}
////////////////////
@ -139,21 +130,22 @@ const firstHero = getTestHeroes()[0];
function heroModuleSetup() {
// #docregion setup-hero-module
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy();
TestBed.configureTestingModule({
imports: [ HeroModule ],
// #enddocregion setup-hero-module
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
// #docregion setup-hero-module
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed
.configureTestingModule({
imports: [HeroModule],
// #enddocregion setup-hero-module
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
// #docregion setup-hero-module
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-hero-module
@ -161,17 +153,17 @@ function heroModuleSetup() {
describe('when navigate to existing hero', () => {
let expectedHero: Hero;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id });
activatedRoute.setParamMap({id: expectedHero.id});
createComponent();
}));
// #docregion selected-tests
// #docregion selected-tests
it('should display that hero\'s name', () => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
// #enddocregion route-good-id
// #enddocregion route-good-id
it('should navigate when click cancel', () => {
click(page.cancelBtn);
@ -190,10 +182,10 @@ function heroModuleSetup() {
});
it('should navigate when click save and save resolves', fakeAsync(() => {
click(page.saveBtn);
tick(); // wait for async save to complete
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
click(page.saveBtn);
tick(); // wait for async save to complete
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
// #docregion title-case-pipe
it('should convert hero name to Title Case', () => {
@ -215,14 +207,14 @@ function heroModuleSetup() {
expect(nameDisplay.textContent).toBe('Quick Brown Fox');
});
// #enddocregion title-case-pipe
// #enddocregion selected-tests
// #docregion route-good-id
// #enddocregion selected-tests
// #docregion route-good-id
});
// #enddocregion route-good-id
// #docregion route-no-id
describe('when navigate with no hero id', () => {
beforeEach(async( createComponent ));
beforeEach(waitForAsync(createComponent));
it('should have hero.id === 0', () => {
expect(component.hero.id).toBe(0);
@ -236,8 +228,8 @@ function heroModuleSetup() {
// #docregion route-bad-id
describe('when navigate to non-existent hero id', () => {
beforeEach(async(() => {
activatedRoute.setParamMap({ id: 99999 });
beforeEach(waitForAsync(() => {
activatedRoute.setParamMap({id: 99999});
createComponent();
}));
@ -253,11 +245,10 @@ function heroModuleSetup() {
let service: HeroDetailService;
fixture = TestBed.createComponent(HeroDetailComponent);
expect(
// Throws because `inject` only has access to TestBed's injector
// which is an ancestor of the component's injector
inject([HeroDetailService], (hds: HeroDetailService) => service = hds )
)
.toThrowError(/No provider for HeroDetailService/);
// Throws because `inject` only has access to TestBed's injector
// which is an ancestor of the component's injector
inject([HeroDetailService], (hds: HeroDetailService) => service = hds))
.toThrowError(/No provider for HeroDetailService/);
// get `HeroDetailService` with component's own injector
service = fixture.debugElement.injector.get(HeroDetailService);
@ -270,30 +261,31 @@ import { FormsModule } from '@angular/forms';
import { TitleCasePipe } from '../shared/title-case.pipe';
function formsModuleSetup() {
// #docregion setup-forms-module
beforeEach(async(() => {
// #docregion setup-forms-module
beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy();
TestBed.configureTestingModule({
imports: [ FormsModule ],
declarations: [ HeroDetailComponent, TitleCasePipe ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed
.configureTestingModule({
imports: [FormsModule],
declarations: [HeroDetailComponent, TitleCasePipe],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-forms-module
it('should display 1st hero\'s name', async(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id });
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
}
///////////////////////
@ -301,29 +293,30 @@ import { SharedModule } from '../shared/shared.module';
function sharedModuleSetup() {
// #docregion setup-shared-module
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy();
TestBed.configureTestingModule({
imports: [ SharedModule ],
declarations: [ HeroDetailComponent ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed
.configureTestingModule({
imports: [SharedModule],
declarations: [HeroDetailComponent],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-shared-module
it('should display 1st hero\'s name', async(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id });
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
}
/////////// Helpers /////
@ -347,11 +340,21 @@ function createComponent() {
// #docregion page
class Page {
// getter properties wait to query the DOM until called.
get buttons() { return this.queryAll<HTMLButtonElement>('button'); }
get saveBtn() { return this.buttons[0]; }
get cancelBtn() { return this.buttons[1]; }
get nameDisplay() { return this.query<HTMLElement>('span'); }
get nameInput() { return this.query<HTMLInputElement>('input'); }
get buttons() {
return this.queryAll<HTMLButtonElement>('button');
}
get saveBtn() {
return this.buttons[0];
}
get cancelBtn() {
return this.buttons[1];
}
get nameDisplay() {
return this.query<HTMLElement>('span');
}
get nameInput() {
return this.query<HTMLInputElement>('input');
}
gotoListSpy: jasmine.Spy;
navigateSpy: jasmine.Spy;

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, fakeAsync, TestBed, tick
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
@ -7,13 +7,12 @@ import { DebugElement } from '@angular/core';
import { Router } from '@angular/router';
import { addMatchers, newEvent } from '../../testing';
import { HeroService } from '../model/hero.service';
import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service';
import { HeroModule } from './hero.module';
import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from '../shared/highlight.directive';
import { HeroService } from '../model/hero.service';
const HEROES = getTestHeroes();
@ -24,20 +23,20 @@ let page: Page;
/////// Tests //////
describe('HeroListComponent', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
addMatchers();
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
TestBed.configureTestingModule({
imports: [HeroModule],
providers: [
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy}
]
})
.compileComponents()
.then(createComponent);
TestBed
.configureTestingModule({
imports: [HeroModule],
providers: [
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy}
]
})
.compileComponents()
.then(createComponent);
}));
it('should display heroes', () => {
@ -52,36 +51,35 @@ describe('HeroListComponent', () => {
});
it('should select hero on click', fakeAsync(() => {
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
expect(comp.selectedHero).toEqual(expectedHero);
}));
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
expect(comp.selectedHero).toEqual(expectedHero);
}));
it('should navigate to selected hero detail on click', fakeAsync(() => {
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// should have navigated
expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
// should have navigated
expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
// composed hero detail will be URL like 'heroes/42'
// expect link array with the route path and hero id
// first argument to router.navigate is link array
const navArgs = page.navSpy.calls.first().args[0];
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
}));
// composed hero detail will be URL like 'heroes/42'
// expect link array with the route path and hero id
// first argument to router.navigate is link array
const navArgs = page.navSpy.calls.first().args[0];
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
}));
it('should find `HighlightDirective` with `By.directive', () => {
// #docregion by
// Can find DebugElement either by css selector or by directive
const h2 = fixture.debugElement.query(By.css('h2'));
const h2 = fixture.debugElement.query(By.css('h2'));
const directive = fixture.debugElement.query(By.directive(HighlightDirective));
// #enddocregion by
expect(h2).toBe(directive);

View File

@ -1,6 +1,7 @@
// #docplaster
// #docregion without-toBlob-macrotask
import { TestBed, async, tick, fakeAsync } from '@angular/core/testing';
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { CanvasComponent } from './canvas.component';
describe('CanvasComponent', () => {
@ -10,29 +11,29 @@ describe('CanvasComponent', () => {
(window as any).__zone_symbol__FakeAsyncTestMacroTask = [
{
source: 'HTMLCanvasElement.toBlob',
callbackArgs: [{ size: 200 }],
callbackArgs: [{size: 200}],
},
];
});
// #enddocregion enable-toBlob-macrotask
// #docregion without-toBlob-macrotask
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
CanvasComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [CanvasComponent],
})
.compileComponents();
}));
it('should be able to generate blob data from canvas', fakeAsync(() => {
const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.componentInstance;
const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.componentInstance;
fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0);
fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0);
tick();
expect(canvasComp.blobSize).toBeGreaterThan(0);
}));
tick();
expect(canvasComp.blobSize).toBeGreaterThan(0);
}));
});
// #enddocregion without-toBlob-macrotask

View File

@ -1,14 +1,13 @@
// #docplaster
import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing';
import { fakeAsync, ComponentFixture, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { asyncData, asyncError } from '../../testing';
import { of, throwError } from 'rxjs';
import { last } from 'rxjs/operators';
import { TwainService } from './twain.service';
import { TwainComponent } from './twain.component';
import { TwainService } from './twain.service';
describe('TwainComponent', () => {
let component: TwainComponent;
@ -32,14 +31,12 @@ describe('TwainComponent', () => {
// Create a fake TwainService object with a `getQuote()` spy
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
// Make the spy return a synchronous Observable with the test data
getQuoteSpy = twainService.getQuote.and.returnValue( of(testQuote) );
getQuoteSpy = twainService.getQuote.and.returnValue(of(testQuote));
// #enddocregion spy
TestBed.configureTestingModule({
declarations: [ TwainComponent ],
providers: [
{ provide: TwainService, useValue: twainService }
]
declarations: [TwainComponent],
providers: [{provide: TwainService, useValue: twainService}]
});
fixture = TestBed.createComponent(TwainComponent);
@ -58,7 +55,7 @@ describe('TwainComponent', () => {
// The quote would not be immediately available if the service were truly async.
// #docregion sync-test
it('should show quote after component initialized', () => {
fixture.detectChanges(); // onInit()
fixture.detectChanges(); // onInit()
// sync spy result shows testQuote immediately after init
expect(quoteEl.textContent).toBe(testQuote);
@ -71,20 +68,19 @@ describe('TwainComponent', () => {
// Use `fakeAsync` because the component error calls `setTimeout`
// #docregion error-test
it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an error observable
getQuoteSpy.and.returnValue(
throwError('TwainService test failure'));
// tell spy to return an error observable
getQuoteSpy.and.returnValue(throwError('TwainService test failure'));
fixture.detectChanges(); // onInit()
// sync spy errors immediately after init
fixture.detectChanges(); // onInit()
// sync spy errors immediately after init
tick(); // flush the component's setTimeout()
tick(); // flush the component's setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout()
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
// #enddocregion error-test
});
@ -113,28 +109,28 @@ describe('TwainComponent', () => {
// #docregion fake-async-test
it('should show quote after getQuote (fakeAsync)', fakeAsync(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
tick(); // flush the observable to get the quote
fixture.detectChanges(); // update view
tick(); // flush the observable to get the quote
fixture.detectChanges(); // update view
expect(quoteEl.textContent).toBe(testQuote, 'should show quote');
expect(errorMessage()).toBeNull('should not show error');
}));
expect(quoteEl.textContent).toBe(testQuote, 'should show quote');
expect(errorMessage()).toBeNull('should not show error');
}));
// #enddocregion fake-async-test
// #docregion async-test
it('should show quote after getQuote (async)', async(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
it('should show quote after getQuote (async)', waitForAsync(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
});
}));
fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
});
}));
// #enddocregion async-test
@ -142,8 +138,8 @@ describe('TwainComponent', () => {
it('should show last quote (quote done)', (done: DoneFn) => {
fixture.detectChanges();
component.quote.pipe( last() ).subscribe(() => {
fixture.detectChanges(); // update view with quote
component.quote.pipe(last()).subscribe(() => {
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
done();
@ -157,7 +153,7 @@ describe('TwainComponent', () => {
// the spy's most recent call returns the observable with the test quote
getQuoteSpy.calls.mostRecent().returnValue.subscribe(() => {
fixture.detectChanges(); // update view with quote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
done();
@ -167,16 +163,16 @@ describe('TwainComponent', () => {
// #docregion async-error-test
it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an async error observable
getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure'));
// tell spy to return an async error observable
getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure'));
fixture.detectChanges();
tick(); // component shows error after a setTimeout()
fixture.detectChanges(); // update error message
fixture.detectChanges();
tick(); // component shows error after a setTimeout()
fixture.detectChanges(); // update error message
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
// #enddocregion async-error-test
});
});

View File

@ -1,12 +1,12 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { HEROES } from '../mock-heroes';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { HeroService } from '../hero.service';
import { HEROES } from '../mock-heroes';
import { DashboardComponent } from './dashboard.component';
describe('DashboardComponent', () => {
let component: DashboardComponent;
@ -14,23 +14,16 @@ describe('DashboardComponent', () => {
let heroService;
let getHeroesSpy;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
getHeroesSpy = heroService.getHeroes.and.returnValue( of(HEROES) );
TestBed.configureTestingModule({
declarations: [
DashboardComponent,
HeroSearchComponent
],
imports: [
RouterTestingModule.withRoutes([])
],
providers: [
{ provide: HeroService, useValue: heroService }
]
})
.compileComponents();
getHeroesSpy = heroService.getHeroes.and.returnValue(of(HEROES));
TestBed
.configureTestingModule({
declarations: [DashboardComponent, HeroSearchComponent],
imports: [RouterTestingModule.withRoutes([])],
providers: [{provide: HeroService, useValue: heroService}]
})
.compileComponents();
}));
beforeEach(() => {
@ -47,12 +40,11 @@ describe('DashboardComponent', () => {
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
});
it('should call heroService', async(() => {
expect(getHeroesSpy.calls.any()).toBe(true);
}));
it('should display 4 links', async(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
it('should call heroService', waitForAsync(() => {
expect(getHeroesSpy.calls.any()).toBe(true);
}));
it('should display 4 links', waitForAsync(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
});

View File

@ -1,22 +1,16 @@
// #docregion
// #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData {
return {
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
}
class MockPhone {
@ -34,10 +28,9 @@ class ActivatedRouteMock {
// #enddocregion activatedroute
describe('PhoneDetailComponent', () => {
// #docregion activatedroute
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [
@ -55,5 +48,4 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
});
});

View File

@ -1,13 +1,14 @@
/* tslint:disable */
// #docregion
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
import {SpyLocation} from '@angular/common/testing';
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {ActivatedRoute} from '@angular/router';
import {Observable, of} from 'rxjs';
import { PhoneListComponent } from './phone-list.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import {Phone, PhoneData} from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
class ActivatedRouteMock {
constructor(public snapshot: any) {}
@ -16,8 +17,7 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return of([
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
]);
}
}
@ -25,18 +25,18 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PhoneListComponent ],
providers: [
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
{ provide: Location, useClass: SpyLocation },
{ provide: Phone, useClass: MockPhone },
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [PhoneListComponent],
providers: [
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{provide: Location, useClass: SpyLocation},
{provide: Phone, useClass: MockPhone},
],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
@ -47,20 +47,15 @@ describe('PhoneList', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect(
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
).toContain('Motorola DROID');
expect(
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
.toContain('Motorola DROID');
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
.toContain('Nexus S');
});
xit('should set the default value of orderProp model', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(
compiled.querySelector('select option:last-child').selected
).toBe(true);
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
});
});

View File

@ -1,22 +1,16 @@
// #docregion
// #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData {
return {
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
}
class MockPhone {
@ -34,10 +28,9 @@ class ActivatedRouteMock {
// #enddocregion activatedroute
describe('PhoneDetailComponent', () => {
// #docregion activatedroute
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [
@ -55,5 +48,4 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
});
});

View File

@ -1,13 +1,14 @@
/* tslint:disable */
// #docregion routestuff
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
import {SpyLocation} from '@angular/common/testing';
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {ActivatedRoute} from '@angular/router';
import {Observable, of} from 'rxjs';
import { PhoneListComponent } from './phone-list.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import {Phone, PhoneData} from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
// #enddocregion routestuff
@ -18,8 +19,7 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return of([
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
]);
}
}
@ -27,20 +27,20 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => {
// #docregion routestuff
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PhoneListComponent ],
providers: [
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
{ provide: Location, useClass: SpyLocation },
{ provide: Phone, useClass: MockPhone },
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [PhoneListComponent],
providers: [
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{provide: Location, useClass: SpyLocation},
{provide: Phone, useClass: MockPhone},
],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
@ -52,20 +52,15 @@ describe('PhoneList', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect(
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
).toContain('Motorola DROID');
expect(
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
.toContain('Motorola DROID');
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
.toContain('Nexus S');
});
xit('should set the default value of orderProp model', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(
compiled.querySelector('select option:last-child').selected
).toBe(true);
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
});
});

View File

@ -58,6 +58,7 @@ v9 - v12
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
| `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 |
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
@ -108,6 +109,7 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
| API | Replacement | Deprecation announced | Notes |
| --- | ----------- | --------------------- | ----- |
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
{@a forms}
@ -477,7 +479,7 @@ The final decision was made on three key points:
{@a wrapped-value}
### `WrappedValue`
### `WrappedValue`
The purpose of `WrappedValue` is to allow the same object instance to be treated as different for the purposes of change detection.
It is commonly used with the `async` pipe in the case where the `Observable` produces the same instance of the value.
@ -487,7 +489,7 @@ No replacement is planned for this deprecation.
If you rely on the behavior that the same object instance should cause change detection, you have two options:
- Clone the resulting value so that it has a new identity.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
{@a deprecated-cli-flags}
## Deprecated CLI APIs and Options

View File

@ -159,10 +159,10 @@ It also generates an initial test file for the component, `banner-external.compo
<div class="alert is-helpful">
Because `compileComponents` is asynchronous, it uses
the [`async`](api/core/testing/async) utility
the [`waitForAsync`](api/core/testing/waitForAsync) utility
function imported from `@angular/core/testing`.
Please refer to the [async](guide/testing-components-scenarios#async) section for more details.
Please refer to the [waitForAsync](guide/testing-components-scenarios#waitForAsync) section for more details.
</div>

View File

@ -402,7 +402,7 @@ There is no nested syntax (like a `Promise.then()`) to disrupt the flow of contr
<div class="alert is-helpful">
Limitation: The `fakeAsync()` function won't work if the test body makes an `XMLHttpRequest` (XHR) call.
XHR calls within a test are rare, but if you need to call XHR, see [`async()`](#async), below.
XHR calls within a test are rare, but if you need to call XHR, see [`waitForAsync()`](#waitForAsync), below.
</div>
@ -587,41 +587,41 @@ Then call `detectChanges()` to tell Angular to update the screen.
Then you can assert that the quote element displays the expected text.
{@a async}
{@a waitForAsync}
#### Async test with _async()_
#### Async test with _waitForAsync()_
To use `async()` functionality, you must import `zone.js/dist/zone-testing` in your test setup file.
To use `waitForAsync()` functionality, you must import `zone.js/dist/zone-testing` in your test setup file.
If you created your project with the Angular CLI, `zone-testing` is already imported in `src/test.ts`.
The `fakeAsync()` utility function has a few limitations.
In particular, it won't work if the test body makes an `XMLHttpRequest` (XHR) call.
XHR calls within a test are rare so you can generally stick with [`fakeAsync()`](#fake-async).
But if you ever do need to call `XMLHttpRequest`, you'll want to know about `async()`.
But if you ever do need to call `XMLHttpRequest`, you'll want to know about `waitForAsync()`.
<div class="alert is-helpful">
The `TestBed.compileComponents()` method (see [below](#compile-components)) calls `XHR`
to read external template and css files during "just-in-time" compilation.
Write tests that call `compileComponents()` with the `async()` utility.
Write tests that call `compileComponents()` with the `waitForAsync()` utility.
</div>
Here's the previous `fakeAsync()` test, re-written with the `async()` utility.
Here's the previous `fakeAsync()` test, re-written with the `waitForAsync()` utility.
<code-example
path="testing/src/app/twain/twain.component.spec.ts"
region="async-test">
</code-example>
The `async()` utility hides some asynchronous boilerplate by arranging for the tester's code
The `waitForAsync()` utility hides some asynchronous boilerplate by arranging for the tester's code
to run in a special _async test zone_.
You don't need to pass Jasmine's `done()` into the test and call `done()` because it is `undefined` in promise or observable callbacks.
But the test's asynchronous nature is revealed by the call to `fixture.whenStable()`,
which breaks the linear flow of control.
When using an `intervalTimer()` such as `setInterval()` in `async()`, remember to cancel the timer with `clearInterval()` after the test, otherwise the `async()` never ends.
When using an `intervalTimer()` such as `setInterval()` in `waitForAsync()`, remember to cancel the timer with `clearInterval()` after the test, otherwise the `waitForAsync()` never ends.
{@a when-stable}
@ -641,18 +641,18 @@ update the quote element with the expected text.
#### Jasmine _done()_
While the `async()` and `fakeAsync()` functions greatly
While the `waitForAsync()` and `fakeAsync()` functions greatly
simplify Angular asynchronous testing,
you can still fall back to the traditional technique
and pass `it` a function that takes a
[`done` callback](https://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).
You can't call `done()` in `async()` or `fakeAsync()` functions, because the `done parameter`
You can't call `done()` in `waitForAsync()` or `fakeAsync()` functions, because the `done parameter`
is `undefined`.
Now you are responsible for chaining promises, handling errors, and calling `done()` at the appropriate moments.
Writing test functions with `done()`, is more cumbersome than `async()`and `fakeAsync()`, but it is occasionally necessary when code involves the `intervalTimer()` like `setInterval`.
Writing test functions with `done()`, is more cumbersome than `waitForAsync()`and `fakeAsync()`, but it is occasionally necessary when code involves the `intervalTimer()` like `setInterval`.
Here are two more versions of the previous test, written with `done()`.
The first one subscribes to the `Observable` exposed to the template by the component's `quote` property.
@ -738,7 +738,7 @@ you tell the `TestScheduler` to _flush_ its queue of prepared tasks like this.
region="test-scheduler-flush"></code-example>
This step serves a purpose analogous to [tick()](api/core/testing/tick) and `whenStable()` in the
earlier `fakeAsync()` and `async()` examples.
earlier `fakeAsync()` and `waitForAsync()` examples.
The balance of the test is the same as those examples.
#### Marble error testing
@ -1535,7 +1535,7 @@ You must call `compileComponents()` within an asynchronous test function.
<div class="alert is-critical">
If you neglect to make the test function async
(e.g., forget to use `async()` as described below),
(e.g., forget to use `waitForAsync()` as described below),
you'll see this error message
<code-example language="sh" class="code-shell" hideCopy>
@ -1549,7 +1549,7 @@ A typical approach is to divide the setup logic into two separate `beforeEach()`
1. An async `beforeEach()` that compiles the components
1. A synchronous `beforeEach()` that performs the remaining setup.
To follow this pattern, import the `async()` helper with the other testing symbols.
To follow this pattern, import the `waitForAsync()` helper with the other testing symbols.
<code-example
path="testing/src/app/banner/banner-external.component.spec.ts"
@ -1565,7 +1565,7 @@ Write the first async `beforeEach` like this.
region="async-before-each"
header="app/banner/banner-external.component.spec.ts (async beforeEach)"></code-example>
The `async()` helper function takes a parameterless function with the body of the setup.
The `waitForAsync()` helper function takes a parameterless function with the body of the setup.
The `TestBed.configureTestingModule()` method returns the `TestBed` class so you can chain
calls to other `TestBed` static methods such as `compileComponents()`.

View File

@ -25,7 +25,7 @@ Here's a summary of the stand-alone functions, in order of likely utility:
<td>
Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.
See [discussion above](guide/testing-components-scenarios#async).
See [discussion above](guide/testing-components-scenarios#waitForAsync).
</td>
</tr>

View File

@ -306,9 +306,9 @@ If you develop angular locally with `ng serve`, a `websocket` connection is set
In Windows, by default, one application can only have 6 websocket connections, <a href="https://msdn.microsoft.com/library/ee330736%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#websocket_maxconn" title="MSDN WebSocket settings">MSDN WebSocket Settings</a>.
So when IE is refreshed (manually or automatically by `ng serve`), sometimes the websocket does not close properly. When websocket connections exceed the limitations, a `SecurityError` will be thrown. This error will not affect the angular application, you can just restart IE to clear this error, or modify the windows registry to update the limitations.
## Appendix: Test using `fakeAsync()/async()`
## Appendix: Test using `fakeAsync()/waitForAsync()`
If you use the `fakeAsync()/async()` helper function to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/dist/zone-testing` in your test setup file.
If you use the `fakeAsync()/waitForAsync()` helper function to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/dist/zone-testing` in your test setup file.
<div class="alert is-important">
If you create project with `Angular/CLI`, it is already imported in `src/test.ts`.

View File

@ -1,6 +1,7 @@
/** @codeGenApi */
export declare const __core_private_testing_placeholder__ = "";
/** @deprecated */
export declare function async(fn: Function): (done: any) => any;
export declare class ComponentFixture<T> {
@ -141,5 +142,7 @@ export declare function tick(millis?: number, tickOptions?: {
processNewMacroTasksSynchronously: boolean;
}): void;
export declare function waitForAsync(fn: Function): (done: any) => any;
export declare function withModule(moduleDef: TestModuleMetadata): InjectSetupWrapper;
export declare function withModule(moduleDef: TestModuleMetadata, fn: Function): () => any;

View File

@ -1,13 +1,13 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {
@ -26,6 +26,7 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('cli-hello-world-ivy-compat app is running!');
expect(compiled.querySelector('.content span').textContent)
.toContain('cli-hello-world-ivy-compat app is running!');
});
});

View File

@ -1,13 +1,13 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {

View File

@ -1,17 +1,15 @@
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {
@ -30,6 +28,7 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('cli-hello-world-lazy-rollup app is running!');
expect(compiled.querySelector('.content span').textContent)
.toContain('cli-hello-world-lazy-rollup app is running!');
});
});

View File

@ -1,17 +1,15 @@
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {
@ -30,6 +28,7 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('cli-hello-world-lazy app is running!');
expect(compiled.querySelector('.content span').textContent)
.toContain('cli-hello-world-lazy app is running!');
});
});

View File

@ -1,13 +1,13 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {
@ -26,6 +26,7 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('cli-hello-world app is running!');
expect(compiled.querySelector('.content span').textContent)
.toContain('cli-hello-world app is running!');
});
});

View File

@ -1,13 +1,13 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
}));
it('should create the app', () => {

View File

@ -7,7 +7,7 @@
*/
import {Component} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
{
describe('binding to CSS class list', () => {
@ -37,7 +37,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
});
});
it('should clean up when the directive is destroyed', async(() => {
it('should clean up when the directive is destroyed', waitForAsync(() => {
fixture = createTestComponent('<div *ngFor="let item of items" [ngClass]="item"></div>');
getComponent().items = [['0']];
@ -47,21 +47,22 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
describe('expressions evaluating to objects', () => {
it('should add classes specified in an object literal', async(() => {
it('should add classes specified in an object literal', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="{foo: true, bar: false}"></div>');
detectChangesAndExpectClassName('foo');
}));
it('should add classes specified in an object literal without change in class names',
async(() => {
waitForAsync(() => {
fixture =
createTestComponent(`<div [ngClass]="{'foo-bar': true, 'fooBar': true}"></div>`);
detectChangesAndExpectClassName('foo-bar fooBar');
}));
it('should add and remove classes based on changes in object literal values', async(() => {
it('should add and remove classes based on changes in object literal values',
waitForAsync(() => {
fixture =
createTestComponent('<div [ngClass]="{foo: condition, bar: !condition}"></div>');
@ -71,7 +72,8 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('bar');
}));
it('should add and remove classes based on changes to the expression object', async(() => {
it('should add and remove classes based on changes to the expression object',
waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr"></div>');
const objExpr = getComponent().objExpr;
@ -88,7 +90,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should add and remove classes based on reference changes to the expression object',
async(() => {
waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr"></div>');
detectChangesAndExpectClassName('foo');
@ -100,7 +102,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('baz');
}));
it('should remove active classes when expression evaluates to null', async(() => {
it('should remove active classes when expression evaluates to null', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr"></div>');
detectChangesAndExpectClassName('foo');
@ -113,7 +115,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should allow multiple classes per expression', async(() => {
it('should allow multiple classes per expression', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr"></div>');
getComponent().objExpr = {'bar baz': true, 'bar1 baz1': true};
@ -123,7 +125,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('bar1 baz1');
}));
it('should split by one or more spaces between classes', async(() => {
it('should split by one or more spaces between classes', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr"></div>');
getComponent().objExpr = {'foo bar baz': true};
@ -132,14 +134,14 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
});
describe('expressions evaluating to lists', () => {
it('should add classes specified in a list literal', async(() => {
it('should add classes specified in a list literal', waitForAsync(() => {
fixture =
createTestComponent(`<div [ngClass]="['foo', 'bar', 'foo-bar', 'fooBar']"></div>`);
detectChangesAndExpectClassName('foo bar foo-bar fooBar');
}));
it('should add and remove classes based on changes to the expression', async(() => {
it('should add and remove classes based on changes to the expression', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="arrExpr"></div>');
const arrExpr = getComponent().arrExpr;
detectChangesAndExpectClassName('foo');
@ -154,7 +156,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('foo');
}));
it('should add and remove classes when a reference changes', async(() => {
it('should add and remove classes when a reference changes', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="arrExpr"></div>');
detectChangesAndExpectClassName('foo');
@ -162,7 +164,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('bar');
}));
it('should take initial classes into account when a reference changes', async(() => {
it('should take initial classes into account when a reference changes', waitForAsync(() => {
fixture = createTestComponent('<div class="foo" [ngClass]="arrExpr"></div>');
detectChangesAndExpectClassName('foo');
@ -170,13 +172,13 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('foo bar');
}));
it('should ignore empty or blank class names', async(() => {
it('should ignore empty or blank class names', waitForAsync(() => {
fixture = createTestComponent('<div class="foo" [ngClass]="arrExpr"></div>');
getComponent().arrExpr = ['', ' '];
detectChangesAndExpectClassName('foo');
}));
it('should trim blanks from class names', async(() => {
it('should trim blanks from class names', waitForAsync(() => {
fixture = createTestComponent('<div class="foo" [ngClass]="arrExpr"></div>');
getComponent().arrExpr = [' bar '];
@ -184,7 +186,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should allow multiple classes per item in arrays', async(() => {
it('should allow multiple classes per item in arrays', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="arrExpr"></div>');
getComponent().arrExpr = ['foo bar baz', 'foo1 bar1 baz1'];
@ -203,7 +205,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
});
describe('expressions evaluating to sets', () => {
it('should add and remove classes if the set instance changed', async(() => {
it('should add and remove classes if the set instance changed', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="setExpr"></div>');
let setExpr = new Set<string>();
setExpr.add('bar');
@ -218,12 +220,12 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
});
describe('expressions evaluating to string', () => {
it('should add classes specified in a string literal', async(() => {
it('should add classes specified in a string literal', waitForAsync(() => {
fixture = createTestComponent(`<div [ngClass]="'foo bar foo-bar fooBar'"></div>`);
detectChangesAndExpectClassName('foo bar foo-bar fooBar');
}));
it('should add and remove classes based on changes to the expression', async(() => {
it('should add and remove classes based on changes to the expression', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="strExpr"></div>');
detectChangesAndExpectClassName('foo');
@ -235,7 +237,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('baz');
}));
it('should remove active classes when switching from string to null', async(() => {
it('should remove active classes when switching from string to null', waitForAsync(() => {
fixture = createTestComponent(`<div [ngClass]="strExpr"></div>`);
detectChangesAndExpectClassName('foo');
@ -244,7 +246,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should take initial classes into account when switching from string to null',
async(() => {
waitForAsync(() => {
fixture = createTestComponent(`<div class="foo" [ngClass]="strExpr"></div>`);
detectChangesAndExpectClassName('foo');
@ -252,7 +254,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('foo');
}));
it('should ignore empty and blank strings', async(() => {
it('should ignore empty and blank strings', waitForAsync(() => {
fixture = createTestComponent(`<div class="foo" [ngClass]="strExpr"></div>`);
getComponent().strExpr = '';
detectChangesAndExpectClassName('foo');
@ -260,7 +262,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
});
describe('cooperation with other class-changing constructs', () => {
it('should co-operate with the class attribute', async(() => {
it('should co-operate with the class attribute', waitForAsync(() => {
fixture = createTestComponent('<div [ngClass]="objExpr" class="init foo"></div>');
const objExpr = getComponent().objExpr;
@ -274,7 +276,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName('init foo');
}));
it('should co-operate with the interpolated class attribute', async(() => {
it('should co-operate with the interpolated class attribute', waitForAsync(() => {
fixture = createTestComponent(`<div [ngClass]="objExpr" class="{{'init foo'}}"></div>`);
const objExpr = getComponent().objExpr;
@ -289,7 +291,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should co-operate with the interpolated class attribute when interpolation changes',
async(() => {
waitForAsync(() => {
fixture = createTestComponent(
`<div [ngClass]="{large: false, small: true}" class="{{strExpr}}"></div>`);
@ -299,7 +301,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName(`bar small`);
}));
it('should co-operate with the class attribute and binding to it', async(() => {
it('should co-operate with the class attribute and binding to it', waitForAsync(() => {
fixture =
createTestComponent(`<div [ngClass]="objExpr" class="init" [class]="'foo'"></div>`);
const objExpr = getComponent().objExpr;
@ -314,7 +316,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
detectChangesAndExpectClassName(`init foo`);
}));
it('should co-operate with the class attribute and class.name binding', async(() => {
it('should co-operate with the class attribute and class.name binding', waitForAsync(() => {
const template =
'<div class="init foo" [ngClass]="objExpr" [class.baz]="condition"></div>';
fixture = createTestComponent(template);
@ -333,7 +335,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should co-operate with initial class and class attribute binding when binding changes',
async(() => {
waitForAsync(() => {
const template = '<div class="init" [ngClass]="objExpr" [class]="strExpr"></div>';
fixture = createTestComponent(template);
const cmp = getComponent();

View File

@ -9,7 +9,7 @@
import {CommonModule} from '@angular/common';
import {NgComponentOutlet} from '@angular/common/src/directives/ng_component_outlet';
import {Compiler, Component, ComponentRef, Inject, InjectionToken, Injector, NgModule, NgModuleFactory, NO_ERRORS_SCHEMA, Optional, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
describe('insert/remove', () => {
@ -17,7 +17,7 @@ describe('insert/remove', () => {
TestBed.configureTestingModule({imports: [TestModule]});
});
it('should do nothing if component is null', async(() => {
it('should do nothing if component is null', waitForAsync(() => {
const template = `<ng-template *ngComponentOutlet="currentComponent"></ng-template>`;
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
@ -28,7 +28,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('');
}));
it('should insert content specified by a component', async(() => {
it('should insert content specified by a component', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
@ -40,7 +40,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('foo');
}));
it('should emit a ComponentRef once a component was created', async(() => {
it('should emit a ComponentRef once a component was created', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
@ -56,7 +56,7 @@ describe('insert/remove', () => {
}));
it('should clear view if component becomes null', async(() => {
it('should clear view if component becomes null', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
@ -74,7 +74,7 @@ describe('insert/remove', () => {
}));
it('should swap content if component changes', async(() => {
it('should swap content if component changes', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
@ -91,7 +91,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('bar');
}));
it('should use the injector, if one supplied', async(() => {
it('should use the injector, if one supplied', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
const uniqueValue = {};
@ -107,7 +107,7 @@ describe('insert/remove', () => {
}));
it('should resolve with an injector', async(() => {
it('should resolve with an injector', waitForAsync(() => {
let fixture = TestBed.createComponent(TestComponent);
// We are accessing a ViewChild (ngComponentOutlet) before change detection has run
@ -120,7 +120,7 @@ describe('insert/remove', () => {
expect(cmpRef.instance.testToken).toBeNull();
}));
it('should render projectable nodes, if supplied', async(() => {
it('should render projectable nodes, if supplied', waitForAsync(() => {
const template = `<ng-template>projected foo</ng-template>${TEST_CMP_TEMPLATE}`;
TestBed.overrideComponent(TestComponent, {set: {template: template}})
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]});
@ -144,7 +144,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('projected foo');
}));
it('should resolve components from other modules, if supplied', async(() => {
it('should resolve components from other modules, if supplied', waitForAsync(() => {
const compiler = TestBed.inject(Compiler);
let fixture = TestBed.createComponent(TestComponent);
@ -158,7 +158,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('baz');
}));
it('should clean up moduleRef, if supplied', async(() => {
it('should clean up moduleRef, if supplied', waitForAsync(() => {
let destroyed = false;
const compiler = TestBed.inject(Compiler);
const fixture = TestBed.createComponent(TestComponent);
@ -174,7 +174,7 @@ describe('insert/remove', () => {
expect(moduleRef.destroy).toHaveBeenCalled();
}));
it('should not re-create moduleRef when it didn\'t actually change', async(() => {
it('should not re-create moduleRef when it didn\'t actually change', waitForAsync(() => {
const compiler = TestBed.inject(Compiler);
const fixture = TestBed.createComponent(TestComponent);
@ -191,7 +191,7 @@ describe('insert/remove', () => {
expect(moduleRef).toBe(fixture.componentInstance.ngComponentOutlet['_moduleRef']);
}));
it('should re-create moduleRef when changed', async(() => {
it('should re-create moduleRef when changed', waitForAsync(() => {
const compiler = TestBed.inject(Compiler);
const fixture = TestBed.createComponent(TestComponent);
fixture.componentInstance.module = compiler.compileModuleSync(TestModule2);

View File

@ -8,7 +8,7 @@
import {CommonModule} from '@angular/common';
import {Component} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -38,27 +38,27 @@ let thisArg: any;
});
});
it('should reflect initial elements', async(() => {
it('should reflect initial elements', waitForAsync(() => {
fixture = createTestComponent();
detectChangesAndExpectText('1;2;');
}));
it('should reflect added elements', async(() => {
it('should reflect added elements', waitForAsync(() => {
fixture = createTestComponent();
fixture.detectChanges();
getComponent().items.push(3);
detectChangesAndExpectText('1;2;3;');
}));
it('should reflect removed elements', async(() => {
it('should reflect removed elements', waitForAsync(() => {
fixture = createTestComponent();
fixture.detectChanges();
getComponent().items.splice(1, 1);
detectChangesAndExpectText('1;');
}));
it('should reflect moved elements', async(() => {
it('should reflect moved elements', waitForAsync(() => {
fixture = createTestComponent();
fixture.detectChanges();
getComponent().items.splice(0, 1);
@ -66,7 +66,7 @@ let thisArg: any;
detectChangesAndExpectText('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)', waitForAsync(() => {
fixture = createTestComponent();
getComponent().items = [0, 1, 2, 3, 4, 5];
@ -77,7 +77,7 @@ let thisArg: any;
detectChangesAndExpectText('6;2;7;0;4;8;');
}));
it('should iterate over an array of objects', async(() => {
it('should iterate over an array of objects', waitForAsync(() => {
const template = '<ul><li *ngFor="let item of items">{{item["name"]}};</li></ul>';
fixture = createTestComponent(template);
@ -95,14 +95,14 @@ let thisArg: any;
detectChangesAndExpectText('shyam;');
}));
it('should gracefully handle nulls', async(() => {
it('should gracefully handle nulls', waitForAsync(() => {
const template = '<ul><li *ngFor="let item of null">{{item}};</li></ul>';
fixture = createTestComponent(template);
detectChangesAndExpectText('');
}));
it('should gracefully handle ref changing to null and back', async(() => {
it('should gracefully handle ref changing to null and back', waitForAsync(() => {
fixture = createTestComponent();
detectChangesAndExpectText('1;2;');
@ -114,7 +114,7 @@ let thisArg: any;
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', waitForAsync(() => {
fixture = createTestComponent();
getComponent().items = <any>'whaaa';
@ -123,7 +123,7 @@ let thisArg: any;
/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', waitForAsync(() => {
fixture = createTestComponent();
detectChangesAndExpectText('1;2;');
@ -132,7 +132,7 @@ let thisArg: any;
expect(() => fixture.detectChanges()).toThrowError();
}));
it('should works with duplicates', async(() => {
it('should works with duplicates', waitForAsync(() => {
fixture = createTestComponent();
const a = new Foo();
@ -140,7 +140,7 @@ let thisArg: any;
detectChangesAndExpectText('foo;foo;');
}));
it('should repeat over nested arrays', async(() => {
it('should repeat over nested arrays', waitForAsync(() => {
const template = '<div *ngFor="let item of items">' +
'<div *ngFor="let subitem of item">{{subitem}}-{{item.length}};</div>|' +
'</div>';
@ -153,7 +153,7 @@ let thisArg: any;
detectChangesAndExpectText('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', waitForAsync(() => {
const template = '<div *ngFor="let item of items">' +
'<div *ngFor="let subitem of item">{{subitem}}-{{item.length}};</div>' +
'</div>';
@ -166,7 +166,8 @@ let thisArg: any;
detectChangesAndExpectText('e-1;f-2;g-2;');
}));
it('should repeat over nested ngIf that are the last node in the ngFor template', async(() => {
it('should repeat over nested ngIf that are the last node in the ngFor template',
waitForAsync(() => {
const template = `<div *ngFor="let item of items; let i=index">` +
`<div>{{i}}|</div>` +
`<div *ngIf="i % 2 == 0">even|</div>` +
@ -185,7 +186,7 @@ let thisArg: any;
detectChangesAndExpectText('0|even|1|2|even|');
}));
it('should allow of saving the collection', async(() => {
it('should allow of saving the collection', waitForAsync(() => {
const template =
'<ul><li *ngFor="let item of items as collection; index as i">{{i}}/{{collection.length}} - {{item}};</li></ul>';
fixture = createTestComponent(template);
@ -196,7 +197,7 @@ let thisArg: any;
detectChangesAndExpectText('0/3 - 1;1/3 - 2;2/3 - 3;');
}));
it('should display indices correctly', async(() => {
it('should display indices correctly', waitForAsync(() => {
const template = '<span *ngFor ="let item of items; let i=index">{{i.toString()}}</span>';
fixture = createTestComponent(template);
@ -207,7 +208,7 @@ let thisArg: any;
detectChangesAndExpectText('0123456789');
}));
it('should display count correctly', async(() => {
it('should display count correctly', waitForAsync(() => {
const template = '<span *ngFor="let item of items; let len=count">{{len}}</span>';
fixture = createTestComponent(template);
@ -218,7 +219,7 @@ let thisArg: any;
detectChangesAndExpectText('666666');
}));
it('should display first item correctly', async(() => {
it('should display first item correctly', waitForAsync(() => {
const template =
'<span *ngFor="let item of items; let isFirst=first">{{isFirst.toString()}}</span>';
fixture = createTestComponent(template);
@ -230,7 +231,7 @@ let thisArg: any;
detectChangesAndExpectText('truefalse');
}));
it('should display last item correctly', async(() => {
it('should display last item correctly', waitForAsync(() => {
const template =
'<span *ngFor="let item of items; let isLast=last">{{isLast.toString()}}</span>';
fixture = createTestComponent(template);
@ -242,7 +243,7 @@ let thisArg: any;
detectChangesAndExpectText('falsetrue');
}));
it('should display even items correctly', async(() => {
it('should display even items correctly', waitForAsync(() => {
const template =
'<span *ngFor="let item of items; let isEven=even">{{isEven.toString()}}</span>';
fixture = createTestComponent(template);
@ -254,7 +255,7 @@ let thisArg: any;
detectChangesAndExpectText('truefalse');
}));
it('should display odd items correctly', async(() => {
it('should display odd items correctly', waitForAsync(() => {
const template =
'<span *ngFor="let item of items; let isOdd=odd">{{isOdd.toString()}}</span>';
fixture = createTestComponent(template);
@ -266,7 +267,7 @@ let thisArg: any;
detectChangesAndExpectText('falsetrue');
}));
it('should allow to use a custom template', async(() => {
it('should allow to use a custom template', waitForAsync(() => {
const template =
'<ng-container *ngFor="let item of items; template: tpl"></ng-container>' +
'<ng-template let-item let-i="index" #tpl><p>{{i}}: {{item}};</p></ng-template>';
@ -276,7 +277,7 @@ let thisArg: any;
detectChangesAndExpectText('0: a;1: b;2: c;');
}));
it('should use a default template if a custom one is null', async(() => {
it('should use a default template if a custom one is null', waitForAsync(() => {
const template =
`<ul><ng-container *ngFor="let item of items; template: null; let i=index">{{i}}: {{item}};</ng-container></ul>`;
fixture = createTestComponent(template);
@ -285,7 +286,8 @@ let thisArg: any;
detectChangesAndExpectText('0: a;1: b;2: c;');
}));
it('should use a custom template when both default and a custom one are present', async(() => {
it('should use a custom template when both default and a custom one are present',
waitForAsync(() => {
const template =
'<ng-container *ngFor="let item of items; template: tpl">{{i}};</ng-container>' +
'<ng-template let-item let-i="index" #tpl>{{i}}: {{item}};</ng-template>';
@ -296,7 +298,7 @@ let thisArg: any;
}));
describe('track by', () => {
it('should console.warn if trackBy is not a function', async(() => {
it('should console.warn if trackBy is not a function', waitForAsync(() => {
// TODO(vicb): expect a warning message when we have a proper log service
const template = `<p *ngFor="let item of items; trackBy: value"></p>`;
fixture = createTestComponent(template);
@ -304,7 +306,7 @@ let thisArg: any;
fixture.detectChanges();
}));
it('should track by identity when trackBy is to `null` or `undefined`', async(() => {
it('should track by identity when trackBy is to `null` or `undefined`', waitForAsync(() => {
// TODO(vicb): expect no warning message when we have a proper log service
const template = `<p *ngFor="let item of items; trackBy: value">{{ item }}</p>`;
fixture = createTestComponent(template);
@ -315,7 +317,7 @@ let thisArg: any;
detectChangesAndExpectText('abc');
}));
it('should set the context to the component instance', async(() => {
it('should set the context to the component instance', waitForAsync(() => {
const template =
`<p *ngFor="let item of items; trackBy: trackByContext.bind(this)"></p>`;
fixture = createTestComponent(template);
@ -325,7 +327,7 @@ let thisArg: any;
expect(thisArg).toBe(getComponent());
}));
it('should not replace tracked items', async(() => {
it('should not replace tracked items', waitForAsync(() => {
const template =
`<p *ngFor="let item of items; trackBy: trackById; let i=index">{{items[i]}}</p>`;
fixture = createTestComponent(template);
@ -341,7 +343,7 @@ let thisArg: any;
expect(finalP.nativeElement).toBe(firstP.nativeElement);
}));
it('should update implicit local variable on view', async(() => {
it('should update implicit local variable on view', waitForAsync(() => {
const template =
`<div *ngFor="let item of items; trackBy: trackById">{{item['color']}}</div>`;
fixture = createTestComponent(template);
@ -353,7 +355,7 @@ let thisArg: any;
detectChangesAndExpectText('red');
}));
it('should move items around and keep them updated ', async(() => {
it('should move items around and keep them updated ', waitForAsync(() => {
const template =
`<div *ngFor="let item of items; trackBy: trackById">{{item['color']}}</div>`;
fixture = createTestComponent(template);
@ -365,7 +367,8 @@ let thisArg: any;
detectChangesAndExpectText('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',
waitForAsync(() => {
const template = `<div *ngFor="let item of items; trackBy: trackByIndex">{{item}}</div>`;
fixture = createTestComponent(template);

View File

@ -8,7 +8,7 @@
import {CommonModule, ɵgetDOM as getDOM} from '@angular/common';
import {Component} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -31,7 +31,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
});
});
it('should work in a template attribute', async(() => {
it('should work in a template attribute', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition">hello</span>';
fixture = createTestComponent(template);
fixture.detectChanges();
@ -39,14 +39,14 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('hello');
}));
it('should work on a template element', async(() => {
it('should work on a template element', waitForAsync(() => {
const template = '<ng-template [ngIf]="booleanCondition">hello2</ng-template>';
fixture = createTestComponent(template);
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('hello2');
}));
it('should toggle node when condition changes', async(() => {
it('should toggle node when condition changes', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition">hello</span>';
fixture = createTestComponent(template);
getComponent().booleanCondition = false;
@ -65,7 +65,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('');
}));
it('should handle nested if correctly', async(() => {
it('should handle nested if correctly', waitForAsync(() => {
const template =
'<div *ngIf="booleanCondition"><span *ngIf="nestedBooleanCondition">hello</span></div>';
@ -97,7 +97,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('');
}));
it('should update several nodes with if', async(() => {
it('should update several nodes with if', waitForAsync(() => {
const template = '<span *ngIf="numberCondition + 1 >= 2">helloNumber</span>' +
'<span *ngIf="stringCondition == \'foo\'">helloString</span>' +
'<span *ngIf="functionCondition(stringCondition, numberCondition)">helloFunction</span>';
@ -120,7 +120,8 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('helloNumber');
}));
it('should not add the element twice if the condition goes from truthy to truthy', async(() => {
it('should not add the element twice if the condition goes from truthy to truthy',
waitForAsync(() => {
const template = '<span *ngIf="numberCondition">hello</span>';
fixture = createTestComponent(template);
@ -141,7 +142,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
}));
describe('then/else templates', () => {
it('should support else', async(() => {
it('should support else', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition; else elseBlock">TRUE</span>' +
'<ng-template #elseBlock>FALSE</ng-template>';
@ -155,7 +156,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('FALSE');
}));
it('should support then and else', async(() => {
it('should support then and else', waitForAsync(() => {
const template =
'<span *ngIf="booleanCondition; then thenBlock; else elseBlock">IGNORE</span>' +
'<ng-template #thenBlock>THEN</ng-template>' +
@ -202,7 +203,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('');
});
it('should support dynamic else', async(() => {
it('should support dynamic else', waitForAsync(() => {
const template =
'<span *ngIf="booleanCondition; else nestedBooleanCondition ? b1 : b2">TRUE</span>' +
'<ng-template #b1>FALSE1</ng-template>' +
@ -222,7 +223,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('FALSE2');
}));
it('should support binding to variable using let', async(() => {
it('should support binding to variable using let', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition; else elseBlock; let v">{{v}}</span>' +
'<ng-template #elseBlock let-v>{{v}}</ng-template>';
@ -236,7 +237,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('false');
}));
it('should support binding to variable using as', async(() => {
it('should support binding to variable using as', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition as v; else elseBlock">{{v}}</span>' +
'<ng-template #elseBlock let-v>{{v}}</ng-template>';
@ -252,7 +253,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
});
describe('Type guarding', () => {
it('should throw when then block is not template', async(() => {
it('should throw when then block is not template', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition; then thenBlock">IGNORE</span>' +
'<div #thenBlock>THEN</div>';
@ -262,7 +263,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
.toThrowError(/ngIfThen must be a TemplateRef, but received/);
}));
it('should throw when else block is not template', async(() => {
it('should throw when else block is not template', waitForAsync(() => {
const template = '<span *ngIf="booleanCondition; else elseBlock">IGNORE</span>' +
'<div #elseBlock>ELSE</div>';

View File

@ -8,7 +8,7 @@
import {CommonModule, NgLocalization} from '@angular/common';
import {Component, Injectable} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
{
@ -36,7 +36,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
});
});
it('should display the template according to the exact value', async(() => {
it('should display the template according to the exact value', waitForAsync(() => {
const template = '<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="=0"><li>you have no messages.</li></ng-template>' +
'<ng-template ngPluralCase="=1"><li>you have one message.</li></ng-template>' +
@ -51,7 +51,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
detectChangesAndExpectText('you have one message.');
}));
it('should display the template according to the exact numeric value', async(() => {
it('should display the template according to the exact numeric value', waitForAsync(() => {
const template = '<div>' +
'<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="0"><li>you have no messages.</li></ng-template>' +
@ -69,7 +69,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
// https://github.com/angular/angular/issues/9868
// https://github.com/angular/angular/issues/9882
it('should not throw when ngPluralCase contains expressions', async(() => {
it('should not throw when ngPluralCase contains expressions', waitForAsync(() => {
const template = '<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="=0"><li>{{ switchValue }}</li></ng-template>' +
'</ul>';
@ -81,7 +81,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
}));
it('should be applicable to <ng-container> elements', async(() => {
it('should be applicable to <ng-container> elements', waitForAsync(() => {
const template = '<ng-container [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="=0">you have no messages.</ng-template>' +
'<ng-template ngPluralCase="=1">you have one message.</ng-template>' +
@ -96,7 +96,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
detectChangesAndExpectText('you have one message.');
}));
it('should display the template according to the category', async(() => {
it('should display the template according to the category', waitForAsync(() => {
const template = '<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="few"><li>you have a few messages.</li></ng-template>' +
'<ng-template ngPluralCase="many"><li>you have many messages.</li></ng-template>' +
@ -111,7 +111,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
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', waitForAsync(() => {
const template = '<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="few"><li>you have a few messages.</li></ng-template>' +
'<ng-template ngPluralCase="other"><li>default message.</li></ng-template>' +
@ -123,7 +123,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
detectChangesAndExpectText('default message.');
}));
it('should prioritize value matches over category matches', async(() => {
it('should prioritize value matches over category matches', waitForAsync(() => {
const template = '<ul [ngPlural]="switchValue">' +
'<ng-template ngPluralCase="few"><li>you have a few messages.</li></ng-template>' +
'<ng-template ngPluralCase="=2">you have two messages.</ng-template>' +

View File

@ -8,7 +8,7 @@
import {CommonModule} from '@angular/common';
import {Component} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
{
describe('NgStyle', () => {
@ -30,14 +30,14 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
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', waitForAsync(() => {
const template = `<div [ngStyle]="{'max-width': '40px'}"></div>`;
fixture = createTestComponent(template);
fixture.detectChanges();
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', waitForAsync(() => {
const template = `<div [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);
@ -51,7 +51,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
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', waitForAsync(() => {
const template = `<div [ngStyle]="{'max-width.px': expr}"></div>`;
fixture = createTestComponent(template);
@ -66,7 +66,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
// https://github.com/angular/angular/issues/21064
it('should add and remove styles which names are not dash-cased', async(() => {
it('should add and remove styles which names are not dash-cased', waitForAsync(() => {
fixture = createTestComponent(`<div [ngStyle]="{'color': expr}"></div>`);
getComponent().expr = 'green';
@ -78,7 +78,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
expectNativeEl(fixture).not.toHaveCssStyle('color');
}));
it('should update styles using style.unit notation when unit changes', async(() => {
it('should update styles using style.unit notation when unit changes', waitForAsync(() => {
const template = `<div [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);
@ -93,7 +93,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
// keyValueDiffer is sensitive to key order #9115
it('should change styles specified in an object expression', async(() => {
it('should change styles specified in an object expression', waitForAsync(() => {
const template = `<div [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);
@ -117,7 +117,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
expectNativeEl(fixture).toHaveCssStyle({'height': '5px', 'width': '5px'});
}));
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', waitForAsync(() => {
const template = `<div [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);
@ -131,7 +131,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
expectNativeEl(fixture).not.toHaveCssStyle('max-width');
}));
it('should co-operate with the style attribute', async(() => {
it('should co-operate with the style attribute', waitForAsync(() => {
const template = `<div style="font-size: 12px" [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);
@ -147,7 +147,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
}));
it('should co-operate with the style.[styleName]="expr" special-case in the compiler',
async(() => {
waitForAsync(() => {
const template = `<div [style.font-size.px]="12" [ngStyle]="expr"></div>`;
fixture = createTestComponent(template);

View File

@ -8,7 +8,7 @@
import {CommonModule} from '@angular/common';
import {Component, ContentChildren, Directive, Injectable, NO_ERRORS_SCHEMA, OnDestroy, QueryList, TemplateRef} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
describe('NgTemplateOutlet', () => {
@ -36,7 +36,7 @@ describe('NgTemplateOutlet', () => {
});
// https://github.com/angular/angular/issues/14778
it('should accept the component as the context', async(() => {
it('should accept the component as the context', waitForAsync(() => {
const template = `<ng-container *ngTemplateOutlet="tpl; context: this"></ng-container>` +
`<ng-template #tpl>{{context.foo}}</ng-template>`;
@ -44,20 +44,20 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('bar');
}));
it('should do nothing if templateRef is `null`', async(() => {
it('should do nothing if templateRef is `null`', waitForAsync(() => {
const template = `<ng-container [ngTemplateOutlet]="null"></ng-container>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('');
}));
it('should insert content specified by TemplateRef', async(() => {
it('should insert content specified by TemplateRef', waitForAsync(() => {
const template = `<ng-template #tpl>foo</ng-template>` +
`<ng-container [ngTemplateOutlet]="tpl"></ng-container>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('foo');
}));
it('should clear content if TemplateRef becomes `null`', async(() => {
it('should clear content if TemplateRef becomes `null`', waitForAsync(() => {
const template = `<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template></tpl-refs>` +
`<ng-container [ngTemplateOutlet]="currentTplRef"></ng-container>`;
fixture = createTestComponent(template);
@ -71,7 +71,7 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('');
}));
it('should swap content if TemplateRef changes', async(() => {
it('should swap content if TemplateRef changes', waitForAsync(() => {
const template =
`<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template><ng-template>bar</ng-template></tpl-refs>` +
`<ng-container [ngTemplateOutlet]="currentTplRef"></ng-container>`;
@ -87,14 +87,14 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('bar');
}));
it('should display template if context is `null`', async(() => {
it('should display template if context is `null`', waitForAsync(() => {
const template = `<ng-template #tpl>foo</ng-template>` +
`<ng-container *ngTemplateOutlet="tpl; context: null"></ng-container>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('foo');
}));
it('should reflect initial context and changes', async(() => {
it('should reflect initial context and changes', waitForAsync(() => {
const template = `<ng-template let-foo="foo" #tpl>{{foo}}</ng-template>` +
`<ng-container *ngTemplateOutlet="tpl; context: context"></ng-container>`;
fixture = createTestComponent(template);
@ -106,7 +106,7 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('alter-bar');
}));
it('should reflect user defined `$implicit` property in the context', async(() => {
it('should reflect user defined `$implicit` property in the context', waitForAsync(() => {
const template = `<ng-template let-ctx #tpl>{{ctx.foo}}</ng-template>` +
`<ng-container *ngTemplateOutlet="tpl; context: context"></ng-container>`;
fixture = createTestComponent(template);
@ -114,7 +114,7 @@ describe('NgTemplateOutlet', () => {
detectChangesAndExpectText('bra');
}));
it('should reflect context re-binding', async(() => {
it('should reflect context re-binding', waitForAsync(() => {
const template = `<ng-template let-shawshank="shawshank" #tpl>{{shawshank}}</ng-template>` +
`<ng-container *ngTemplateOutlet="tpl; context: context"></ng-container>`;
fixture = createTestComponent(template);
@ -222,7 +222,8 @@ describe('NgTemplateOutlet', () => {
}).not.toThrow();
});
it('should not throw when switching from template to null and back to template', async(() => {
it('should not throw when switching from template to null and back to template',
waitForAsync(() => {
const template = `<tpl-refs #refs="tplRefs"><ng-template>foo</ng-template></tpl-refs>` +
`<ng-container [ngTemplateOutlet]="currentTplRef"></ng-container>`;
fixture = createTestComponent(template);

View File

@ -9,7 +9,7 @@
import {ɵgetDOM as getDOM} from '@angular/common';
import {Component, Directive} from '@angular/core';
import {ElementRef} from '@angular/core/src/linker/element_ref';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {hasClass} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -21,7 +21,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
});
});
it('should not interpolate children', async(() => {
it('should not interpolate children', waitForAsync(() => {
const template = '<div>{{text}}<span ngNonBindable>{{text}}</span></div>';
const fixture = createTestComponent(template);
@ -29,7 +29,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(fixture.nativeElement).toHaveText('foo{{text}}');
}));
it('should ignore directives on child nodes', async(() => {
it('should ignore directives on child nodes', waitForAsync(() => {
const template = '<div ngNonBindable><span id=child test-dec>{{text}}</span></div>';
const fixture = createTestComponent(template);
fixture.detectChanges();
@ -40,7 +40,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
expect(hasClass(span, 'compiled')).toBeFalsy();
}));
it('should trigger directives on the same node', async(() => {
it('should trigger directives on the same node', waitForAsync(() => {
const template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>';
const fixture = createTestComponent(template);
fixture.detectChanges();

View File

@ -8,7 +8,7 @@
import {CommonModule, JsonPipe} from '@angular/common';
import {Component} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
{
@ -64,7 +64,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
TestBed.configureTestingModule({declarations: [TestComp], imports: [CommonModule]});
});
it('should work with mutable objects', async(() => {
it('should work with mutable objects', waitForAsync(() => {
const fixture = TestBed.createComponent(TestComp);
const mutable: number[] = [1];
fixture.componentInstance.data = mutable;

View File

@ -8,7 +8,7 @@
import {CommonModule, SlicePipe} from '@angular/common';
import {Component} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
{
@ -105,7 +105,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
TestBed.configureTestingModule({declarations: [TestComp], imports: [CommonModule]});
});
it('should work with mutable arrays', async(() => {
it('should work with mutable arrays', waitForAsync(() => {
const fixture = TestBed.createComponent(TestComp);
const mutable: number[] = [1, 2];
fixture.componentInstance.data = mutable;

View File

@ -7,15 +7,15 @@
*/
import {Xliff2} from '@angular/compiler/src/i18n/serializers/xliff2';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {configureCompiler, createComponent, HTML, serializeTranslations, validateHtml} from './integration_common';
describe('i18n XLIFF integration spec', () => {
describe('(with LF line endings)', () => {
beforeEach(
async(() => configureCompiler(XLIFF2_TOMERGE + LF_LINE_ENDING_XLIFF2_TOMERGE, 'xlf2')));
beforeEach(waitForAsync(
() => configureCompiler(XLIFF2_TOMERGE + LF_LINE_ENDING_XLIFF2_TOMERGE, 'xlf2')));
it('should extract from templates', () => {
const serializer = new Xliff2();
@ -34,8 +34,8 @@ describe('i18n XLIFF integration spec', () => {
});
describe('(with CRLF line endings', () => {
beforeEach(
async(() => configureCompiler(XLIFF2_TOMERGE + CRLF_LINE_ENDING_XLIFF2_TOMERGE, 'xlf2')));
beforeEach(waitForAsync(
() => configureCompiler(XLIFF2_TOMERGE + CRLF_LINE_ENDING_XLIFF2_TOMERGE, 'xlf2')));
it('should extract from templates (with CRLF line endings)', () => {
const serializer = new Xliff2();

View File

@ -7,14 +7,15 @@
*/
import {Xliff} from '@angular/compiler/src/i18n/serializers/xliff';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {configureCompiler, createComponent, HTML, serializeTranslations, validateHtml} from './integration_common';
describe('i18n XLIFF integration spec', () => {
describe('(with LF line endings)', () => {
beforeEach(async(() => configureCompiler(XLIFF_TOMERGE + LF_LINE_ENDING_XLIFF_TOMERGE, 'xlf')));
beforeEach(
waitForAsync(() => configureCompiler(XLIFF_TOMERGE + LF_LINE_ENDING_XLIFF_TOMERGE, 'xlf')));
it('should extract from templates', () => {
const serializer = new Xliff();
@ -33,8 +34,8 @@ describe('i18n XLIFF integration spec', () => {
});
describe('(with CRLF line endings', () => {
beforeEach(
async(() => configureCompiler(XLIFF_TOMERGE + CRLF_LINE_ENDING_XLIFF_TOMERGE, 'xlf')));
beforeEach(waitForAsync(
() => configureCompiler(XLIFF_TOMERGE + CRLF_LINE_ENDING_XLIFF_TOMERGE, 'xlf')));
it('should extract from templates (with CRLF line endings)', () => {
const serializer = new Xliff();

View File

@ -7,14 +7,14 @@
*/
import {Xmb} from '@angular/compiler/src/i18n/serializers/xmb';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {configureCompiler, createComponent, HTML, serializeTranslations, validateHtml} from './integration_common';
describe('i18n XMB/XTB integration spec', () => {
describe('(with LF line endings)', () => {
beforeEach(async(() => configureCompiler(XTB + LF_LINE_ENDING_XTB, 'xtb')));
beforeEach(waitForAsync(() => configureCompiler(XTB + LF_LINE_ENDING_XTB, 'xtb')));
it('should extract from templates', () => {
const serializer = new Xmb();
@ -33,7 +33,7 @@ describe('i18n XMB/XTB integration spec', () => {
});
describe('(with CRLF line endings', () => {
beforeEach(async(() => configureCompiler(XTB + CRLF_LINE_ENDING_XTB, 'xtb')));
beforeEach(waitForAsync(() => configureCompiler(XTB + CRLF_LINE_ENDING_XTB, 'xtb')));
it('should extract from templates (with CRLF line endings)', () => {
const serializer = new Xmb();

View File

@ -7,7 +7,7 @@
*/
import {Component, Directive, Input} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -17,7 +17,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
let fixture: ComponentFixture<TestComponent>;
describe('directives', () => {
it('should support dotted selectors', async(() => {
it('should support dotted selectors', waitForAsync(() => {
@Directive({selector: '[dot.name]'})
class MyDir {
// TODO(issue/24571): remove '!'.
@ -41,7 +41,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
describe('ng-container', () => {
if (browserDetection.isChromeDesktop) {
it('should work regardless the namespace', async(() => {
it('should work regardless the namespace', waitForAsync(() => {
@Component({
selector: 'comp',
template:

View File

@ -8,7 +8,7 @@
import {LIFECYCLE_HOOKS_VALUES, LifecycleHooks} from '@angular/compiler/src/lifecycle_reflector';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, Directive, DoCheck, Injectable, NgModule, OnChanges, OnDestroy, OnInit, Pipe, SimpleChanges, ViewEncapsulation, ɵstringify as stringify} from '@angular/core';
import {async, inject, TestBed} from '@angular/core/testing';
import {inject, TestBed, waitForAsync} from '@angular/core/testing';
import {CompileDiDependencyMetadata, identifierName} from '../src/compile_metadata';
import {CompileMetadataResolver} from '../src/metadata_resolver';
@ -77,7 +77,7 @@ import {TEST_COMPILER_PROVIDERS} from './test_bindings';
}));
it('should read external metadata when sync=false',
async(inject(
waitForAsync(inject(
[CompileMetadataResolver, ResourceLoader],
(resolver: CompileMetadataResolver, resourceLoader: MockResourceLoader) => {
@NgModule({declarations: [ComponentWithExternalResources]})
@ -96,7 +96,7 @@ import {TEST_COMPILER_PROVIDERS} from './test_bindings';
})));
it('should use `./` as base url for templates during runtime compilation if no moduleId is given',
async(inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
waitForAsync(inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@Component({selector: 'someComponent', templateUrl: 'someUrl'})
class ComponentWithoutModuleId {
}

View File

@ -8,7 +8,7 @@
import {DirectiveResolver, ResourceLoader} from '@angular/compiler';
import {Compiler, Component, Injector, NgModule, NgModuleFactory, ɵstringify as stringify} from '@angular/core';
import {async, fakeAsync, inject, TestBed, tick} from '@angular/core/testing';
import {fakeAsync, inject, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {MockDirectiveResolver} from '../testing';
@ -42,7 +42,8 @@ class SomeCompWithUrlTemplate {
{providers: [{provide: ResourceLoader, useClass: StubResourceLoader, deps: []}]});
});
it('should throw when using a templateUrl that has not been compiled before', async(() => {
it('should throw when using a templateUrl that has not been compiled before',
waitForAsync(() => {
TestBed.configureTestingModule({declarations: [SomeCompWithUrlTemplate]});
TestBed.compileComponents().then(() => {
expect(() => TestBed.createComponent(SomeCompWithUrlTemplate))
@ -76,7 +77,8 @@ class SomeCompWithUrlTemplate {
{providers: [{provide: ResourceLoader, useClass: StubResourceLoader, deps: []}]});
});
it('should allow to use templateUrl components that have been loaded before', async(() => {
it('should allow to use templateUrl components that have been loaded before',
waitForAsync(() => {
TestBed.configureTestingModule({declarations: [SomeCompWithUrlTemplate]});
TestBed.compileComponents().then(() => {
const fixture = TestBed.createComponent(SomeCompWithUrlTemplate);

View File

@ -8,7 +8,7 @@
import {CommonModule} from '@angular/common';
import {Component, Directive, forwardRef, Inject, Injectable, InjectionToken, Injector, NgModule, Optional} from '@angular/core';
import {async, inject, TestBed} from '@angular/core/testing';
import {inject, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {modifiedInIvy, onlyInIvy} from '@angular/private/testing';
@ -603,7 +603,7 @@ describe('providers', () => {
});
it('should support injecting without bootstrapping',
async(inject([MyComp, MyService], (comp: MyComp, service: MyService) => {
waitForAsync(inject([MyComp, MyService], (comp: MyComp, service: MyService) => {
expect(comp.svc.value).toEqual('some value');
})));
});

View File

@ -8,19 +8,19 @@
import {Injector} from '@angular/core';
import {APP_INITIALIZER, ApplicationInitStatus} from '@angular/core/src/application_init';
import {async, inject, TestBed} from '../testing';
import {inject, TestBed, waitForAsync} from '../testing';
{
describe('ApplicationInitStatus', () => {
describe('no initializers', () => {
it('should return true for `done`',
async(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
waitForAsync(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
(status as any).runInitializers();
expect(status.done).toBe(true);
})));
it('should return a promise that resolves immediately for `donePromise`',
async(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
waitForAsync(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
(status as any).runInitializers();
status.donePromise.then(() => {
expect(status.done).toBe(true);
@ -58,7 +58,7 @@ import {async, inject, TestBed} from '../testing';
});
it('should update the status once all async initializers are done',
async(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
waitForAsync(inject([ApplicationInitStatus], (status: ApplicationInitStatus) => {
(status as any).runInitializers();
setTimeout(() => {

View File

@ -19,7 +19,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
import {onlyInIvy} from '@angular/private/testing';
import {NoopNgZone} from '../src/zone/ng_zone';
import {async, ComponentFixtureNoNgZone, inject, TestBed, withModule} from '../testing';
import {ComponentFixtureNoNgZone, inject, TestBed, waitForAsync, withModule} from '../testing';
@Component({selector: 'bootstrap-app', template: 'hello'})
class SomeComponent {
@ -79,62 +79,66 @@ class SomeComponent {
}
it('should bootstrap a component from a child module',
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({
selector: 'bootstrap-app',
template: '',
})
class SomeComponent {
}
waitForAsync(
inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({
selector: 'bootstrap-app',
template: '',
})
class SomeComponent {
}
const helloToken = new InjectionToken<string>('hello');
const helloToken = new InjectionToken<string>('hello');
@NgModule({
providers: [{provide: helloToken, useValue: 'component'}],
declarations: [SomeComponent],
entryComponents: [SomeComponent],
})
class SomeModule {
}
@NgModule({
providers: [{provide: helloToken, useValue: 'component'}],
declarations: [SomeComponent],
entryComponents: [SomeComponent],
})
class SomeModule {
}
createRootEl();
const modFactory = compiler.compileModuleSync(SomeModule);
const module = modFactory.create(TestBed);
const cmpFactory = module.componentFactoryResolver.resolveComponentFactory(SomeComponent)!;
const component = app.bootstrap(cmpFactory);
createRootEl();
const modFactory = compiler.compileModuleSync(SomeModule);
const module = modFactory.create(TestBed);
const cmpFactory =
module.componentFactoryResolver.resolveComponentFactory(SomeComponent)!;
const component = app.bootstrap(cmpFactory);
// The component should see the child module providers
expect(component.injector.get(helloToken)).toEqual('component');
})));
// The component should see the child module providers
expect(component.injector.get(helloToken)).toEqual('component');
})));
it('should bootstrap a component with a custom selector',
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({
selector: 'bootstrap-app',
template: '',
})
class SomeComponent {
}
waitForAsync(
inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({
selector: 'bootstrap-app',
template: '',
})
class SomeComponent {
}
const helloToken = new InjectionToken<string>('hello');
const helloToken = new InjectionToken<string>('hello');
@NgModule({
providers: [{provide: helloToken, useValue: 'component'}],
declarations: [SomeComponent],
entryComponents: [SomeComponent],
})
class SomeModule {
}
@NgModule({
providers: [{provide: helloToken, useValue: 'component'}],
declarations: [SomeComponent],
entryComponents: [SomeComponent],
})
class SomeModule {
}
createRootEl('custom-selector');
const modFactory = compiler.compileModuleSync(SomeModule);
const module = modFactory.create(TestBed);
const cmpFactory = module.componentFactoryResolver.resolveComponentFactory(SomeComponent)!;
const component = app.bootstrap(cmpFactory, 'custom-selector');
createRootEl('custom-selector');
const modFactory = compiler.compileModuleSync(SomeModule);
const module = modFactory.create(TestBed);
const cmpFactory =
module.componentFactoryResolver.resolveComponentFactory(SomeComponent)!;
const component = app.bootstrap(cmpFactory, 'custom-selector');
// The component should see the child module providers
expect(component.injector.get(helloToken)).toEqual('component');
})));
// The component should see the child module providers
expect(component.injector.get(helloToken)).toEqual('component');
})));
describe('ApplicationRef', () => {
beforeEach(() => {
@ -216,7 +220,7 @@ class SomeComponent {
defaultPlatform = _platform;
}));
it('should wait for asynchronous app initializers', async(() => {
it('should wait for asynchronous app initializers', waitForAsync(() => {
let resolve: (result: any) => void;
const promise: Promise<any> = new Promise((res) => {
resolve = res;
@ -235,7 +239,8 @@ class SomeComponent {
});
}));
it('should rethrow sync errors even if the exceptionHandler is not rethrowing', async(() => {
it('should rethrow sync errors even if the exceptionHandler is not rethrowing',
waitForAsync(() => {
defaultPlatform
.bootstrapModule(createModule([{
provide: APP_INITIALIZER,
@ -253,7 +258,7 @@ class SomeComponent {
}));
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
async(() => {
waitForAsync(() => {
defaultPlatform
.bootstrapModule(createModule([
{provide: APP_INITIALIZER, useValue: () => Promise.reject('Test'), multi: true}
@ -264,7 +269,7 @@ class SomeComponent {
});
}));
it('should throw useful error when ApplicationRef is not configured', async(() => {
it('should throw useful error when ApplicationRef is not configured', waitForAsync(() => {
@NgModule()
class EmptyModule {
}
@ -277,7 +282,7 @@ class SomeComponent {
}));
it('should call the `ngDoBootstrap` method with `ApplicationRef` on the main module',
async(() => {
waitForAsync(() => {
const ngDoBootstrap = jasmine.createSpy('ngDoBootstrap');
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: ngDoBootstrap}))
.then((moduleRef) => {
@ -286,7 +291,7 @@ class SomeComponent {
});
}));
it('should auto bootstrap components listed in @NgModule.bootstrap', async(() => {
it('should auto bootstrap components listed in @NgModule.bootstrap', waitForAsync(() => {
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
.then((moduleRef) => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
@ -295,7 +300,7 @@ class SomeComponent {
}));
it('should error if neither `ngDoBootstrap` nor @NgModule.bootstrap was specified',
async(() => {
waitForAsync(() => {
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: false}))
.then(() => expect(false).toBe(true), (e) => {
const expectedErrMsg =
@ -305,12 +310,12 @@ class SomeComponent {
});
}));
it('should add bootstrapped module into platform modules list', async(() => {
it('should add bootstrapped module into platform modules list', waitForAsync(() => {
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
.then(module => expect((<any>defaultPlatform)._modules).toContain(module));
}));
it('should bootstrap with NoopNgZone', async(() => {
it('should bootstrap with NoopNgZone', waitForAsync(() => {
defaultPlatform
.bootstrapModule(createModule({bootstrap: [SomeComponent]}), {ngZone: 'noop'})
.then((module) => {
@ -376,7 +381,7 @@ class SomeComponent {
createRootEl();
defaultPlatform = _platform;
}));
it('should wait for asynchronous app initializers', async(() => {
it('should wait for asynchronous app initializers', waitForAsync(() => {
let resolve: (result: any) => void;
const promise: Promise<any> = new Promise((res) => {
resolve = res;
@ -396,7 +401,8 @@ class SomeComponent {
});
}));
it('should rethrow sync errors even if the exceptionHandler is not rethrowing', async(() => {
it('should rethrow sync errors even if the exceptionHandler is not rethrowing',
waitForAsync(() => {
const compilerFactory: CompilerFactory =
defaultPlatform.injector.get(CompilerFactory, null)!;
const moduleFactory = compilerFactory.createCompiler().compileModuleSync(createModule([{
@ -413,7 +419,7 @@ class SomeComponent {
}));
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
async(() => {
waitForAsync(() => {
const compilerFactory: CompilerFactory =
defaultPlatform.injector.get(CompilerFactory, null)!;
const moduleFactory = compilerFactory.createCompiler().compileModuleSync(createModule(
@ -623,25 +629,25 @@ class SomeComponent {
});
}
it('isStable should fire on synchronous component loading', async(() => {
it('isStable should fire on synchronous component loading', waitForAsync(() => {
expectStableTexts(SyncComp, ['1']);
}));
it('isStable should fire after a microtask on init is completed', async(() => {
it('isStable should fire after a microtask on init is completed', waitForAsync(() => {
expectStableTexts(MicroTaskComp, ['11']);
}));
it('isStable should fire after a macrotask on init is completed', async(() => {
it('isStable should fire after a macrotask on init is completed', waitForAsync(() => {
expectStableTexts(MacroTaskComp, ['11']);
}));
it('isStable should fire only after chain of micro and macrotasks on init are completed',
async(() => {
waitForAsync(() => {
expectStableTexts(MicroMacroTaskComp, ['111']);
}));
it('isStable should fire only after chain of macro and microtasks on init are completed',
async(() => {
waitForAsync(() => {
expectStableTexts(MacroMicroTaskComp, ['111']);
}));
@ -665,7 +671,7 @@ class SomeComponent {
});
}
it('should be fired after app becomes unstable', async(() => {
it('should be fired after app becomes unstable', waitForAsync(() => {
const fixture = TestBed.createComponent(ClickComp);
const appRef: ApplicationRef = TestBed.inject(ApplicationRef);
const zone: NgZone = TestBed.inject(NgZone);

View File

@ -7,7 +7,7 @@
*/
import {Component, Injectable, Input} from '@angular/core';
import {async, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBed, withModule} from '@angular/core/testing';
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBed, waitForAsync, withModule} from '@angular/core/testing';
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -100,7 +100,7 @@ class NestedAsyncTimeoutComp {
{
describe('ComponentFixture', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
AutoDetectComp, AsyncComp, AsyncTimeoutComp, NestedAsyncTimeoutComp, AsyncChangeComp,
@ -134,7 +134,7 @@ class NestedAsyncTimeoutComp {
}));
it('should signal through whenStable when the fixture is stable (autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
@ -153,7 +153,7 @@ class NestedAsyncTimeoutComp {
}));
it('should signal through isStable when the fixture is stable (no autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.detectChanges();
@ -174,7 +174,7 @@ class NestedAsyncTimeoutComp {
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
@ -194,7 +194,7 @@ class NestedAsyncTimeoutComp {
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
@ -215,7 +215,7 @@ class NestedAsyncTimeoutComp {
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.autoDetectChanges();
@ -236,7 +236,7 @@ class NestedAsyncTimeoutComp {
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
waitForAsync(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
@ -255,7 +255,8 @@ class NestedAsyncTimeoutComp {
});
}));
it('should stabilize after async task in change detection (autoDetectChanges)', async(() => {
it('should stabilize after async task in change detection (autoDetectChanges)',
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.autoDetectChanges();
@ -271,7 +272,8 @@ class NestedAsyncTimeoutComp {
});
}));
it('should stabilize after async task in change detection(no autoDetectChanges)', async(() => {
it('should stabilize after async task in change detection(no autoDetectChanges)',
waitForAsync(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.detectChanges();
componentFixture.whenStable().then((_) => {
@ -306,7 +308,7 @@ class NestedAsyncTimeoutComp {
}).toThrowError(/Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set/);
});
it('should instantiate a component with valid DOM', async(() => {
it('should instantiate a component with valid DOM', waitForAsync(() => {
const componentFixture = TestBed.createComponent(SimpleComp);
expect(componentFixture.ngZone).toBeNull();
@ -314,7 +316,7 @@ class NestedAsyncTimeoutComp {
expect(componentFixture.nativeElement).toHaveText('Original Simple');
}));
it('should allow changing members of the component', async(() => {
it('should allow changing members of the component', waitForAsync(() => {
const componentFixture = TestBed.createComponent(MyIfComp);
componentFixture.detectChanges();

View File

@ -10,7 +10,7 @@
import {CommonModule, NgIfContext, ɵgetDOM as getDOM} from '@angular/common';
import {Component, DebugElement, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, OnInit, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {NgZone} from '@angular/core/src/zone';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {createMouseEvent, hasClass} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -264,7 +264,7 @@ class TestCmptWithPropInterpolation {
describe('debug element', () => {
let fixture: ComponentFixture<any>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
ChildComp,

View File

@ -17,7 +17,7 @@ import {TemplateRef} from '@angular/core/src/linker/template_ref';
import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
import {EmbeddedViewRef} from '@angular/core/src/linker/view_ref';
import {Attribute, Component, ContentChildren, Directive, HostBinding, HostListener, Input, Output, Pipe} from '@angular/core/src/metadata';
import {async, fakeAsync, getTestBed, TestBed, tick} from '@angular/core/testing';
import {fakeAsync, getTestBed, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {createMouseEvent, dispatchEvent, el, isCommentNode} from '@angular/platform-browser/testing/src/browser_util';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {modifiedInIvy, obsoleteInIvy, onlyInIvy} from '@angular/private/testing';
@ -757,7 +757,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
});
it('should support events via EventEmitter on regular elements', async(() => {
it('should support events via EventEmitter on regular elements', waitForAsync(() => {
TestBed.configureTestingModule(
{declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]});
const template = '<div emitter listener></div>';
@ -787,7 +787,7 @@ function declareTests(config?: {useJit: boolean}) {
emitter.fireEvent('fired !');
}));
it('should support events via EventEmitter on template elements', async(() => {
it('should support events via EventEmitter on template elements', waitForAsync(() => {
const fixture =
TestBed
.configureTestingModule(
@ -819,7 +819,7 @@ function declareTests(config?: {useJit: boolean}) {
emitter.fireEvent('fired !');
}));
it('should support [()] syntax', async(() => {
it('should support [()] syntax', waitForAsync(() => {
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTwoWayBinding]});
const template = '<div [(control)]="ctxProp" two-way></div>';
TestBed.overrideComponent(MyComp, {set: {template}});
@ -1072,7 +1072,7 @@ function declareTests(config?: {useJit: boolean}) {
});
describe('.createComponent', () => {
it('should allow to create a component at any bound location', async(() => {
it('should allow to create a component at any bound location', waitForAsync(() => {
const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(MyComp);
const tc = fixture.debugElement.children[0].children[0];
@ -1083,7 +1083,7 @@ function declareTests(config?: {useJit: boolean}) {
.toHaveText('dynamic greet');
}));
it('should allow to create multiple components at a location', async(() => {
it('should allow to create multiple components at a location', waitForAsync(() => {
const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(MyComp);
const tc = fixture.debugElement.children[0].children[0];
@ -1219,7 +1219,7 @@ function declareTests(config?: {useJit: boolean}) {
});
describe('.insert', () => {
it('should throw with destroyed views', async(() => {
it('should throw with destroyed views', waitForAsync(() => {
const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(MyComp);
const tc = fixture.debugElement.children[0].children[0];
@ -1235,7 +1235,7 @@ function declareTests(config?: {useJit: boolean}) {
});
describe('.move', () => {
it('should throw with destroyed views', async(() => {
it('should throw with destroyed views', waitForAsync(() => {
const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(MyComp);
const tc = fixture.debugElement.children[0].children[0];
@ -2001,7 +2001,7 @@ function declareTests(config?: {useJit: boolean}) {
});
describe('whitespaces in templates', () => {
it('should not remove whitespaces by default', async(() => {
it('should not remove whitespaces by default', waitForAsync(() => {
@Component({
selector: 'comp',
template: '<span>foo</span> <span>bar</span>',
@ -2015,7 +2015,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(f.nativeElement.childNodes.length).toBe(2);
}));
it('should not remove whitespaces when explicitly requested not to do so', async(() => {
it('should not remove whitespaces when explicitly requested not to do so',
waitForAsync(() => {
@Component({
selector: 'comp',
template: '<span>foo</span> <span>bar</span>',
@ -2030,7 +2031,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(f.nativeElement.childNodes.length).toBe(3);
}));
it('should remove whitespaces when explicitly requested to do so', async(() => {
it('should remove whitespaces when explicitly requested to do so', waitForAsync(() => {
@Component({
selector: 'comp',
template: '<span>foo</span> <span>bar</span>',

View File

@ -10,7 +10,7 @@ import {ResourceLoader} from '@angular/compiler';
import {CompileMetadataResolver} from '@angular/compiler/src/metadata_resolver';
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
import {Component, Directive, Injectable, NgModule, OnDestroy, Pipe} from '@angular/core';
import {async, getTestBed, TestBed} from '@angular/core/testing';
import {getTestBed, TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {obsoleteInIvy} from '@angular/private/testing';
@ -135,7 +135,7 @@ import {obsoleteInIvy} from '@angular/private/testing';
SomeService.annotations = [];
}
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
instances = new Map<any, any>();
createSummaries().then(s => summaries = s);
}));

View File

@ -8,7 +8,7 @@
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, asNativeElements, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core';
import {ElementRef} from '@angular/core/src/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {ivyEnabled, modifiedInIvy, onlyInIvy} from '@angular/private/testing';
import {Subject} from 'rxjs';
@ -414,7 +414,7 @@ describe('Query API', () => {
});
describe('changes', () => {
it('should notify query on change', async(() => {
it('should notify query on change', waitForAsync(() => {
const template = '<needs-query #q>' +
'<div text="1"></div>' +
'<div *ngIf="shouldShow" text="2"></div>' +

View File

@ -8,7 +8,7 @@
import {Compiler, SystemJsNgModuleLoader} from '@angular/core';
import {global} from '@angular/core/src/util/global';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {afterEach, beforeEach, describe, expect, it} from '@angular/core/testing/src/testing_internal';
import {modifiedInIvy, onlyInIvy} from '@angular/private/testing';
@ -36,19 +36,19 @@ describe('SystemJsNgModuleLoader', () => {
global['System'] = oldSystem;
});
it('loads a default factory by appending the factory suffix', async(() => {
it('loads a default factory by appending the factory suffix', waitForAsync(() => {
const loader = new SystemJsNgModuleLoader(new Compiler());
loader.load('test').then(contents => {
expect(contents).toBe('test module factory' as any);
});
}));
it('loads a named factory by appending the factory suffix', async(() => {
it('loads a named factory by appending the factory suffix', waitForAsync(() => {
const loader = new SystemJsNgModuleLoader(new Compiler());
loader.load('test#Named').then(contents => {
expect(contents).toBe('test NamedNgFactory' as any);
});
}));
it('loads a named factory with a configured prefix and suffix', async(() => {
it('loads a named factory with a configured prefix and suffix', waitForAsync(() => {
const loader = new SystemJsNgModuleLoader(new Compiler(), {
factoryPathPrefix: 'prefixed/',
factoryPathSuffix: '/suffixed',
@ -70,13 +70,13 @@ describe('SystemJsNgModuleLoader', () => {
global['System'] = oldSystem;
});
it('loads a default module', async(() => {
it('loads a default module', waitForAsync(() => {
const loader = new SystemJsNgModuleLoader(new Compiler());
loader.load('test').then(contents => {
expect(contents.moduleType).toBe('test module' as any);
});
}));
it('loads a named module', async(() => {
it('loads a named module', waitForAsync(() => {
const loader = new SystemJsNgModuleLoader(new Compiler());
loader.load('test#NamedModule').then(contents => {
expect(contents.moduleType).toBe('test NamedModule' as any);

View File

@ -10,7 +10,7 @@ import {EventEmitter} from '@angular/core';
import {Injectable} from '@angular/core/src/di';
import {PendingMacrotask, Testability, TestabilityRegistry} from '@angular/core/src/testability/testability';
import {NgZone} from '@angular/core/src/zone/ng_zone';
import {async, fakeAsync, flush, tick} from '@angular/core/testing';
import {fakeAsync, flush, tick, waitForAsync} from '@angular/core/testing';
import {beforeEach, describe, expect, it, SpyObject} from '@angular/core/testing/src/testing_internal';
import {scheduleMicroTask} from '../../src/util/microtask';
@ -55,7 +55,7 @@ class MockNgZone extends NgZone {
let updateCallback: any;
let ngZone: MockNgZone;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
ngZone = new MockNgZone();
testability = new Testability(ngZone);
execute = new SpyObject().spy('execute');
@ -68,7 +68,7 @@ class MockNgZone extends NgZone {
expect(testability.getPendingRequestCount()).toEqual(0);
});
it('should fire whenstable callbacks if pending count is 0', async(() => {
it('should fire whenstable callbacks if pending count is 0', waitForAsync(() => {
testability.whenStable(execute);
microTask(() => {
@ -81,7 +81,7 @@ class MockNgZone extends NgZone {
expect(execute).not.toHaveBeenCalled();
});
it('should not call whenstable callbacks when there are pending counts', async(() => {
it('should not call whenstable callbacks when there are pending counts', waitForAsync(() => {
testability.increasePendingRequestCount();
testability.increasePendingRequestCount();
testability.whenStable(execute);
@ -96,7 +96,7 @@ class MockNgZone extends NgZone {
});
}));
it('should fire whenstable callbacks when pending drops to 0', async(() => {
it('should fire whenstable callbacks when pending drops to 0', waitForAsync(() => {
testability.increasePendingRequestCount();
testability.whenStable(execute);
@ -110,7 +110,8 @@ class MockNgZone extends NgZone {
});
}));
it('should not fire whenstable callbacks synchronously when pending drops to 0', async(() => {
it('should not fire whenstable callbacks synchronously when pending drops to 0',
waitForAsync(() => {
testability.increasePendingRequestCount();
testability.whenStable(execute);
testability.decreasePendingRequestCount();
@ -118,7 +119,7 @@ class MockNgZone extends NgZone {
expect(execute).not.toHaveBeenCalled();
}));
it('should fire whenstable callbacks with didWork if pending count is 0', async(() => {
it('should fire whenstable callbacks with didWork if pending count is 0', waitForAsync(() => {
microTask(() => {
testability.whenStable(execute);
@ -128,7 +129,8 @@ class MockNgZone extends NgZone {
});
}));
it('should fire whenstable callbacks with didWork when pending drops to 0', async(() => {
it('should fire whenstable callbacks with didWork when pending drops to 0',
waitForAsync(() => {
testability.increasePendingRequestCount();
testability.whenStable(execute);
@ -165,7 +167,7 @@ class MockNgZone extends NgZone {
clearTimeout(id);
}));
it('should fire if Angular is already stable', async(() => {
it('should fire if Angular is already stable', waitForAsync(() => {
testability.whenStable(execute, 200);
microTask(() => {
@ -363,7 +365,7 @@ class MockNgZone extends NgZone {
let registry: TestabilityRegistry;
let ngZone: MockNgZone;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
ngZone = new MockNgZone();
testability1 = new Testability(ngZone);
testability2 = new Testability(ngZone);

View File

@ -7,7 +7,7 @@
*/
import {EventEmitter, NgZone} from '@angular/core';
import {async, fakeAsync, flushMicrotasks} from '@angular/core/testing';
import {fakeAsync, flushMicrotasks, waitForAsync} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it, Log, xit} from '@angular/core/testing/src/testing_internal';
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
@ -914,7 +914,7 @@ function commonTests() {
asyncResult = null!;
});
it('should async even if the NgZone was created outside.', async(() => {
it('should async even if the NgZone was created outside.', waitForAsync(() => {
// try to escape the current async zone by using NgZone which was created outside.
ngZone.run(() => {
setTimeout(() => {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {async, fakeAsync, tick} from '@angular/core/testing';
import {fakeAsync, tick, waitForAsync} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, describe, inject, it} from '@angular/core/testing/src/testing_internal';
import {AbstractControl, FormArray, FormControl, FormGroup, ValidationErrors, Validators} from '@angular/forms';
import {of} from 'rxjs';
@ -726,7 +726,7 @@ describe('FormGroup', () => {
let control: FormControl;
let group: FormGroup;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
control = new FormControl('', asyncValidatorReturningObservable);
group = new FormGroup({'one': control});
}));

View File

@ -8,7 +8,7 @@
import {ɵgetDOM as getDOM} from '@angular/common';
import {Component, Directive, forwardRef, Type} from '@angular/core';
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {ComponentFixture, fakeAsync, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {AbstractControl, AsyncValidator, COMPOSITION_BUFFER_MODE, FormControl, FormsModule, NG_ASYNC_VALIDATORS, NgForm, NgModel} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {dispatchEvent, sortedClassList} from '@angular/platform-browser/testing/src/browser_util';
@ -168,7 +168,7 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
expect(form.value).toEqual({});
}));
it('should set status classes with ngModel', async(() => {
it('should set status classes with ngModel', waitForAsync(() => {
const fixture = initTest(NgModelForm);
fixture.componentInstance.name = 'aa';
fixture.detectChanges();
@ -212,7 +212,7 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
});
}));
it('should set status classes with ngModelGroup and ngForm', async(() => {
it('should set status classes with ngModelGroup and ngForm', waitForAsync(() => {
const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.first = '';
fixture.detectChanges();
@ -1179,7 +1179,7 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
expect(input.nativeElement.disabled).toBe(true);
}));
it('should disable a custom control if disabled attr is added', async(() => {
it('should disable a custom control if disabled attr is added', waitForAsync(() => {
const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp);
fixture.componentInstance.name = 'Nancy';
fixture.componentInstance.isDisabled = true;

View File

@ -7,7 +7,7 @@
*/
import {Component, Directive, EventEmitter, Input, Output, Type, ViewChild} from '@angular/core';
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {ComponentFixture, fakeAsync, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {AbstractControl, ControlValueAccessor, FormControl, FormGroup, FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgControl, NgForm, NgModel, ReactiveFormsModule, Validators} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
@ -1078,7 +1078,7 @@ import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util'
});
describe('in template-driven forms', () => {
it('should support standard writing to view and model', async(() => {
it('should support standard writing to view and model', waitForAsync(() => {
const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp);
fixture.componentInstance.name = 'Nancy';
fixture.detectChanges();

View File

@ -10,7 +10,7 @@
import {HTTP_INTERCEPTORS, HttpBackend, HttpClient, HttpClientModule, HttpEvent, HttpEventType, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import {TestBed, waitForAsync} from '@angular/core/testing';
import {HttpClientBackendService, HttpClientInMemoryWebApiModule} from 'angular-in-memory-web-api';
import {Observable, zip} from 'rxjs';
import {concatMap, map, tap} from 'rxjs/operators';
@ -37,14 +37,14 @@ describe('HttpClient Backend Service', () => {
http = TestBed.get(HttpClient);
});
it('can get heroes', async(() => {
it('can get heroes', waitForAsync(() => {
http.get<Hero[]>('api/heroes')
.subscribe(
heroes => expect(heroes.length).toBeGreaterThan(0, 'should have heroes'),
failRequest);
}));
it('GET should be a "cold" observable', async(() => {
it('GET should be a "cold" observable', waitForAsync(() => {
const httpBackend = TestBed.get(HttpBackend);
const spy = spyOn(httpBackend, 'collectionHandler').and.callThrough();
const get$ = http.get<Hero[]>('api/heroes');
@ -58,7 +58,7 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('GET should wait until after delay to respond', async(() => {
it('GET should wait until after delay to respond', waitForAsync(() => {
// to make test fail, set `delay=0` above
let gotResponse = false;
@ -70,7 +70,7 @@ describe('HttpClient Backend Service', () => {
expect(gotResponse).toBe(false, 'should delay before response');
}));
it('Should only initialize the db once', async(() => {
it('Should only initialize the db once', waitForAsync(() => {
const httpBackend = TestBed.get(HttpBackend);
const spy = spyOn(httpBackend, 'resetDb').and.callThrough();
@ -86,13 +86,13 @@ describe('HttpClient Backend Service', () => {
expect(spy.calls.count()).toBe(1);
}));
it('can get heroes (w/ a different base path)', async(() => {
it('can get heroes (w/ a different base path)', waitForAsync(() => {
http.get<Hero[]>('some-base-path/heroes').subscribe(heroes => {
expect(heroes.length).toBeGreaterThan(0, 'should have heroes');
}, failRequest);
}));
it('should 404 when GET unknown collection (after delay)', async(() => {
it('should 404 when GET unknown collection (after delay)', waitForAsync(() => {
let gotError = false;
const url = 'api/unknown-collection';
http.get<Hero[]>(url).subscribe(
@ -104,46 +104,46 @@ describe('HttpClient Backend Service', () => {
expect(gotError).toBe(false, 'should not get error until after delay');
}));
it('should return the hero w/id=1 for GET app/heroes/1', async(() => {
it('should return the hero w/id=1 for GET app/heroes/1', waitForAsync(() => {
http.get<Hero>('api/heroes/1')
.subscribe(
hero => expect(hero).toBeDefined('should find hero with id=1'), failRequest);
}));
// test where id is string that looks like a number
it('should return the stringer w/id="10" for GET app/stringers/10', async(() => {
it('should return the stringer w/id="10" for GET app/stringers/10', waitForAsync(() => {
http.get<Hero>('api/stringers/10')
.subscribe(
hero => expect(hero).toBeDefined('should find string with id="10"'), failRequest);
}));
it('should return 1-item array for GET app/heroes/?id=1', async(() => {
it('should return 1-item array for GET app/heroes/?id=1', waitForAsync(() => {
http.get<Hero[]>('api/heroes/?id=1')
.subscribe(
heroes => expect(heroes.length).toBe(1, 'should find one hero w/id=1'),
failRequest);
}));
it('should return 1-item array for GET app/heroes?id=1', async(() => {
it('should return 1-item array for GET app/heroes?id=1', waitForAsync(() => {
http.get<Hero[]>('api/heroes?id=1')
.subscribe(
heroes => expect(heroes.length).toBe(1, 'should find one hero w/id=1'),
failRequest);
}));
it('should return undefined for GET app/heroes?id=not-found-id', async(() => {
it('should return undefined for GET app/heroes?id=not-found-id', waitForAsync(() => {
http.get<Hero[]>('api/heroes?id=123456')
.subscribe(heroes => expect(heroes.length).toBe(0), failRequest);
}));
it('should return 404 for GET app/heroes/not-found-id', async(() => {
it('should return 404 for GET app/heroes/not-found-id', waitForAsync(() => {
const url = 'api/heroes/123456';
http.get<Hero[]>(url).subscribe(
() => fail(`should not have found data for '${url}'`),
err => expect(err.status).toBe(404, 'should have 404 status'));
}));
it('can generate the id when add a hero with no id', async(() => {
it('can generate the id when add a hero with no id', waitForAsync(() => {
const hero = new Hero(undefined, 'SuperDooper');
http.post<Hero>('api/heroes', hero).subscribe(replyHero => {
expect(replyHero.id).toBeDefined('added hero should have an id');
@ -151,13 +151,13 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('can get nobodies (empty collection)', async(() => {
it('can get nobodies (empty collection)', waitForAsync(() => {
http.get<Hero[]>('api/nobodies').subscribe(nobodies => {
expect(nobodies.length).toBe(0, 'should have no nobodies');
}, failRequest);
}));
it('can add a nobody with an id to empty nobodies collection', async(() => {
it('can add a nobody with an id to empty nobodies collection', waitForAsync(() => {
const id = 'g-u-i-d';
http.post('api/nobodies', {id, name: 'Noman'})
@ -169,7 +169,8 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('should fail when add a nobody without an id to empty nobodies collection', async(() => {
it('should fail when add a nobody without an id to empty nobodies collection',
waitForAsync(() => {
http.post('api/nobodies', {name: 'Noman'})
.subscribe(
() => fail(`should not have been able to add 'Norman' to 'nobodies'`), err => {
@ -179,11 +180,11 @@ describe('HttpClient Backend Service', () => {
}));
describe('can reset the database', () => {
it('to empty (object db)', async(() => resetDatabaseTest('object')));
it('to empty (object db)', waitForAsync(() => resetDatabaseTest('object')));
it('to empty (observable db)', async(() => resetDatabaseTest('observable')));
it('to empty (observable db)', waitForAsync(() => resetDatabaseTest('observable')));
it('to empty (promise db)', async(() => resetDatabaseTest('promise')));
it('to empty (promise db)', waitForAsync(() => resetDatabaseTest('promise')));
function resetDatabaseTest(returnType: string) {
// Observable of the number of heroes and nobodies
@ -223,28 +224,29 @@ describe('HttpClient Backend Service', () => {
http = TestBed.get(HttpClient);
});
it('can get heroes', async(() => {
it('can get heroes', waitForAsync(() => {
http.get<Hero[]>('api/heroes')
.subscribe(
heroes => expect(heroes.length).toBeGreaterThan(0, 'should have heroes'),
failRequest);
}));
it('can translate `foo/heroes` to `heroes` via `parsedRequestUrl` override', async(() => {
it('can translate `foo/heroes` to `heroes` via `parsedRequestUrl` override',
waitForAsync(() => {
http.get<Hero[]>('api/foo/heroes')
.subscribe(
heroes => expect(heroes.length).toBeGreaterThan(0, 'should have heroes'),
failRequest);
}));
it('can get villains', async(() => {
it('can get villains', waitForAsync(() => {
http.get<Hero[]>('api/villains')
.subscribe(
villains => expect(villains.length).toBeGreaterThan(0, 'should have villains'),
failRequest);
}));
it('should 404 when POST to villains', async(() => {
it('should 404 when POST to villains', waitForAsync(() => {
const url = 'api/villains';
http.post<Hero[]>(url, {id: 42, name: 'Dr. Evil'})
.subscribe(
@ -252,14 +254,14 @@ describe('HttpClient Backend Service', () => {
err => expect(err.status).toBe(404, 'should have 404 status'));
}));
it('should 404 when GET unknown collection', async(() => {
it('should 404 when GET unknown collection', waitForAsync(() => {
const url = 'api/unknown-collection';
http.get<Hero[]>(url).subscribe(
() => fail(`should not have found data for '${url}'`),
err => expect(err.status).toBe(404, 'should have 404 status'));
}));
it('should use genId override to add new hero, "Maxinius"', async(() => {
it('should use genId override to add new hero, "Maxinius"', waitForAsync(() => {
http.post('api/heroes', {name: 'Maxinius'})
.pipe(concatMap(() => http.get<Hero[]>('api/heroes?name=Maxi')))
.subscribe(heroes => {
@ -269,7 +271,8 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('should use genId override guid generator for a new nobody without an id', async(() => {
it('should use genId override guid generator for a new nobody without an id',
waitForAsync(() => {
http.post('api/nobodies', {name: 'Noman'})
.pipe(concatMap(() => http.get<{id: string; name: string}[]>('api/nobodies')))
.subscribe(nobodies => {
@ -280,11 +283,11 @@ describe('HttpClient Backend Service', () => {
}));
describe('can reset the database', () => {
it('to empty (object db)', async(() => resetDatabaseTest('object')));
it('to empty (object db)', waitForAsync(() => resetDatabaseTest('object')));
it('to empty (observable db)', async(() => resetDatabaseTest('observable')));
it('to empty (observable db)', waitForAsync(() => resetDatabaseTest('observable')));
it('to empty (promise db)', async(() => resetDatabaseTest('promise')));
it('to empty (promise db)', waitForAsync(() => resetDatabaseTest('promise')));
function resetDatabaseTest(returnType: string) {
// Observable of the number of heroes, nobodies and villains
@ -331,19 +334,19 @@ describe('HttpClient Backend Service', () => {
heroService = TestBed.get(HeroService);
});
it('can get heroes', async(() => {
it('can get heroes', waitForAsync(() => {
heroService.getHeroes().subscribe(heroes => {
expect(heroes.length).toBeGreaterThan(0, 'should have heroes');
}, failRequest);
}));
it('can get hero w/ id=1', async(() => {
it('can get hero w/ id=1', waitForAsync(() => {
heroService.getHero(1).subscribe(hero => {
expect(hero.name).toBe('Windstorm');
}, () => fail('getHero failed'));
}));
it('should 404 when hero id not found', async(() => {
it('should 404 when hero id not found', waitForAsync(() => {
const id = 123456;
heroService.getHero(id).subscribe(
() => fail(`should not have found hero for id='${id}'`), err => {
@ -351,7 +354,7 @@ describe('HttpClient Backend Service', () => {
});
}));
it('can add a hero', async(() => {
it('can add a hero', waitForAsync(() => {
heroService.addHero('FunkyBob')
.pipe(
tap(hero => expect(hero.name).toBe('FunkyBob')),
@ -363,23 +366,23 @@ describe('HttpClient Backend Service', () => {
}),
10000);
it('can delete a hero', async(() => {
it('can delete a hero', waitForAsync(() => {
const id = 1;
heroService.deleteHero(id).subscribe((_: {}) => expect(_).toBeDefined(), failRequest);
}));
it('should allow delete of non-existent hero', async(() => {
it('should allow delete of non-existent hero', waitForAsync(() => {
const id = 123456;
heroService.deleteHero(id).subscribe((_: {}) => expect(_).toBeDefined(), failRequest);
}));
it('can search for heroes by name containing "a"', async(() => {
it('can search for heroes by name containing "a"', waitForAsync(() => {
heroService.searchHeroes('a').subscribe((heroes: Hero[]) => {
expect(heroes.length).toBe(3, 'should find 3 heroes with letter "a"');
}, failRequest);
}));
it('can update existing hero', async(() => {
it('can update existing hero', waitForAsync(() => {
const id = 1;
heroService.getHero(id)
.pipe(
@ -394,7 +397,7 @@ describe('HttpClient Backend Service', () => {
}),
10000);
it('should create new hero when try to update non-existent hero', async(() => {
it('should create new hero when try to update non-existent hero', waitForAsync(() => {
const falseHero = new Hero(12321, 'DryMan');
heroService.updateHero(falseHero).subscribe(
hero => expect(hero.name).toBe(falseHero.name), failRequest);
@ -446,7 +449,7 @@ describe('HttpClient Backend Service', () => {
expect(ti).toBeDefined();
});
it('should have GET request header from test interceptor', async(() => {
it('should have GET request header from test interceptor', waitForAsync(() => {
const handle = spyOn(httpBackend, 'handle').and.callThrough();
http.get<Hero[]>('api/heroes').subscribe(heroes => {
@ -459,7 +462,7 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('should have GET response header from test interceptor', async(() => {
it('should have GET response header from test interceptor', waitForAsync(() => {
let gotResponse = false;
const req = new HttpRequest<any>('GET', 'api/heroes');
http.request<Hero[]>(req).subscribe(event => {
@ -503,7 +506,7 @@ describe('HttpClient Backend Service', () => {
jasmine.Ajax.uninstall();
});
it('can get heroes (no passthru)', async(() => {
it('can get heroes (no passthru)', waitForAsync(() => {
http.get<Hero[]>('api/heroes').subscribe(heroes => {
expect(createPassThruBackend).not.toHaveBeenCalled();
expect(heroes.length).toBeGreaterThan(0, 'should have heroes');
@ -513,7 +516,7 @@ describe('HttpClient Backend Service', () => {
// `passthru` is NOT a collection in the data store
// so requests for it should pass thru to the "real" server
it('can GET passthru', async(() => {
it('can GET passthru', waitForAsync(() => {
jasmine.Ajax.stubRequest('api/passthru').andReturn({
'status': 200,
'contentType': 'application/json',
@ -525,7 +528,7 @@ describe('HttpClient Backend Service', () => {
}, failRequest);
}));
it('can ADD to passthru', async(() => {
it('can ADD to passthru', waitForAsync(() => {
jasmine.Ajax.stubRequest('api/passthru').andReturn({
'status': 200,
'contentType': 'application/json',
@ -554,7 +557,7 @@ describe('HttpClient Backend Service', () => {
http = TestBed.get(HttpClient);
});
it('can get heroes (encapsulated)', async(() => {
it('can get heroes (encapsulated)', waitForAsync(() => {
http.get<{data: any}>('api/heroes')
.pipe(map(data => data.data as Hero[]))
.subscribe(

View File

@ -8,7 +8,7 @@
import {ResourceLoader, UrlResolver} from '@angular/compiler';
import {Component} from '@angular/core';
import {async, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {fakeAsync, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {CachedResourceLoader} from '@angular/platform-browser-dynamic/src/resource_loader/resource_loader_cache';
import {setTemplateCache} from '@angular/platform-browser-dynamic/test/resource_loader/resource_loader_cache_setter';
import {expect} from '@angular/platform-browser/testing/src/matchers';
@ -29,14 +29,14 @@ if (isBrowser) {
}).toThrowError('CachedResourceLoader: Template cache was not found in $templateCache.');
});
it('should resolve the Promise with the cached file content on success', async(() => {
it('should resolve the Promise with the cached file content on success', waitForAsync(() => {
resourceLoader = createCachedResourceLoader();
resourceLoader.get('test.html').then((text) => {
expect(text).toBe('<div>Hello</div>');
});
}));
it('should reject the Promise on failure', async(() => {
it('should reject the Promise on failure', waitForAsync(() => {
resourceLoader = createCachedResourceLoader();
resourceLoader.get('unknown.html').then(() => {
throw new Error('Not expected to succeed.');

View File

@ -8,7 +8,7 @@
import {ResourceLoader} from '@angular/compiler';
import {Compiler, Component, NgModule} from '@angular/core';
import {async, fakeAsync, inject, TestBed, tick} from '@angular/core/testing';
import {fakeAsync, inject, TestBed, tick, waitForAsync} from '@angular/core/testing';
import {ResourceLoaderImpl} from '@angular/platform-browser-dynamic/src/resource_loader/resource_loader_impl';
@ -54,7 +54,7 @@ if (isBrowser) {
expect(actuallyDone).toEqual(true);
});
it('should run async tests with ResourceLoaders', async(() => {
it('should run async tests with ResourceLoaders', waitForAsync(() => {
const resourceLoader = new ResourceLoaderImpl();
resourceLoader
.get('/base/angular/packages/platform-browser/test/static_assets/test.html')
@ -132,7 +132,7 @@ if (isBrowser) {
it('should fail when an ResourceLoader fails', done => {
const itPromise = patchJasmineIt();
it('should fail with an error from a promise', async(() => {
it('should fail with an error from a promise', waitForAsync(() => {
TestBed.configureTestingModule({declarations: [BadTemplateUrl]});
TestBed.compileComponents();
}));
@ -151,7 +151,7 @@ if (isBrowser) {
});
describe('TestBed createComponent', function() {
it('should allow an external templateUrl', async(() => {
it('should allow an external templateUrl', waitForAsync(() => {
TestBed.configureTestingModule({declarations: [ExternalTemplateComp]});
TestBed.compileComponents().then(() => {
const componentFixture = TestBed.createComponent(ExternalTemplateComp);

View File

@ -8,7 +8,7 @@
import {CompilerConfig, ResourceLoader} from '@angular/compiler';
import {Compiler, Component, ComponentFactoryResolver, CUSTOM_ELEMENTS_SCHEMA, Directive, Inject, Injectable, InjectionToken, Injector, Input, NgModule, Optional, Pipe, SkipSelf, ɵstringify as stringify} from '@angular/core';
import {async, fakeAsync, getTestBed, inject, TestBed, tick, withModule} from '@angular/core/testing';
import {fakeAsync, getTestBed, inject, TestBed, tick, waitForAsync, withModule} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {ivyEnabled, modifiedInIvy, obsoleteInIvy, onlyInIvy} from '@angular/private/testing';
@ -146,11 +146,11 @@ const bTok = new InjectionToken<string>('b');
}, 0);
});
it('should run async tests with tasks', async(function(this: TestContext) {
it('should run async tests with tasks', waitForAsync(function(this: TestContext) {
setTimeout(() => this.actuallyDone = true, 0);
}));
it('should run async tests with promises', async(function(this: TestContext) {
it('should run async tests with promises', waitForAsync(function(this: TestContext) {
const p = new Promise((resolve, reject) => setTimeout(resolve, 10));
p.then(() => this.actuallyDone = true);
}));
@ -192,7 +192,7 @@ const bTok = new InjectionToken<string>('b');
}));
it('should preserve context when async and inject helpers are combined',
async(inject([], function(this: TestContext) {
waitForAsync(inject([], function(this: TestContext) {
setTimeout(() => this.contextModified = true, 0);
})));
@ -214,7 +214,7 @@ const bTok = new InjectionToken<string>('b');
}));
it('should wait until returned promises',
async(inject([FancyService], (service: FancyService) => {
waitForAsync(inject([FancyService], (service: FancyService) => {
service.getAsyncValue().then((value) => expect(value).toEqual('async value'));
service.getTimeoutValue().then((value) => expect(value).toEqual('timeout value'));
})));
@ -251,7 +251,7 @@ const bTok = new InjectionToken<string>('b');
});
describe('using async beforeEach', () => {
beforeEach(async(inject([FancyService], (service: FancyService) => {
beforeEach(waitForAsync(inject([FancyService], (service: FancyService) => {
service.getAsyncValue().then((value) => service.value = value);
})));
@ -335,7 +335,7 @@ const bTok = new InjectionToken<string>('b');
});
describe('components with template url', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [CompWithUrlTemplate]});
TestBed.compileComponents();
}));
@ -892,9 +892,9 @@ const bTok = new InjectionToken<string>('b');
const itPromise = patchJasmineIt();
const barError = new Error('bar');
it('throws an async error', async(inject([], () => setTimeout(() => {
throw barError;
}, 0))));
it('throws an async error', waitForAsync(inject([], () => setTimeout(() => {
throw barError;
}, 0))));
itPromise.then(() => done.fail('Expected test to fail, but it did not'), (err) => {
expect(err).toEqual(barError);
@ -906,7 +906,7 @@ const bTok = new InjectionToken<string>('b');
it('should fail when a returned promise is rejected', (done) => {
const itPromise = patchJasmineIt();
it('should fail with an error from a promise', async(inject([], () => {
it('should fail with an error from a promise', waitForAsync(inject([], () => {
let reject: (error: any) => void = undefined!;
const promise = new Promise((_, rej) => reject = rej);
const p = promise.then(() => expect(1).toEqual(2));
@ -1011,14 +1011,14 @@ Did you run and wait for 'resolveComponentResources()'?` :
});
});
it('should instantiate a component with valid DOM', async(() => {
it('should instantiate a component with valid DOM', waitForAsync(() => {
const fixture = TestBed.createComponent(ChildComp);
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('Original Child');
}));
it('should allow changing members of the component', async(() => {
it('should allow changing members of the component', waitForAsync(() => {
const componentFixture = TestBed.createComponent(MyIfComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('MyIf()');
@ -1028,14 +1028,14 @@ Did you run and wait for 'resolveComponentResources()'?` :
expect(componentFixture.nativeElement).toHaveText('MyIf(More)');
}));
it('should override a template', async(() => {
it('should override a template', waitForAsync(() => {
TestBed.overrideComponent(ChildComp, {set: {template: '<span>Mock</span>'}});
const componentFixture = TestBed.createComponent(ChildComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('Mock');
}));
it('should override a provider', async(() => {
it('should override a provider', waitForAsync(() => {
TestBed.overrideComponent(
TestProvidersComp,
{set: {providers: [{provide: FancyService, useClass: MockFancyService}]}});
@ -1045,7 +1045,7 @@ Did you run and wait for 'resolveComponentResources()'?` :
}));
it('should override a viewProvider', async(() => {
it('should override a viewProvider', waitForAsync(() => {
TestBed.overrideComponent(
TestViewProvidersComp,
{set: {viewProviders: [{provide: FancyService, useClass: MockFancyService}]}});
@ -1065,7 +1065,7 @@ Did you run and wait for 'resolveComponentResources()'?` :
});
});
it('should override component dependencies', async(() => {
it('should override component dependencies', waitForAsync(() => {
const componentFixture = TestBed.createComponent(ParentComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('Parent(Mock)');

View File

@ -11,7 +11,7 @@ import {DOCUMENT, isPlatformServer, PlatformLocation, ɵgetDOM as getDOM} from '
import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {ApplicationRef, CompilerFactory, Component, destroyPlatform, getPlatform, HostListener, Inject, Injectable, Input, NgModule, NgZone, PLATFORM_ID, PlatformRef, ViewEncapsulation} from '@angular/core';
import {async, inject} from '@angular/core/testing';
import {inject, waitForAsync} from '@angular/core/testing';
import {BrowserModule, makeStateKey, Title, TransferState} from '@angular/platform-browser';
import {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, platformDynamicServer, PlatformState, renderModule, renderModuleFactory, ServerModule, ServerTransferStateModule} from '@angular/platform-server';
import {ivyEnabled, modifiedInIvy} from '@angular/private/testing';
@ -409,7 +409,7 @@ describe('platform-server integration', () => {
if (getPlatform()) destroyPlatform();
});
it('should bootstrap', async(() => {
it('should bootstrap', waitForAsync(() => {
const platform =
platformDynamicServer([{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
@ -426,7 +426,7 @@ describe('platform-server integration', () => {
});
}));
it('should allow multiple platform instances', async(() => {
it('should allow multiple platform instances', waitForAsync(() => {
const platform =
platformDynamicServer([{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
@ -447,7 +447,7 @@ describe('platform-server integration', () => {
});
}));
it('adds title to the document using Title service', async(() => {
it('adds title to the document using Title service', waitForAsync(() => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue: {document: '<html><head><title></title></head><body><app></app></body></html>'}
@ -461,7 +461,7 @@ describe('platform-server integration', () => {
});
}));
it('should get base href from document', async(() => {
it('should get base href from document', waitForAsync(() => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue: {document: '<html><head><base href="/"></head><body><app></app></body></html>'}
@ -473,7 +473,7 @@ describe('platform-server integration', () => {
});
}));
it('adds styles with ng-transition attribute', async(() => {
it('adds styles with ng-transition attribute', waitForAsync(() => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue: {document: '<html><head></head><body><app></app></body></html>'}
@ -488,7 +488,7 @@ describe('platform-server integration', () => {
});
}));
it('copies known properties to attributes', async(() => {
it('copies known properties to attributes', waitForAsync(() => {
const platform =
platformDynamicServer([{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(ImageExampleModule).then(ref => {
@ -500,7 +500,7 @@ describe('platform-server integration', () => {
}));
describe('PlatformLocation', () => {
it('is injectable', async(() => {
it('is injectable', waitForAsync(() => {
const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(ExampleModule).then(appRef => {
@ -551,7 +551,7 @@ describe('platform-server integration', () => {
expect(location.hash).toBe('');
});
});
it('pushState causes the URL to update', async(() => {
it('pushState causes the URL to update', waitForAsync(() => {
const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(ExampleModule).then(appRef => {
@ -601,7 +601,7 @@ describe('platform-server integration', () => {
expect(called).toBe(true);
});
it('using long form should work', async(() => {
it('using long form should work', waitForAsync(() => {
const platform =
platformDynamicServer([{provide: INITIAL_CONFIG, useValue: {document: doc}}]);
@ -618,7 +618,7 @@ describe('platform-server integration', () => {
});
}));
it('using renderModule should work', async(() => {
it('using renderModule should work', waitForAsync(() => {
renderModule(AsyncServerModule, {document: doc}).then(output => {
expect(output).toBe(expectedOutput);
called = true;
@ -626,7 +626,7 @@ describe('platform-server integration', () => {
}));
modifiedInIvy('Will not support binding to innerText in Ivy since domino does not')
.it('should support binding to innerText', async(() => {
.it('should support binding to innerText', waitForAsync(() => {
renderModule(InnerTextModule, {document: doc}).then(output => {
expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER"><div innertext="Some text">Some text</div></app></body></html>');
@ -635,7 +635,7 @@ describe('platform-server integration', () => {
}));
it('using renderModuleFactory should work',
async(inject([PlatformRef], (defaultPlatform: PlatformRef) => {
waitForAsync(inject([PlatformRef], (defaultPlatform: PlatformRef) => {
const compilerFactory: CompilerFactory =
defaultPlatform.injector.get(CompilerFactory, null)!;
const moduleFactory =
@ -646,7 +646,7 @@ describe('platform-server integration', () => {
});
})));
it('works with SVG elements', async(() => {
it('works with SVG elements', waitForAsync(() => {
renderModule(SVGServerModule, {document: doc}).then(output => {
expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' +
@ -655,7 +655,7 @@ describe('platform-server integration', () => {
});
}));
it('works with animation', async(() => {
it('works with animation', waitForAsync(() => {
renderModule(AnimationServerModule, {document: doc}).then(output => {
expect(output).toContain('Works!');
expect(output).toContain('ng-trigger-myAnimation');
@ -666,7 +666,7 @@ describe('platform-server integration', () => {
});
}));
it('should handle ViewEncapsulation.Native', async(() => {
it('should handle ViewEncapsulation.Native', waitForAsync(() => {
renderModule(NativeExampleModule, {document: doc}).then(output => {
expect(output).not.toBe('');
expect(output).toContain('color: red');
@ -675,7 +675,7 @@ describe('platform-server integration', () => {
}));
it('sets a prefix for the _nghost and _ngcontent attributes', async(() => {
it('sets a prefix for the _nghost and _ngcontent attributes', waitForAsync(() => {
renderModule(ExampleStylesModule, {document: doc}).then(output => {
expect(output).toMatch(
/<html><head><style ng-transition="example-styles">div\[_ngcontent-sc\d+\] {color: blue; } \[_nghost-sc\d+\] { color: red; }<\/style><\/head><body><app _nghost-sc\d+="" ng-version="0.0.0-PLACEHOLDER"><div _ngcontent-sc\d+="">Works!<\/div><\/app><\/body><\/html>/);
@ -683,7 +683,7 @@ describe('platform-server integration', () => {
});
}));
it('should handle false values on attributes', async(() => {
it('should handle false values on attributes', waitForAsync(() => {
renderModule(FalseAttributesModule, {document: doc}).then(output => {
expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' +
@ -692,7 +692,7 @@ describe('platform-server integration', () => {
});
}));
it('should handle element property "name"', async(() => {
it('should handle element property "name"', waitForAsync(() => {
renderModule(NameModule, {document: doc}).then(output => {
expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' +
@ -701,7 +701,7 @@ describe('platform-server integration', () => {
});
}));
it('should work with sanitizer to handle "innerHTML"', async(() => {
it('should work with sanitizer to handle "innerHTML"', waitForAsync(() => {
// Clear out any global states. These should be set when platform-server
// is initialized.
(global as any).Node = undefined;
@ -714,7 +714,7 @@ describe('platform-server integration', () => {
});
}));
it('should handle element property "hidden"', async(() => {
it('should handle element property "hidden"', waitForAsync(() => {
renderModule(HiddenModule, {document: doc}).then(output => {
expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' +
@ -723,7 +723,7 @@ describe('platform-server integration', () => {
});
}));
it('should call render hook', async(() => {
it('should call render hook', waitForAsync(() => {
renderModule(RenderHookModule, {document: doc}).then(output => {
// title should be added by the render hook.
expect(output).toBe(
@ -733,7 +733,7 @@ describe('platform-server integration', () => {
});
}));
it('should call multiple render hooks', async(() => {
it('should call multiple render hooks', waitForAsync(() => {
const consoleSpy = spyOn(console, 'warn');
renderModule(MultiRenderHookModule, {document: doc}).then(output => {
// title should be added by the render hook.
@ -745,7 +745,7 @@ describe('platform-server integration', () => {
});
}));
it('should call async render hooks', async(() => {
it('should call async render hooks', waitForAsync(() => {
renderModule(AsyncRenderHookModule, {document: doc}).then(output => {
// title should be added by the render hook.
expect(output).toBe(
@ -755,7 +755,7 @@ describe('platform-server integration', () => {
});
}));
it('should call multiple async and sync render hooks', async(() => {
it('should call multiple async and sync render hooks', waitForAsync(() => {
const consoleSpy = spyOn(console, 'warn');
renderModule(AsyncMultiRenderHookModule, {document: doc}).then(output => {
// title should be added by the render hook.
@ -769,7 +769,7 @@ describe('platform-server integration', () => {
});
describe('HttpClient', () => {
it('can inject HttpClient', async(() => {
it('can inject HttpClient', waitForAsync(() => {
const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(HttpClientExampleModule).then(ref => {
@ -777,7 +777,7 @@ describe('platform-server integration', () => {
});
}));
it('can make HttpClient requests', async(() => {
it('can make HttpClient requests', waitForAsync(() => {
const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(HttpClientExampleModule).then(ref => {
@ -938,7 +938,7 @@ describe('platform-server integration', () => {
});
});
it('requests are macrotasks', async(() => {
it('requests are macrotasks', waitForAsync(() => {
const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
platform.bootstrapModule(HttpClientExampleModule).then(ref => {
@ -984,7 +984,7 @@ describe('platform-server integration', () => {
expect(called).toBe(true);
});
it('adds transfer script tag when using renderModule', async(() => {
it('adds transfer script tag when using renderModule', waitForAsync(() => {
renderModule(TransferStoreModule, {document: '<app></app>'}).then(output => {
expect(output).toBe(defaultExpectedOutput);
called = true;
@ -992,7 +992,7 @@ describe('platform-server integration', () => {
}));
it('adds transfer script tag when using renderModuleFactory',
async(inject([PlatformRef], (defaultPlatform: PlatformRef) => {
waitForAsync(inject([PlatformRef], (defaultPlatform: PlatformRef) => {
const compilerFactory: CompilerFactory =
defaultPlatform.injector.get(CompilerFactory, null)!;
const moduleFactory =
@ -1003,7 +1003,7 @@ describe('platform-server integration', () => {
});
})));
it('cannot break out of <script> tag in serialized output', async(() => {
it('cannot break out of <script> tag in serialized output', waitForAsync(() => {
renderModule(EscapedTransferStoreModule, {
document: '<esc-app></esc-app>'
}).then(output => {

View File

@ -7,7 +7,7 @@
*/
import {ChangeDetectorRef, Component, destroyPlatform, EventEmitter, forwardRef, Input, NgModule, NgModuleFactory, NgZone, NO_ERRORS_SCHEMA, OnChanges, OnDestroy, Output, SimpleChange, SimpleChanges, Testability} from '@angular/core';
import {async, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {fakeAsync, flushMicrotasks, tick, waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@ -30,7 +30,7 @@ withEachNg1Version(() => {
it('should have AngularJS loaded',
() => expect(angular.getAngularJSGlobal().version.major).toBe(1));
it('should instantiate ng2 in ng1 template and project content', async(() => {
it('should instantiate ng2 in ng1 template and project content', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []);
@Component({
@ -55,7 +55,7 @@ withEachNg1Version(() => {
});
}));
it('should instantiate ng1 in ng2 template and project content', async(() => {
it('should instantiate ng1 in ng2 template and project content', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -86,7 +86,7 @@ withEachNg1Version(() => {
});
}));
it('supports the compilerOptions argument', async(() => {
it('supports the compilerOptions argument', waitForAsync(() => {
const platformRef = platformBrowserDynamic();
spyOn(platformRef, 'bootstrapModule').and.callThrough();
spyOn(platformRef, 'bootstrapModuleFactory').and.callThrough();
@ -170,7 +170,7 @@ withEachNg1Version(() => {
});
describe('change-detection', () => {
it('should not break if a $digest is already in progress', async(() => {
it('should not break if a $digest is already in progress', waitForAsync(() => {
@Component({selector: 'my-app', template: ''})
class AppComponent {
}
@ -209,7 +209,7 @@ withEachNg1Version(() => {
});
}));
it('should interleave scope and component expressions', async(() => {
it('should interleave scope and component expressions', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
const log: string[] = [];
@ -256,7 +256,8 @@ withEachNg1Version(() => {
});
}));
it('should propagate changes to a downgraded component inside the ngZone', async(() => {
it('should propagate changes to a downgraded component inside the ngZone',
waitForAsync(() => {
let appComponent: AppComponent;
let upgradeRef: UpgradeAdapterRef;
@ -342,7 +343,7 @@ withEachNg1Version(() => {
});
describe('downgrade ng2 component', () => {
it('should allow non-element selectors for downgraded components', async(() => {
it('should allow non-element selectors for downgraded components', waitForAsync(() => {
@Component({selector: '[itWorks]', template: 'It works'})
class WorksComponent {
}
@ -361,7 +362,7 @@ withEachNg1Version(() => {
});
}));
it('should bind properties, events', async(() => {
it('should bind properties, events', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []).value($EXCEPTION_HANDLER, (err: any) => {
throw err;
@ -483,7 +484,7 @@ withEachNg1Version(() => {
});
}));
it('should support two-way binding and event listener', async(() => {
it('should support two-way binding and event listener', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const listenerSpy = jasmine.createSpy('$rootScope.listener');
const ng1Module = angular.module_('ng1', []).run(($rootScope: angular.IScope) => {
@ -532,7 +533,7 @@ withEachNg1Version(() => {
});
}));
it('should initialize inputs in time for `ngOnChanges`', async(() => {
it('should initialize inputs in time for `ngOnChanges`', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
@Component({
@ -591,7 +592,7 @@ withEachNg1Version(() => {
});
}));
it('should bind to ng-model', async(() => {
it('should bind to ng-model', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -661,7 +662,7 @@ withEachNg1Version(() => {
});
}));
it('should properly run cleanup when ng1 directive is destroyed', async(() => {
it('should properly run cleanup when ng1 directive is destroyed', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
const onDestroyed: EventEmitter<string> = new EventEmitter<string>();
@ -700,7 +701,7 @@ withEachNg1Version(() => {
});
}));
it('should properly run cleanup with multiple levels of nesting', async(() => {
it('should properly run cleanup with multiple levels of nesting', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let destroyed = false;
@ -745,7 +746,8 @@ withEachNg1Version(() => {
});
}));
it('should fallback to the root ng2.injector when compiled outside the dom', async(() => {
it('should fallback to the root ng2.injector when compiled outside the dom',
waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -781,7 +783,7 @@ withEachNg1Version(() => {
});
}));
it('should support multi-slot projection', async(() => {
it('should support multi-slot projection', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []);
@Component({
@ -810,7 +812,7 @@ withEachNg1Version(() => {
});
}));
it('should correctly project structural directives', async(() => {
it('should correctly project structural directives', waitForAsync(() => {
@Component({selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'})
class Ng2Component {
// TODO(issue/24571): remove '!'.
@ -844,7 +846,7 @@ withEachNg1Version(() => {
});
}));
it('should allow attribute selectors for components in ng2', async(() => {
it('should allow attribute selectors for components in ng2', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => MyNg2Module));
const ng1Module = angular.module_('myExample', []);
@ -1123,7 +1125,7 @@ withEachNg1Version(() => {
});
}));
it('should bind properties, events', async(() => {
it('should bind properties, events', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1181,7 +1183,7 @@ withEachNg1Version(() => {
});
}));
it('should bind optional properties', async(() => {
it('should bind optional properties', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1226,7 +1228,7 @@ withEachNg1Version(() => {
}));
it('should bind properties, events in controller when bindToController is not used',
async(() => {
waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1272,7 +1274,7 @@ withEachNg1Version(() => {
});
}));
it('should bind properties, events in link function', async(() => {
it('should bind properties, events in link function', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1318,7 +1320,7 @@ withEachNg1Version(() => {
});
}));
it('should support templateUrl fetched from $httpBackend', async(() => {
it('should support templateUrl fetched from $httpBackend', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
ng1Module.value(
@ -1349,7 +1351,7 @@ withEachNg1Version(() => {
});
}));
it('should support templateUrl as a function', async(() => {
it('should support templateUrl as a function', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
ng1Module.value(
@ -1384,7 +1386,7 @@ withEachNg1Version(() => {
});
}));
it('should support empty template', async(() => {
it('should support empty template', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1412,7 +1414,7 @@ withEachNg1Version(() => {
});
}));
it('should support template as a function', async(() => {
it('should support template as a function', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1444,7 +1446,7 @@ withEachNg1Version(() => {
});
}));
it('should support templateUrl fetched from $templateCache', async(() => {
it('should support templateUrl fetched from $templateCache', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
ng1Module.run(($templateCache: any) => $templateCache.put('url.html', 'WORKS'));
@ -1473,7 +1475,7 @@ withEachNg1Version(() => {
});
}));
it('should support controller with controllerAs', async(() => {
it('should support controller with controllerAs', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1524,7 +1526,7 @@ withEachNg1Version(() => {
});
}));
it('should support bindToController', async(() => {
it('should support bindToController', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1558,7 +1560,7 @@ withEachNg1Version(() => {
});
}));
it('should support bindToController with bindings', async(() => {
it('should support bindToController with bindings', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1592,7 +1594,7 @@ withEachNg1Version(() => {
});
}));
it('should support single require in linking fn', async(() => {
it('should support single require in linking fn', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1635,7 +1637,7 @@ withEachNg1Version(() => {
});
}));
it('should support array require in linking fn', async(() => {
it('should support array require in linking fn', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -1688,7 +1690,7 @@ withEachNg1Version(() => {
}));
describe('with life-cycle hooks', () => {
it('should call `$onInit()` on controller', async(() => {
it('should call `$onInit()` on controller', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onInitSpyA = jasmine.createSpy('$onInitA');
const $onInitSpyB = jasmine.createSpy('$onInitB');
@ -1739,7 +1741,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$onInit()` on scope', async(() => {
it('should not call `$onInit()` on scope', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onInitSpy = jasmine.createSpy('$onInit');
@ -1785,7 +1787,7 @@ withEachNg1Version(() => {
});
}));
it('should call `$doCheck()` on controller', async(() => {
it('should call `$doCheck()` on controller', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $doCheckSpyA = jasmine.createSpy('$doCheckA');
const $doCheckSpyB = jasmine.createSpy('$doCheckB');
@ -1847,7 +1849,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$doCheck()` on scope', async(() => {
it('should not call `$doCheck()` on scope', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $doCheckSpyA = jasmine.createSpy('$doCheckA');
const $doCheckSpyB = jasmine.createSpy('$doCheckB');
@ -1904,7 +1906,7 @@ withEachNg1Version(() => {
});
}));
it('should call `$postLink()` on controller', async(() => {
it('should call `$postLink()` on controller', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $postLinkSpyA = jasmine.createSpy('$postLinkA');
const $postLinkSpyB = jasmine.createSpy('$postLinkB');
@ -1955,7 +1957,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$postLink()` on scope', async(() => {
it('should not call `$postLink()` on scope', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $postLinkSpy = jasmine.createSpy('$postLink');
@ -2520,7 +2522,7 @@ withEachNg1Version(() => {
});
describe('linking', () => {
it('should run the pre-linking after instantiating the controller', async(() => {
it('should run the pre-linking after instantiating the controller', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = [];
@ -2561,7 +2563,7 @@ withEachNg1Version(() => {
});
}));
it('should run the pre-linking function before linking', async(() => {
it('should run the pre-linking function before linking', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = [];
@ -2601,7 +2603,7 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function after linking (link: object)', async(() => {
it('should run the post-linking function after linking (link: object)', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = [];
@ -2641,7 +2643,8 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function after linking (link: function)', async(() => {
it('should run the post-linking function after linking (link: function)',
waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = [];
@ -2681,7 +2684,7 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function before `$postLink`', async(() => {
it('should run the post-linking function before `$postLink`', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = [];
@ -2724,7 +2727,7 @@ withEachNg1Version(() => {
});
describe('transclusion', () => {
it('should support single-slot transclusion', async(() => {
it('should support single-slot transclusion', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentAInstance: Ng2ComponentA;
let ng2ComponentBInstance: Ng2ComponentB;
@ -2788,7 +2791,7 @@ withEachNg1Version(() => {
});
}));
it('should support single-slot transclusion with fallback content', async(() => {
it('should support single-slot transclusion with fallback content', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -2854,7 +2857,7 @@ withEachNg1Version(() => {
});
}));
it('should support multi-slot transclusion', async(() => {
it('should support multi-slot transclusion', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component;
@ -2916,7 +2919,7 @@ withEachNg1Version(() => {
});
}));
it('should support default slot (with fallback content)', async(() => {
it('should support default slot (with fallback content)', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -2999,7 +3002,8 @@ withEachNg1Version(() => {
});
}));
it('should support optional transclusion slots (with fallback content)', async(() => {
it('should support optional transclusion slots (with fallback content)',
waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -3072,7 +3076,7 @@ withEachNg1Version(() => {
});
}));
it('should throw if a non-optional slot is not filled', async(() => {
it('should throw if a non-optional slot is not filled', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let errorMessage: string;
@ -3111,7 +3115,7 @@ withEachNg1Version(() => {
});
}));
it('should support structural directives in transcluded content', async(() => {
it('should support structural directives in transcluded content', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component;
@ -3179,7 +3183,7 @@ withEachNg1Version(() => {
}));
});
it('should bind input properties (<) of components', async(() => {
it('should bind input properties (<) of components', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -3211,7 +3215,7 @@ withEachNg1Version(() => {
});
}));
it('should support ng2 > ng1 > ng2', async(() => {
it('should support ng2 > ng1 > ng2', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module_('ng1', []);
@ -3247,7 +3251,7 @@ withEachNg1Version(() => {
describe('injection', () => {
function SomeToken() {}
it('should export ng2 instance to ng1', async(() => {
it('should export ng2 instance to ng1', waitForAsync(() => {
@NgModule({
providers: [{provide: SomeToken, useValue: 'correct_value'}],
imports: [BrowserModule],
@ -3264,7 +3268,7 @@ withEachNg1Version(() => {
});
}));
it('should export ng1 instance to ng2', async(() => {
it('should export ng1 instance to ng2', waitForAsync(() => {
@NgModule({imports: [BrowserModule]})
class MyNg2Module {
}
@ -3283,7 +3287,7 @@ withEachNg1Version(() => {
});
}));
it('should respect hierarchical dependency injection for ng2', async(() => {
it('should respect hierarchical dependency injection for ng2', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []);
@Component({selector: 'ng2-parent', template: `ng2-parent(<ng-content></ng-content>)`})
@ -3311,7 +3315,7 @@ withEachNg1Version(() => {
});
describe('testability', () => {
it('should handle deferred bootstrap', async(() => {
it('should handle deferred bootstrap', waitForAsync(() => {
@NgModule({imports: [BrowserModule]})
class MyNg2Module {
}
@ -3362,7 +3366,7 @@ withEachNg1Version(() => {
expect(value).toBe(a1Injector);
}));
it('should wait for ng2 testability', async(() => {
it('should wait for ng2 testability', waitForAsync(() => {
@NgModule({imports: [BrowserModule]})
class MyNg2Module {
}
@ -3389,7 +3393,7 @@ withEachNg1Version(() => {
});
describe('examples', () => {
it('should verify UpgradeAdapter example', async(() => {
it('should verify UpgradeAdapter example', waitForAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const module = angular.module_('myExample', []);
@ -3461,7 +3465,7 @@ withEachNg1Version(() => {
});
});
it('should be able to test ng1 components that use ng2 components', async(() => {
it('should be able to test ng1 components that use ng2 components', waitForAsync(() => {
upgradeAdapterRef.ready(() => {
const element = $compile('<ng2></ng2>')($rootScope);
$rootScope.$digest();

View File

@ -7,7 +7,7 @@
*/
import {Component, destroyPlatform, Directive, ElementRef, Injector, Input, NgModule, NgZone, SimpleChanges} from '@angular/core';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {downgradeComponent, UpgradeComponent, UpgradeModule} from '@angular/upgrade/static';
@ -22,7 +22,7 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
it('should not break if a $digest is already in progress', async(() => {
it('should not break if a $digest is already in progress', waitForAsync(() => {
const element = html('<my-app></my-app>');
@Component({selector: 'my-app', template: ''})
@ -77,7 +77,7 @@ withEachNg1Version(() => {
});
}));
it('should interleave scope and component expressions', async(() => {
it('should interleave scope and component expressions', waitForAsync(() => {
const log: string[] = [];
const l = (value: string) => {
log.push(value);
@ -132,7 +132,7 @@ withEachNg1Version(() => {
});
}));
it('should propagate changes to a downgraded component inside the ngZone', async(() => {
it('should propagate changes to a downgraded component inside the ngZone', waitForAsync(() => {
const element = html('<my-app></my-app>');
let appComponent: AppComponent;

View File

@ -7,7 +7,7 @@
*/
import {Component, destroyPlatform, Directive, ElementRef, Injector, Input, NgModule} from '@angular/core';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {downgradeComponent, UpgradeComponent, UpgradeModule} from '@angular/upgrade/static';
@ -22,7 +22,7 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
it('should instantiate ng2 in ng1 template and project content', async(() => {
it('should instantiate ng2 in ng1 template and project content', waitForAsync(() => {
// the ng2 component that will be used in ng1 (downgraded)
@Component({selector: 'ng2', template: `{{ prop }}(<ng-content></ng-content>)`})
class Ng2Component {
@ -57,7 +57,7 @@ withEachNg1Version(() => {
});
}));
it('should correctly project structural directives', async(() => {
it('should correctly project structural directives', waitForAsync(() => {
@Component({selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'})
class Ng2Component {
// TODO(issue/24571): remove '!'.
@ -94,7 +94,7 @@ withEachNg1Version(() => {
});
}));
it('should instantiate ng1 in ng2 template and project content', async(() => {
it('should instantiate ng1 in ng2 template and project content', waitForAsync(() => {
@Component({
selector: 'ng2',
template: `{{ 'ng2(' }}<ng1>{{ transclude }}</ng1>{{ ')' }}`,
@ -139,7 +139,7 @@ withEachNg1Version(() => {
});
}));
it('should support multi-slot projection', async(() => {
it('should support multi-slot projection', waitForAsync(() => {
@Component({
selector: 'ng2',
template: '2a(<ng-content select=".ng1a"></ng-content>)' +

View File

@ -7,7 +7,7 @@
*/
import {ChangeDetectionStrategy, Compiler, Component, destroyPlatform, Directive, ElementRef, EventEmitter, Injector, Input, NgModule, NgModuleRef, OnChanges, OnDestroy, Output, SimpleChanges} from '@angular/core';
import {async, fakeAsync, tick} from '@angular/core/testing';
import {fakeAsync, tick, waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {downgradeComponent, UpgradeComponent, UpgradeModule} from '@angular/upgrade/static';
@ -22,7 +22,7 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
it('should bind properties, events', async(() => {
it('should bind properties, events', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['name'] = 'world';
$rootScope['dataA'] = 'A';
@ -146,7 +146,7 @@ withEachNg1Version(() => {
});
}));
it('should bind properties to onpush components', async(() => {
it('should bind properties to onpush components', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['dataB'] = 'B';
});
@ -188,7 +188,7 @@ withEachNg1Version(() => {
});
}));
it('should support two-way binding and event listener', async(() => {
it('should support two-way binding and event listener', waitForAsync(() => {
const listenerSpy = jasmine.createSpy('$rootScope.listener');
const ng1Module = angular.module_('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['value'] = 'world';
@ -240,7 +240,7 @@ withEachNg1Version(() => {
});
}));
it('should run change-detection on every digest (by default)', async(() => {
it('should run change-detection on every digest (by default)', waitForAsync(() => {
let ng2Component: Ng2Component;
@Component({selector: 'ng2', template: '{{ value1 }} | {{ value2 }}'})
@ -305,7 +305,7 @@ withEachNg1Version(() => {
});
}));
it('should not run change-detection on every digest when opted out', async(() => {
it('should not run change-detection on every digest when opted out', waitForAsync(() => {
let ng2Component: Ng2Component;
@Component({selector: 'ng2', template: '{{ value1 }} | {{ value2 }}'})
@ -408,7 +408,7 @@ withEachNg1Version(() => {
});
}));
it('should initialize inputs in time for `ngOnChanges`', async(() => {
it('should initialize inputs in time for `ngOnChanges`', waitForAsync(() => {
@Component({
selector: 'ng2',
template: `
@ -468,7 +468,7 @@ withEachNg1Version(() => {
});
}));
it('should bind to ng-model', async(() => {
it('should bind to ng-model', waitForAsync(() => {
const ng1Module = angular.module_('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['modelA'] = 'A';
});
@ -534,7 +534,7 @@ withEachNg1Version(() => {
});
}));
it('should properly run cleanup when ng1 directive is destroyed', async(() => {
it('should properly run cleanup when ng1 directive is destroyed', waitForAsync(() => {
let destroyed = false;
@Component({selector: 'ng2', template: 'test'})
class Ng2Component implements OnDestroy {
@ -574,7 +574,7 @@ withEachNg1Version(() => {
});
}));
it('should properly run cleanup with multiple levels of nesting', async(() => {
it('should properly run cleanup with multiple levels of nesting', waitForAsync(() => {
let destroyed = false;
@Component({
@ -628,7 +628,7 @@ withEachNg1Version(() => {
}));
it('should work when compiled outside the dom (by fallback to the root ng2.injector)',
async(() => {
waitForAsync(() => {
@Component({selector: 'ng2', template: 'test'})
class Ng2Component {
}
@ -674,7 +674,7 @@ withEachNg1Version(() => {
});
}));
it('should allow attribute selectors for downgraded components', async(() => {
it('should allow attribute selectors for downgraded components', waitForAsync(() => {
@Component({selector: '[itWorks]', template: 'It works'})
class WorksComponent {
}
@ -698,7 +698,7 @@ withEachNg1Version(() => {
});
}));
it('should allow attribute selectors for components in ng2', async(() => {
it('should allow attribute selectors for components in ng2', waitForAsync(() => {
@Component({selector: '[itWorks]', template: 'It works'})
class WorksComponent {
}
@ -726,7 +726,7 @@ withEachNg1Version(() => {
});
}));
it('should respect hierarchical dependency injection for ng2', async(() => {
it('should respect hierarchical dependency injection for ng2', waitForAsync(() => {
@Component({selector: 'parent', template: 'parent(<ng-content></ng-content>)'})
class ParentComponent {
}
@ -757,7 +757,7 @@ withEachNg1Version(() => {
});
}));
it('should be compiled synchronously, if possible', async(() => {
it('should be compiled synchronously, if possible', waitForAsync(() => {
@Component({selector: 'ng2A', template: '<ng-content></ng-content>'})
class Ng2ComponentA {
}
@ -786,7 +786,7 @@ withEachNg1Version(() => {
});
}));
it('should work with ng2 lazy loaded components', async(() => {
it('should work with ng2 lazy loaded components', waitForAsync(() => {
let componentInjector: Injector;
@Component({selector: 'ng2', template: ''})
@ -836,7 +836,7 @@ withEachNg1Version(() => {
});
}));
it('should throw if `downgradedModule` is specified', async(() => {
it('should throw if `downgradedModule` is specified', waitForAsync(() => {
@Component({selector: 'ng2', template: ''})
class Ng2Component {
}

View File

@ -7,7 +7,7 @@
*/
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ApplicationRef, Compiler, Component, destroyPlatform, Directive, DoCheck, ElementRef, getPlatform, Inject, Injectable, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, OnInit, StaticProvider, Type, ViewRef} from '@angular/core';
import {async, fakeAsync, tick} from '@angular/core/testing';
import {fakeAsync, tick, waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
@ -26,7 +26,7 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
it('should support multiple downgraded modules', async(() => {
it('should support multiple downgraded modules', waitForAsync(() => {
@Component({selector: 'ng2A', template: 'a'})
class Ng2ComponentA {
}
@ -80,7 +80,7 @@ withEachNg1Version(() => {
setTimeout(() => expect(element.textContent).toBe('a | b'));
}));
it('should support nesting components from different downgraded modules', async(() => {
it('should support nesting components from different downgraded modules', waitForAsync(() => {
@Directive({selector: 'ng1A'})
class Ng1ComponentA extends UpgradeComponent {
constructor(elementRef: ElementRef, injector: Injector) {
@ -163,7 +163,7 @@ withEachNg1Version(() => {
}));
it('should support nesting components from different downgraded modules (via projection)',
async(() => {
waitForAsync(() => {
@Component({
selector: 'ng2A',
template: 'ng2A(<ng-content></ng-content>)',
@ -336,7 +336,8 @@ withEachNg1Version(() => {
expect(multiTrim(element.children[1].textContent)).toBe('Counter:1');
}));
it('should correctly traverse the injector tree of downgraded components', async(() => {
it('should correctly traverse the injector tree of downgraded components',
waitForAsync(() => {
@Component({
selector: 'ng2A',
template: 'ng2A(<ng-content></ng-content>)',
@ -423,7 +424,7 @@ withEachNg1Version(() => {
}));
it('should correctly traverse the injector tree of downgraded components (from different modules)',
async(() => {
waitForAsync(() => {
@Component({
selector: 'ng2A',
template: 'ng2A(<ng-content></ng-content>)',
@ -544,7 +545,7 @@ withEachNg1Version(() => {
});
}));
it('should support downgrading a component and propagate inputs', async(() => {
it('should support downgrading a component and propagate inputs', waitForAsync(() => {
@Component(
{selector: 'ng2A', template: 'a({{ value }}) | <ng2B [value]="value"></ng2B>'})
class Ng2AComponent {
@ -598,7 +599,7 @@ withEachNg1Version(() => {
});
}));
it('should support using an upgraded service', async(() => {
it('should support using an upgraded service', waitForAsync(() => {
@Injectable()
class Ng2Service {
constructor(@Inject('ng1Value') private ng1Value: string) {}
@ -658,7 +659,7 @@ withEachNg1Version(() => {
});
}));
it('should create components inside the Angular zone', async(() => {
it('should create components inside the Angular zone', waitForAsync(() => {
@Component({selector: 'ng2', template: 'In the zone: {{ inTheZone }}'})
class Ng2Component {
private inTheZone = false;
@ -694,7 +695,7 @@ withEachNg1Version(() => {
});
}));
it('should destroy components inside the Angular zone', async(() => {
it('should destroy components inside the Angular zone', waitForAsync(() => {
let destroyedInTheZone = false;
@Component({selector: 'ng2', template: ''})
@ -732,7 +733,7 @@ withEachNg1Version(() => {
});
}));
it('should propagate input changes inside the Angular zone', async(() => {
it('should propagate input changes inside the Angular zone', waitForAsync(() => {
let ng2Component: Ng2Component;
@Component({selector: 'ng2', template: ''})
@ -793,7 +794,7 @@ withEachNg1Version(() => {
}));
it('should create and destroy nested, asynchronously instantiated components inside the Angular zone',
async(() => {
waitForAsync(() => {
let createdInTheZone = false;
let destroyedInTheZone = false;
@ -858,7 +859,7 @@ withEachNg1Version(() => {
});
}));
it('should wire up the component for change detection', async(() => {
it('should wire up the component for change detection', waitForAsync(() => {
@Component(
{selector: 'ng2', template: '{{ count }}<button (click)="increment()"></button>'})
class Ng2Component {
@ -903,7 +904,7 @@ withEachNg1Version(() => {
}));
it('should wire up nested, asynchronously instantiated components for change detection',
async(() => {
waitForAsync(() => {
@Component(
{selector: 'test', template: '{{ count }}<button (click)="increment()"></button>'})
class TestComponent {
@ -961,7 +962,7 @@ withEachNg1Version(() => {
});
}));
it('should run the lifecycle hooks in the correct order', async(() => {
it('should run the lifecycle hooks in the correct order', waitForAsync(() => {
const logs: string[] = [];
let rootScope: angular.IRootScopeService;
@ -1138,7 +1139,7 @@ withEachNg1Version(() => {
});
}));
it('should detach hostViews from the ApplicationRef once destroyed', async(() => {
it('should detach hostViews from the ApplicationRef once destroyed', waitForAsync(() => {
let ng2Component: Ng2Component;
@Component({selector: 'ng2', template: ''})
@ -1253,7 +1254,8 @@ withEachNg1Version(() => {
$rootScope.$destroy();
}));
it('should give access to both injectors in the Angular module\'s constructor', async(() => {
it('should give access to both injectors in the Angular module\'s constructor',
waitForAsync(() => {
let $injectorFromNg2: angular.IInjectorService|null = null;
@Component({selector: 'ng2', template: ''})
@ -1341,7 +1343,7 @@ withEachNg1Version(() => {
// Explicitly clean up after each test to prevent that.
afterEach(() => setTempInjectorRef(null!));
it('should throw if no downgraded module is included', async(() => {
it('should throw if no downgraded module is included', waitForAsync(() => {
const ng1Module = angular.module_('ng1', [])
.value($EXCEPTION_HANDLER, errorSpy)
.directive('ng2A', downgradeComponent({
@ -1374,7 +1376,8 @@ withEachNg1Version(() => {
'<ng2-b>');
}));
it('should throw if the corresponding downgraded module is not included', async(() => {
it('should throw if the corresponding downgraded module is not included',
waitForAsync(() => {
const ng1Module = angular.module_('ng1', [downModA])
.value($EXCEPTION_HANDLER, errorSpy)
.directive('ng2A', downgradeComponent({
@ -1402,7 +1405,7 @@ withEachNg1Version(() => {
}));
it('should throw if `downgradedModule` is not specified and there are multiple downgraded modules',
async(() => {
waitForAsync(() => {
const ng1Module = angular.module_('ng1', [downModA, downModB])
.value($EXCEPTION_HANDLER, errorSpy)
.directive('ng2A', downgradeComponent({

View File

@ -7,7 +7,7 @@
*/
import {Component, destroyPlatform, Directive, ElementRef, Injector, Input, NgModule} from '@angular/core';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {downgradeComponent, UpgradeComponent, UpgradeModule} from '@angular/upgrade/static';
@ -25,7 +25,7 @@ withEachNg1Version(() => {
it('should have AngularJS loaded',
() => expect(angular.getAngularJSGlobal().version.major).toBe(1));
it('should verify UpgradeAdapter example', async(() => {
it('should verify UpgradeAdapter example', waitForAsync(() => {
// This is wrapping (upgrading) an AngularJS component to be used in an Angular
// component
@Directive({selector: 'ng1'})

View File

@ -7,7 +7,7 @@
*/
import {destroyPlatform, InjectionToken, Injector, NgModule} from '@angular/core';
import {async} from '@angular/core/testing';
import {waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@ -23,7 +23,7 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
it('should downgrade ng2 service to ng1', async(() => {
it('should downgrade ng2 service to ng1', waitForAsync(() => {
// Tokens used in ng2 to identify services
const Ng2Service = new InjectionToken('ng2-service');
@ -49,7 +49,7 @@ withEachNg1Version(() => {
});
}));
it('should upgrade ng1 service to ng2', async(() => {
it('should upgrade ng1 service to ng2', waitForAsync(() => {
// Tokens used in ng2 to identify services
const Ng1Service = new InjectionToken('ng1-service');
@ -81,7 +81,7 @@ withEachNg1Version(() => {
}));
it('should initialize the upgraded injector before application run blocks are executed',
async(() => {
waitForAsync(() => {
let runBlockTriggered = false;
const ng1Module = angular.module_('ng1Module', []).run([
@ -102,7 +102,7 @@ withEachNg1Version(() => {
});
}));
it('should allow resetting angular at runtime', async(() => {
it('should allow resetting angular at runtime', waitForAsync(() => {
let wrappedBootstrapCalled = false;
const n: any = getAngularJSGlobal();

View File

@ -7,7 +7,7 @@
*/
import {Component, destroyPlatform, Directive, ElementRef, EventEmitter, Inject, Injector, Input, NgModule, NO_ERRORS_SCHEMA, Output, SimpleChanges} from '@angular/core';
import {async, fakeAsync, tick} from '@angular/core/testing';
import {fakeAsync, tick, waitForAsync} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@ -25,7 +25,7 @@ withEachNg1Version(() => {
afterEach(() => destroyPlatform());
describe('template/templateUrl', () => {
it('should support `template` (string)', async(() => {
it('should support `template` (string)', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {template: 'Hello, Angular!'};
@ -65,7 +65,7 @@ withEachNg1Version(() => {
});
}));
it('should support `template` (function)', async(() => {
it('should support `template` (function)', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {template: () => 'Hello, Angular!'};
@ -105,7 +105,7 @@ withEachNg1Version(() => {
});
}));
it('should pass $element to `template` function and not $attrs', async(() => {
it('should pass $element to `template` function and not $attrs', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {
template: ($attrs: angular.IAttributes, $element: angular.IAugmentedJQuery) => {
@ -152,7 +152,7 @@ withEachNg1Version(() => {
});
}));
it('should support `templateUrl` (string) fetched from `$templateCache`', async(() => {
it('should support `templateUrl` (string) fetched from `$templateCache`', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {templateUrl: 'ng1.component.html'};
@ -196,7 +196,8 @@ withEachNg1Version(() => {
});
}));
it('should support `templateUrl` (function) fetched from `$templateCache`', async(() => {
it('should support `templateUrl` (function) fetched from `$templateCache`',
waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {templateUrl: () => 'ng1.component.html'};
@ -240,7 +241,7 @@ withEachNg1Version(() => {
});
}));
it('should pass $element to `templateUrl` function and not $attrs', async(() => {
it('should pass $element to `templateUrl` function and not $attrs', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {
templateUrl: ($attrs: angular.IAttributes, $element: angular.IAugmentedJQuery) => {
@ -393,7 +394,7 @@ withEachNg1Version(() => {
});
}));
it('should support empty templates', async(() => {
it('should support empty templates', waitForAsync(() => {
// Define `ng1Component`s
const ng1ComponentA: angular.IComponent = {template: ''};
const ng1ComponentB: angular.IComponent = {template: () => ''};
@ -1063,7 +1064,7 @@ withEachNg1Version(() => {
});
describe('compiling', () => {
it('should compile the ng1 template in the correct DOM context', async(() => {
it('should compile the ng1 template in the correct DOM context', waitForAsync(() => {
let grandParentNodeName: string;
// Define `ng1Component`
@ -1114,7 +1115,7 @@ withEachNg1Version(() => {
});
describe('linking', () => {
it('should run the pre-linking after instantiating the controller', async(() => {
it('should run the pre-linking after instantiating the controller', waitForAsync(() => {
const log: string[] = [];
// Define `ng1Directive`
@ -1164,7 +1165,7 @@ withEachNg1Version(() => {
});
}));
it('should run the pre-linking function before linking', async(() => {
it('should run the pre-linking function before linking', waitForAsync(() => {
const log: string[] = [];
// Define `ng1Directive`
@ -1212,7 +1213,7 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function after linking (link: object)', async(() => {
it('should run the post-linking function after linking (link: object)', waitForAsync(() => {
const log: string[] = [];
// Define `ng1Directive`
@ -1260,7 +1261,7 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function after linking (link: function)', async(() => {
it('should run the post-linking function after linking (link: function)', waitForAsync(() => {
const log: string[] = [];
// Define `ng1Directive`
@ -1308,7 +1309,7 @@ withEachNg1Version(() => {
});
}));
it('should run the post-linking function before `$postLink`', async(() => {
it('should run the post-linking function before `$postLink`', waitForAsync(() => {
const log: string[] = [];
// Define `ng1Directive`
@ -1360,7 +1361,7 @@ withEachNg1Version(() => {
});
describe('controller', () => {
it('should support `controllerAs`', async(() => {
it('should support `controllerAs`', waitForAsync(() => {
// Define `ng1Directive`
const ng1Directive: angular.IDirective = {
template:
@ -1425,7 +1426,7 @@ withEachNg1Version(() => {
});
}));
it('should support `bindToController` (boolean)', async(() => {
it('should support `bindToController` (boolean)', waitForAsync(() => {
// Define `ng1Directive`
const ng1DirectiveA: angular.IDirective = {
template: 'Scope: {{ title }}; Controller: {{ $ctrl.title }}',
@ -1501,7 +1502,7 @@ withEachNg1Version(() => {
});
}));
it('should support `bindToController` (object)', async(() => {
it('should support `bindToController` (object)', waitForAsync(() => {
// Define `ng1Directive`
const ng1Directive: angular.IDirective = {
template: '{{ $ctrl.title }}',
@ -1552,7 +1553,7 @@ withEachNg1Version(() => {
});
}));
it('should support `controller` as string', async(() => {
it('should support `controller` as string', waitForAsync(() => {
// Define `ng1Directive`
const ng1Directive: angular.IDirective = {
template: '{{ $ctrl.title }} {{ $ctrl.text }}',
@ -1605,7 +1606,8 @@ withEachNg1Version(() => {
});
}));
it('should insert the compiled content before instantiating the controller', async(() => {
it('should insert the compiled content before instantiating the controller',
waitForAsync(() => {
let compiledContent: string;
let getCurrentContent: () => string;
@ -1663,7 +1665,7 @@ withEachNg1Version(() => {
describe('require', () => {
// NOT YET SUPPORTED
xdescribe('in pre-/post-link', () => {
it('should resolve to its own controller if falsy', async(() => {
it('should resolve to its own controller if falsy', waitForAsync(() => {
// Define `ng1Directive`
const ng1Directive: angular.IDirective = {
template: 'Pre: {{ pre }} | Post: {{ post }}',
@ -1720,7 +1722,7 @@ withEachNg1Version(() => {
});
describe('in controller', () => {
it('should be available to children', async(() => {
it('should be available to children', waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: '<ng1-b></ng1-b>',
@ -1771,7 +1773,7 @@ withEachNg1Version(() => {
});
}));
it('should throw if required controller cannot be found', async(() => {
it('should throw if required controller cannot be found', waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {require: {foo: 'iDoNotExist'}};
const ng1ComponentB: angular.IComponent = {require: {foo: '^iDoNotExist'}};
@ -1861,7 +1863,7 @@ withEachNg1Version(() => {
});
}));
it('should not throw if missing required controller is optional', async(() => {
it('should not throw if missing required controller is optional', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {
require: {
@ -1910,7 +1912,7 @@ withEachNg1Version(() => {
}));
it('should assign resolved values to the controller instance (if `require` is not object)',
async(() => {
waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: 'ng1A(<div><ng2></ng2></div>)',
@ -1988,7 +1990,7 @@ withEachNg1Version(() => {
}));
it('should assign resolved values to the controller instance (if `require` is object)',
async(() => {
waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: 'ng1A(<div><ng2></ng2></div>)',
@ -2058,7 +2060,7 @@ withEachNg1Version(() => {
});
}));
it('should assign to controller before calling `$onInit()`', async(() => {
it('should assign to controller before calling `$onInit()`', waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: '<ng2></ng2>',
@ -2115,7 +2117,8 @@ withEachNg1Version(() => {
});
}));
it('should use the key as name if the required controller name is omitted', async(() => {
it('should use the key as name if the required controller name is omitted',
waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: '<ng1-b></ng1-b>',
@ -2185,7 +2188,7 @@ withEachNg1Version(() => {
});
describe('transclusion', () => {
it('should support single-slot transclusion', async(() => {
it('should support single-slot transclusion', waitForAsync(() => {
let ng2ComponentAInstance: Ng2ComponentA;
let ng2ComponentBInstance: Ng2ComponentB;
@ -2256,7 +2259,7 @@ withEachNg1Version(() => {
});
}));
it('should support single-slot transclusion with fallback content', async(() => {
it('should support single-slot transclusion with fallback content', waitForAsync(() => {
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -2318,7 +2321,7 @@ withEachNg1Version(() => {
});
}));
it('should support multi-slot transclusion', async(() => {
it('should support multi-slot transclusion', waitForAsync(() => {
let ng2ComponentInstance: Ng2Component;
// Define `ng1Component`
@ -2387,7 +2390,7 @@ withEachNg1Version(() => {
});
}));
it('should support default slot (with fallback content)', async(() => {
it('should support default slot (with fallback content)', waitForAsync(() => {
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -2471,7 +2474,7 @@ withEachNg1Version(() => {
});
}));
it('should support optional transclusion slots (with fallback content)', async(() => {
it('should support optional transclusion slots (with fallback content)', waitForAsync(() => {
let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component;
@ -2553,7 +2556,7 @@ withEachNg1Version(() => {
});
}));
it('should throw if a non-optional slot is not filled', async(() => {
it('should throw if a non-optional slot is not filled', waitForAsync(() => {
let errorMessage: string;
// Define `ng1Component`
@ -2601,7 +2604,7 @@ withEachNg1Version(() => {
});
}));
it('should support structural directives in transcluded content', async(() => {
it('should support structural directives in transcluded content', waitForAsync(() => {
let ng2ComponentInstance: Ng2Component;
// Define `ng1Component`
@ -2984,7 +2987,7 @@ withEachNg1Version(() => {
});
}));
it('should call `$onInit()` on controller', async(() => {
it('should call `$onInit()` on controller', waitForAsync(() => {
// Define `ng1Directive`
const ng1DirectiveA: angular.IDirective = {
template: 'Called: {{ called }}',
@ -3055,7 +3058,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$onInit()` on scope', async(() => {
it('should not call `$onInit()` on scope', waitForAsync(() => {
// Define `ng1Directive`
const ng1DirectiveA: angular.IDirective = {
template: 'Called: {{ called }}',
@ -3125,7 +3128,7 @@ withEachNg1Version(() => {
});
}));
it('should call `$postLink()` on controller', async(() => {
it('should call `$postLink()` on controller', waitForAsync(() => {
// Define `ng1Directive`
const ng1DirectiveA: angular.IDirective = {
template: 'Called: {{ called }}',
@ -3196,7 +3199,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$postLink()` on scope', async(() => {
it('should not call `$postLink()` on scope', waitForAsync(() => {
// Define `ng1Directive`
const ng1DirectiveA: angular.IDirective = {
template: 'Called: {{ called }}',
@ -3267,7 +3270,7 @@ withEachNg1Version(() => {
}));
it('should call `$doCheck()` on controller', async(() => {
it('should call `$doCheck()` on controller', waitForAsync(() => {
const controllerDoCheckA = jasmine.createSpy('controllerDoCheckA');
const controllerDoCheckB = jasmine.createSpy('controllerDoCheckB');
@ -3354,7 +3357,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$doCheck()` on scope', async(() => {
it('should not call `$doCheck()` on scope', waitForAsync(() => {
const scopeDoCheck = jasmine.createSpy('scopeDoCheck');
// Define `ng1Directive`
@ -3432,7 +3435,7 @@ withEachNg1Version(() => {
}));
it('should call `$onDestroy()` on controller', async(() => {
it('should call `$onDestroy()` on controller', waitForAsync(() => {
const controllerOnDestroyA = jasmine.createSpy('controllerOnDestroyA');
const controllerOnDestroyB = jasmine.createSpy('controllerOnDestroyB');
@ -3532,7 +3535,7 @@ withEachNg1Version(() => {
});
}));
it('should not call `$onDestroy()` on scope', async(() => {
it('should not call `$onDestroy()` on scope', waitForAsync(() => {
const scopeOnDestroy = jasmine.createSpy('scopeOnDestroy');
// Define `ng1Directive`
@ -3628,7 +3631,7 @@ withEachNg1Version(() => {
}));
it('should be called in order `$onChanges()` > `$onInit()` > `$doCheck()` > `$postLink()`',
async(() => {
waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {
// `$doCheck()` will keep getting called as long as the interpolated value keeps
@ -3697,7 +3700,7 @@ withEachNg1Version(() => {
});
describe('destroying the upgraded component', () => {
it('should destroy `$componentScope`', async(() => {
it('should destroy `$componentScope`', waitForAsync(() => {
const scopeDestroyListener = jasmine.createSpy('scopeDestroyListener');
let ng2ComponentAInstance: Ng2ComponentA;
@ -3760,7 +3763,7 @@ withEachNg1Version(() => {
});
}));
it('should emit `$destroy` on `$element` and descendants', async(() => {
it('should emit `$destroy` on `$element` and descendants', waitForAsync(() => {
const elementDestroyListener = jasmine.createSpy('elementDestroyListener');
const descendantDestroyListener = jasmine.createSpy('descendantDestroyListener');
let ng2ComponentAInstance: Ng2ComponentA;
@ -3828,7 +3831,7 @@ withEachNg1Version(() => {
});
}));
it('should clear data on `$element` and descendants`', async(() => {
it('should clear data on `$element` and descendants`', waitForAsync(() => {
let ng1ComponentElement: angular.IAugmentedJQuery;
let ng2ComponentAInstance: Ng2ComponentA;
@ -3897,7 +3900,7 @@ withEachNg1Version(() => {
});
}));
it('should clear dom listeners on `$element` and descendants`', async(() => {
it('should clear dom listeners on `$element` and descendants`', waitForAsync(() => {
const elementClickListener = jasmine.createSpy('elementClickListener');
const descendantClickListener = jasmine.createSpy('descendantClickListener');
let ng1DescendantElement: angular.IAugmentedJQuery;
@ -3970,7 +3973,7 @@ withEachNg1Version(() => {
});
}));
it('should clean up `$doCheck()` watchers from the parent scope', async(() => {
it('should clean up `$doCheck()` watchers from the parent scope', waitForAsync(() => {
let ng2Component: Ng2Component;
// Define `ng1Component`
@ -4041,7 +4044,7 @@ withEachNg1Version(() => {
}));
});
it('should support ng2 > ng1 > ng2 (no inputs/outputs)', async(() => {
it('should support ng2 > ng1 > ng2 (no inputs/outputs)', waitForAsync(() => {
// Define `ng1Component`
const ng1Component: angular.IComponent = {template: 'ng1X(<ng2-b></ng2-b>)'};
@ -4283,7 +4286,7 @@ withEachNg1Version(() => {
});
}));
it('should support ng2 > ng1 > ng2 > ng1 (with `require`)', async(() => {
it('should support ng2 > ng1 > ng2 > ng1 (with `require`)', waitForAsync(() => {
// Define `ng1Component`
const ng1ComponentA: angular.IComponent = {
template: 'ng1A(<ng2-b></ng2-b>)',