test(ivy): update root causes for @angular/core TestBed failures (#27370)
PR Close #27370
This commit is contained in:
parent
eb17502a7c
commit
1fa5478fef
|
@ -135,7 +135,7 @@ class SomeComponent {
|
|||
describe('ApplicationRef', () => {
|
||||
beforeEach(() => { TestBed.configureTestingModule({imports: [createModule()]}); });
|
||||
|
||||
fixmeIvy('unknown') && it('should throw when reentering tick', () => {
|
||||
it('should throw when reentering tick', () => {
|
||||
@Component({template: '{{reenter()}}'})
|
||||
class ReenteringComponent {
|
||||
reenterCount = 1;
|
||||
|
@ -185,22 +185,19 @@ class SomeComponent {
|
|||
});
|
||||
|
||||
describe('bootstrap', () => {
|
||||
fixmeIvy('unknown') &&
|
||||
it('should throw if an APP_INITIIALIZER is not yet resolved',
|
||||
withModule(
|
||||
{
|
||||
providers: [{
|
||||
provide: APP_INITIALIZER,
|
||||
useValue: () => new Promise(() => {}),
|
||||
multi: true
|
||||
}]
|
||||
},
|
||||
inject([ApplicationRef], (ref: ApplicationRef) => {
|
||||
createRootEl();
|
||||
expect(() => ref.bootstrap(SomeComponent))
|
||||
.toThrowError(
|
||||
'Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
|
||||
})));
|
||||
it('should throw if an APP_INITIIALIZER is not yet resolved',
|
||||
withModule(
|
||||
{
|
||||
providers: [
|
||||
{provide: APP_INITIALIZER, useValue: () => new Promise(() => {}), multi: true}
|
||||
]
|
||||
},
|
||||
inject([ApplicationRef], (ref: ApplicationRef) => {
|
||||
createRootEl();
|
||||
expect(() => ref.bootstrap(SomeComponent))
|
||||
.toThrowError(
|
||||
'Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -211,112 +208,99 @@ class SomeComponent {
|
|||
defaultPlatform = _platform;
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for asynchronous app initializers', async(() => {
|
||||
let resolve: (result: any) => void;
|
||||
const promise: Promise<any> = new Promise((res) => { resolve = res; });
|
||||
let initializerDone = false;
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
initializerDone = true;
|
||||
}, 1);
|
||||
it('should wait for asynchronous app initializers', async(() => {
|
||||
let resolve: (result: any) => void;
|
||||
const promise: Promise<any> = new Promise((res) => { resolve = res; });
|
||||
let initializerDone = false;
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
initializerDone = true;
|
||||
}, 1);
|
||||
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => promise, multi: true}]))
|
||||
.then(_ => { expect(initializerDone).toBe(true); });
|
||||
}));
|
||||
defaultPlatform
|
||||
.bootstrapModule(
|
||||
createModule([{provide: APP_INITIALIZER, useValue: () => promise, multi: true}]))
|
||||
.then(_ => { expect(initializerDone).toBe(true); });
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should rethrow sync errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule([
|
||||
{provide: APP_INITIALIZER, useValue: () => { throw 'Test'; }, multi: true}
|
||||
]))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
// Error rethrown will be seen by the exception handler since it's after
|
||||
// construction.
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
it('should rethrow sync errors even if the exceptionHandler is not rethrowing', async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => { throw 'Test'; }, multi: true}]))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
// Error rethrown will be seen by the exception handler since it's after
|
||||
// construction.
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule([{
|
||||
provide: APP_INITIALIZER,
|
||||
useValue: () => Promise.reject('Test'),
|
||||
multi: true
|
||||
}]))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule([
|
||||
{provide: APP_INITIALIZER, useValue: () => Promise.reject('Test'), multi: true}
|
||||
]))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should throw useful error when ApplicationRef is not configured', async(() => {
|
||||
@NgModule()
|
||||
class EmptyModule {
|
||||
}
|
||||
it('should throw useful error when ApplicationRef is not configured', async(() => {
|
||||
@NgModule()
|
||||
class EmptyModule {
|
||||
}
|
||||
|
||||
return defaultPlatform.bootstrapModule(EmptyModule)
|
||||
.then(() => fail('expecting error'), (error) => {
|
||||
expect(error.message)
|
||||
.toEqual('No ErrorHandler. Is platform module (BrowserModule) included?');
|
||||
});
|
||||
}));
|
||||
return defaultPlatform.bootstrapModule(EmptyModule)
|
||||
.then(() => fail('expecting error'), (error) => {
|
||||
expect(error.message)
|
||||
.toEqual('No ErrorHandler. Is platform module (BrowserModule) included?');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should call the `ngDoBootstrap` method with `ApplicationRef` on the main module',
|
||||
async(() => {
|
||||
const ngDoBootstrap = jasmine.createSpy('ngDoBootstrap');
|
||||
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: ngDoBootstrap}))
|
||||
.then((moduleRef) => {
|
||||
const appRef = moduleRef.injector.get(ApplicationRef);
|
||||
expect(ngDoBootstrap).toHaveBeenCalledWith(appRef);
|
||||
});
|
||||
}));
|
||||
it('should call the `ngDoBootstrap` method with `ApplicationRef` on the main module',
|
||||
async(() => {
|
||||
const ngDoBootstrap = jasmine.createSpy('ngDoBootstrap');
|
||||
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: ngDoBootstrap}))
|
||||
.then((moduleRef) => {
|
||||
const appRef = moduleRef.injector.get(ApplicationRef);
|
||||
expect(ngDoBootstrap).toHaveBeenCalledWith(appRef);
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should auto bootstrap components listed in @NgModule.bootstrap', async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
|
||||
.then((moduleRef) => {
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
expect(appRef.componentTypes).toEqual([SomeComponent]);
|
||||
});
|
||||
}));
|
||||
it('should auto bootstrap components listed in @NgModule.bootstrap', async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
|
||||
.then((moduleRef) => {
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
expect(appRef.componentTypes).toEqual([SomeComponent]);
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should error if neither `ngDoBootstrap` nor @NgModule.bootstrap was specified',
|
||||
async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: false}))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
const expectedErrMsg =
|
||||
`The module MyModule was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.`;
|
||||
expect(e.message).toEqual(expectedErrMsg);
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Error: ' + expectedErrMsg);
|
||||
});
|
||||
}));
|
||||
it('should error if neither `ngDoBootstrap` nor @NgModule.bootstrap was specified',
|
||||
async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({ngDoBootstrap: false}))
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
const expectedErrMsg =
|
||||
`The module MyModule was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.`;
|
||||
expect(e.message).toEqual(expectedErrMsg);
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Error: ' + expectedErrMsg);
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should add bootstrapped module into platform modules list', async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
|
||||
.then(module => expect((<any>defaultPlatform)._modules).toContain(module));
|
||||
}));
|
||||
it('should add bootstrapped module into platform modules list', async(() => {
|
||||
defaultPlatform.bootstrapModule(createModule({bootstrap: [SomeComponent]}))
|
||||
.then(module => expect((<any>defaultPlatform)._modules).toContain(module));
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should bootstrap with NoopNgZone', async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule({bootstrap: [SomeComponent]}), {ngZone: 'noop'})
|
||||
.then((module) => {
|
||||
const ngZone = module.injector.get(NgZone);
|
||||
expect(ngZone instanceof NoopNgZone).toBe(true);
|
||||
});
|
||||
}));
|
||||
it('should bootstrap with NoopNgZone', async(() => {
|
||||
defaultPlatform
|
||||
.bootstrapModule(createModule({bootstrap: [SomeComponent]}), {ngZone: 'noop'})
|
||||
.then((module) => {
|
||||
const ngZone = module.injector.get(NgZone);
|
||||
expect(ngZone instanceof NoopNgZone).toBe(true);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('bootstrapModuleFactory', () => {
|
||||
|
@ -325,58 +309,47 @@ class SomeComponent {
|
|||
createRootEl();
|
||||
defaultPlatform = _platform;
|
||||
}));
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for asynchronous app initializers', async(() => {
|
||||
let resolve: (result: any) => void;
|
||||
const promise: Promise<any> = new Promise((res) => { resolve = res; });
|
||||
let initializerDone = false;
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
initializerDone = true;
|
||||
}, 1);
|
||||
it('should wait for asynchronous app initializers', async(() => {
|
||||
let resolve: (result: any) => void;
|
||||
const promise: Promise<any> = new Promise((res) => { resolve = res; });
|
||||
let initializerDone = false;
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
initializerDone = true;
|
||||
}, 1);
|
||||
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory =
|
||||
compilerFactory.createCompiler().compileModuleSync(createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => promise, multi: true}]));
|
||||
defaultPlatform.bootstrapModuleFactory(moduleFactory).then(_ => {
|
||||
expect(initializerDone).toBe(true);
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory = compilerFactory.createCompiler().compileModuleSync(
|
||||
createModule([{provide: APP_INITIALIZER, useValue: () => promise, multi: true}]));
|
||||
defaultPlatform.bootstrapModuleFactory(moduleFactory).then(_ => {
|
||||
expect(initializerDone).toBe(true);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should rethrow sync errors even if the exceptionHandler is not rethrowing', async(() => {
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory = compilerFactory.createCompiler().compileModuleSync(createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => { throw 'Test'; }, multi: true}]));
|
||||
expect(() => defaultPlatform.bootstrapModuleFactory(moduleFactory)).toThrow('Test');
|
||||
// Error rethrown will be seen by the exception handler since it's after
|
||||
// construction.
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
}));
|
||||
|
||||
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory = compilerFactory.createCompiler().compileModuleSync(createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => Promise.reject('Test'), multi: true}]));
|
||||
defaultPlatform.bootstrapModuleFactory(moduleFactory)
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should rethrow sync errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory =
|
||||
compilerFactory.createCompiler().compileModuleSync(createModule([
|
||||
{provide: APP_INITIALIZER, useValue: () => { throw 'Test'; }, multi: true}
|
||||
]));
|
||||
expect(() => defaultPlatform.bootstrapModuleFactory(moduleFactory)).toThrow('Test');
|
||||
// Error rethrown will be seen by the exception handler since it's after
|
||||
// construction.
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should rethrow promise errors even if the exceptionHandler is not rethrowing',
|
||||
async(() => {
|
||||
const compilerFactory: CompilerFactory =
|
||||
defaultPlatform.injector.get(CompilerFactory, null);
|
||||
const moduleFactory =
|
||||
compilerFactory.createCompiler().compileModuleSync(createModule([{
|
||||
provide: APP_INITIALIZER,
|
||||
useValue: () => Promise.reject('Test'),
|
||||
multi: true
|
||||
}]));
|
||||
defaultPlatform.bootstrapModuleFactory(moduleFactory)
|
||||
.then(() => expect(false).toBe(true), (e) => {
|
||||
expect(e).toBe('Test');
|
||||
expect(mockConsole.res[0].join('#')).toEqual('ERROR#Test');
|
||||
});
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
||||
describe('attachView / detachView', () => {
|
||||
|
@ -565,22 +538,20 @@ class SomeComponent {
|
|||
});
|
||||
}
|
||||
|
||||
fixmeIvy('unknown') && it('isStable should fire on synchronous component loading',
|
||||
async(() => { expectStableTexts(SyncComp, ['1']); }));
|
||||
it('isStable should fire on synchronous component loading',
|
||||
async(() => { expectStableTexts(SyncComp, ['1']); }));
|
||||
|
||||
fixmeIvy('unknown') && it('isStable should fire after a microtask on init is completed',
|
||||
async(() => { expectStableTexts(MicroTaskComp, ['11']); }));
|
||||
it('isStable should fire after a microtask on init is completed',
|
||||
async(() => { expectStableTexts(MicroTaskComp, ['11']); }));
|
||||
|
||||
fixmeIvy('unknown') && it('isStable should fire after a macrotask on init is completed',
|
||||
async(() => { expectStableTexts(MacroTaskComp, ['11']); }));
|
||||
it('isStable should fire after a macrotask on init is completed',
|
||||
async(() => { expectStableTexts(MacroTaskComp, ['11']); }));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('isStable should fire only after chain of micro and macrotasks on init are completed',
|
||||
async(() => { expectStableTexts(MicroMacroTaskComp, ['111']); }));
|
||||
it('isStable should fire only after chain of micro and macrotasks on init are completed',
|
||||
async(() => { expectStableTexts(MicroMacroTaskComp, ['111']); }));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('isStable should fire only after chain of macro and microtasks on init are completed',
|
||||
async(() => { expectStableTexts(MacroMicroTaskComp, ['111']); }));
|
||||
it('isStable should fire only after chain of macro and microtasks on init are completed',
|
||||
async(() => { expectStableTexts(MacroMicroTaskComp, ['111']); }));
|
||||
|
||||
describe('unstable', () => {
|
||||
let unstableCalled = false;
|
||||
|
@ -601,19 +572,19 @@ class SomeComponent {
|
|||
});
|
||||
}
|
||||
|
||||
fixmeIvy('unknown') && it('should be fired after app becomes unstable', async(() => {
|
||||
const fixture = TestBed.createComponent(ClickComp);
|
||||
const appRef: ApplicationRef = TestBed.get(ApplicationRef);
|
||||
const zone: NgZone = TestBed.get(NgZone);
|
||||
appRef.attachView(fixture.componentRef.hostView);
|
||||
zone.run(() => appRef.tick());
|
||||
it('should be fired after app becomes unstable', async(() => {
|
||||
const fixture = TestBed.createComponent(ClickComp);
|
||||
const appRef: ApplicationRef = TestBed.get(ApplicationRef);
|
||||
const zone: NgZone = TestBed.get(NgZone);
|
||||
appRef.attachView(fixture.componentRef.hostView);
|
||||
zone.run(() => appRef.tick());
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
expectUnstable(appRef);
|
||||
const element = fixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
});
|
||||
}));
|
||||
fixture.whenStable().then(() => {
|
||||
expectUnstable(appRef);
|
||||
const element = fixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import {Component, Injectable, Input} from '@angular/core';
|
|||
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBed, async, withModule} from '@angular/core/testing';
|
||||
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
@Component({selector: 'simple-comp', template: `<span>Original {{simpleBinding}}</span>`})
|
||||
@Injectable()
|
||||
|
@ -94,7 +93,7 @@ class NestedAsyncTimeoutComp {
|
|||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should auto detect changes if autoDetectChanges is called', () => {
|
||||
it('should auto detect changes if autoDetectChanges is called', () => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AutoDetectComp);
|
||||
expect(componentFixture.ngZone).not.toBeNull();
|
||||
|
@ -108,192 +107,181 @@ class NestedAsyncTimeoutComp {
|
|||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should auto detect changes if ComponentFixtureAutoDetect is provided as true',
|
||||
withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}, () => {
|
||||
it('should auto detect changes if ComponentFixtureAutoDetect is provided as true',
|
||||
withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}, () => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AutoDetectComp);
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
const componentFixture = TestBed.createComponent(AutoDetectComp);
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
}));
|
||||
|
||||
it('should signal through whenStable when the fixture is stable (autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncComp);
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become stable
|
||||
// before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should signal through isStable when the fixture is stable (no autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncComp);
|
||||
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become stable
|
||||
// before checking.
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
|
||||
'(autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
|
||||
'(no autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
|
||||
'(autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
|
||||
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
|
||||
'(no autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should stabilize after async task in change detection (autoDetectChanges)', async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncChangeComp);
|
||||
|
||||
componentFixture.autoDetectChanges();
|
||||
componentFixture.whenStable().then((_) => {
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
|
||||
componentFixture.whenStable().then(
|
||||
(_) => { expect(componentFixture.nativeElement).toHaveText('11'); });
|
||||
});
|
||||
}));
|
||||
|
||||
it('should stabilize after async task in change detection(no autoDetectChanges)', async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncChangeComp);
|
||||
componentFixture.detectChanges();
|
||||
componentFixture.whenStable().then((_) => {
|
||||
// Run detectChanges again so that stabilized value is reflected in the
|
||||
// DOM.
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
componentFixture.detectChanges();
|
||||
|
||||
componentFixture.whenStable().then((_) => {
|
||||
// Run detectChanges again so that stabilized value is reflected in
|
||||
// the DOM.
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should signal through whenStable when the fixture is stable (autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncComp);
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become stable
|
||||
// before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should signal through isStable when the fixture is stable (no autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncComp);
|
||||
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become stable
|
||||
// before checking.
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
|
||||
'(autoDetectChanges)',
|
||||
async(() => {
|
||||
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
|
||||
'(no autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
|
||||
'(autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
|
||||
|
||||
componentFixture.autoDetectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
|
||||
'(no autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
// Component is updated asynchronously. Wait for the fixture to become
|
||||
// stable before checking for new value.
|
||||
expect(componentFixture.isStable()).toBe(false);
|
||||
componentFixture.whenStable().then((waited) => {
|
||||
expect(waited).toBe(true);
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should stabilize after async task in change detection (autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncChangeComp);
|
||||
|
||||
componentFixture.autoDetectChanges();
|
||||
componentFixture.whenStable().then((_) => {
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
|
||||
componentFixture.whenStable().then(
|
||||
(_) => { expect(componentFixture.nativeElement).toHaveText('11'); });
|
||||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should stabilize after async task in change detection(no autoDetectChanges)',
|
||||
async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(AsyncChangeComp);
|
||||
componentFixture.detectChanges();
|
||||
componentFixture.whenStable().then((_) => {
|
||||
// Run detectChanges again so that stabilized value is reflected in the
|
||||
// DOM.
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('1');
|
||||
|
||||
const element = componentFixture.debugElement.children[0];
|
||||
dispatchEvent(element.nativeElement, 'click');
|
||||
componentFixture.detectChanges();
|
||||
|
||||
componentFixture.whenStable().then((_) => {
|
||||
// Run detectChanges again so that stabilized value is reflected in
|
||||
// the DOM.
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('11');
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
describe('No NgZone', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -301,7 +289,7 @@ class NestedAsyncTimeoutComp {
|
|||
{providers: [{provide: ComponentFixtureNoNgZone, useValue: true}]});
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('calling autoDetectChanges raises an error', () => {
|
||||
it('calling autoDetectChanges raises an error', () => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(SimpleComp);
|
||||
expect(() => {
|
||||
|
@ -309,28 +297,27 @@ class NestedAsyncTimeoutComp {
|
|||
}).toThrowError(/Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set/);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should instantiate a component with valid DOM', async(() => {
|
||||
it('should instantiate a component with valid DOM', async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(SimpleComp);
|
||||
const componentFixture = TestBed.createComponent(SimpleComp);
|
||||
|
||||
expect(componentFixture.ngZone).toBeNull();
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('Original Simple');
|
||||
}));
|
||||
expect(componentFixture.ngZone).toBeNull();
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('Original Simple');
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should allow changing members of the component', async(() => {
|
||||
it('should allow changing members of the component', async(() => {
|
||||
|
||||
const componentFixture = TestBed.createComponent(MyIfComp);
|
||||
const componentFixture = TestBed.createComponent(MyIfComp);
|
||||
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('MyIf()');
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('MyIf()');
|
||||
|
||||
componentFixture.componentInstance.showMore = true;
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('MyIf(More)');
|
||||
componentFixture.componentInstance.showMore = true;
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.nativeElement).toHaveText('MyIf(More)');
|
||||
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -192,13 +192,13 @@ class TestApp {
|
|||
});
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should list all child nodes', () => {
|
||||
it('should list all child nodes', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.childNodes.length).toEqual(3);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list all component child elements', () => {
|
||||
it('should list all component child elements', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
const childEls = fixture.debugElement.children;
|
||||
|
@ -225,7 +225,7 @@ class TestApp {
|
|||
expect(getDOM().hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list conditional component child elements', () => {
|
||||
it('should list conditional component child elements', () => {
|
||||
fixture = TestBed.createComponent(ConditionalParentComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
|
@ -246,7 +246,7 @@ class TestApp {
|
|||
expect(conditionalContentComp.children.length).toEqual(1);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list child elements within viewports', () => {
|
||||
it('should list child elements within viewports', () => {
|
||||
fixture = TestBed.createComponent(UsingFor);
|
||||
fixture.detectChanges();
|
||||
|
||||
|
@ -259,34 +259,37 @@ class TestApp {
|
|||
expect(list.children.length).toEqual(3);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list element attributes', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should list element attributes', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
|
||||
expect(bankElem.attributes['bank']).toEqual('RBC');
|
||||
expect(bankElem.attributes['account']).toEqual('4747');
|
||||
});
|
||||
expect(bankElem.attributes['bank']).toEqual('RBC');
|
||||
expect(bankElem.attributes['account']).toEqual('4747');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list element classes', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should list element classes', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
|
||||
expect(bankElem.classes['closed']).toBe(true);
|
||||
expect(bankElem.classes['open']).toBe(false);
|
||||
});
|
||||
expect(bankElem.classes['closed']).toBe(true);
|
||||
expect(bankElem.classes['open']).toBe(false);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list element styles', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should list element styles', () => {
|
||||
fixture = TestBed.createComponent(TestApp);
|
||||
fixture.detectChanges();
|
||||
const bankElem = fixture.debugElement.children[0];
|
||||
|
||||
expect(bankElem.styles['width']).toEqual('200px');
|
||||
expect(bankElem.styles['color']).toEqual('red');
|
||||
});
|
||||
expect(bankElem.styles['width']).toEqual('200px');
|
||||
expect(bankElem.styles['color']).toEqual('red');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should query child elements by css', () => {
|
||||
it('should query child elements by css', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
|
@ -296,7 +299,7 @@ class TestApp {
|
|||
expect(getDOM().hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should query child elements by directive', () => {
|
||||
it('should query child elements by directive', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
|
@ -309,39 +312,42 @@ class TestApp {
|
|||
expect(getDOM().hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list providerTokens', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should list providerTokens', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.providerTokens).toContain(Logger);
|
||||
});
|
||||
expect(fixture.debugElement.providerTokens).toContain(Logger);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list locals', () => {
|
||||
it('should list locals', () => {
|
||||
fixture = TestBed.createComponent(LocalsComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].references !['alice']).toBeAnInstanceOf(MyDir);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should allow injecting from the element injector', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should allow injecting from the element injector', () => {
|
||||
fixture = TestBed.createComponent(ParentComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect((<Logger>(fixture.debugElement.children[0].injector.get(Logger))).logs).toEqual([
|
||||
'parent', 'nestedparent', 'child', 'nestedchild'
|
||||
]);
|
||||
});
|
||||
expect((<Logger>(fixture.debugElement.children[0].injector.get(Logger))).logs).toEqual([
|
||||
'parent', 'nestedparent', 'child', 'nestedchild'
|
||||
]);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should list event listeners', () => {
|
||||
fixture = TestBed.createComponent(EventsComp);
|
||||
fixture.detectChanges();
|
||||
fixmeIvy('FW-719: DebugElement needs proper implementation of its methods.') &&
|
||||
it('should list event listeners', () => {
|
||||
fixture = TestBed.createComponent(EventsComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].listeners.length).toEqual(1);
|
||||
expect(fixture.debugElement.children[1].listeners.length).toEqual(1);
|
||||
expect(fixture.debugElement.children[0].listeners.length).toEqual(1);
|
||||
expect(fixture.debugElement.children[1].listeners.length).toEqual(1);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should trigger event handlers', () => {
|
||||
it('should trigger event handlers', () => {
|
||||
fixture = TestBed.createComponent(EventsComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
|
|
|
@ -19,14 +19,14 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
|
|||
|
||||
{
|
||||
describe('fake async', () => {
|
||||
fixmeIvy('unknown') && it('should run synchronous code', () => {
|
||||
it('should run synchronous code', () => {
|
||||
let ran = false;
|
||||
fakeAsync(() => { ran = true; })();
|
||||
|
||||
expect(ran).toEqual(true);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should pass arguments to the wrapped function', () => {
|
||||
it('should pass arguments to the wrapped function', () => {
|
||||
fakeAsync((foo: any /** TODO #9100 */, bar: any /** TODO #9100 */) => {
|
||||
expect(foo).toEqual('foo');
|
||||
expect(bar).toEqual('bar');
|
||||
|
@ -38,13 +38,13 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
|
|||
expect(parser).toBeAnInstanceOf(Parser);
|
||||
})));
|
||||
|
||||
fixmeIvy('unknown') && it('should throw on nested calls', () => {
|
||||
it('should throw on nested calls', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => { fakeAsync((): any /** TODO #9100 */ => null)(); })();
|
||||
}).toThrowError('fakeAsync() calls can not be nested');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should flush microtasks before returning', () => {
|
||||
it('should flush microtasks before returning', () => {
|
||||
let thenRan = false;
|
||||
|
||||
fakeAsync(() => { resolvedPromise.then(_ => { thenRan = true; }); })();
|
||||
|
@ -53,280 +53,275 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
|
|||
});
|
||||
|
||||
|
||||
fixmeIvy('unknown') && it('should propagate the return value',
|
||||
() => { expect(fakeAsync(() => 'foo')()).toEqual('foo'); });
|
||||
it('should propagate the return value',
|
||||
() => { expect(fakeAsync(() => 'foo')()).toEqual('foo'); });
|
||||
|
||||
describe('Promise', () => {
|
||||
fixmeIvy('unknown') && it('should run asynchronous code', fakeAsync(() => {
|
||||
let thenRan = false;
|
||||
resolvedPromise.then((_) => { thenRan = true; });
|
||||
it('should run asynchronous code', fakeAsync(() => {
|
||||
let thenRan = false;
|
||||
resolvedPromise.then((_) => { thenRan = true; });
|
||||
|
||||
expect(thenRan).toEqual(false);
|
||||
expect(thenRan).toEqual(false);
|
||||
|
||||
flushMicrotasks();
|
||||
expect(thenRan).toEqual(true);
|
||||
}));
|
||||
flushMicrotasks();
|
||||
expect(thenRan).toEqual(true);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should run chained thens', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
it('should run chained thens', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
|
||||
resolvedPromise.then((_) => log.add(1)).then((_) => log.add(2));
|
||||
resolvedPromise.then((_) => log.add(1)).then((_) => log.add(2));
|
||||
|
||||
expect(log.result()).toEqual('');
|
||||
expect(log.result()).toEqual('');
|
||||
|
||||
flushMicrotasks();
|
||||
expect(log.result()).toEqual('1; 2');
|
||||
}));
|
||||
flushMicrotasks();
|
||||
expect(log.result()).toEqual('1; 2');
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should run Promise created in Promise', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
it('should run Promise created in Promise', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
|
||||
resolvedPromise.then((_) => {
|
||||
log.add(1);
|
||||
resolvedPromise.then((_) => log.add(2));
|
||||
});
|
||||
resolvedPromise.then((_) => {
|
||||
log.add(1);
|
||||
resolvedPromise.then((_) => log.add(2));
|
||||
});
|
||||
|
||||
expect(log.result()).toEqual('');
|
||||
expect(log.result()).toEqual('');
|
||||
|
||||
flushMicrotasks();
|
||||
expect(log.result()).toEqual('1; 2');
|
||||
}));
|
||||
flushMicrotasks();
|
||||
expect(log.result()).toEqual('1; 2');
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should complain if the test throws an exception during async calls', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => {
|
||||
resolvedPromise.then((_) => { throw new Error('async'); });
|
||||
flushMicrotasks();
|
||||
})();
|
||||
}).toThrowError(/Uncaught \(in promise\): Error: async/);
|
||||
});
|
||||
it('should complain if the test throws an exception during async calls', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => {
|
||||
resolvedPromise.then((_) => { throw new Error('async'); });
|
||||
flushMicrotasks();
|
||||
})();
|
||||
}).toThrowError(/Uncaught \(in promise\): Error: async/);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should complain if a test throws an exception', () => {
|
||||
it('should complain if a test throws an exception', () => {
|
||||
expect(() => { fakeAsync(() => { throw new Error('sync'); })(); }).toThrowError('sync');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('timers', () => {
|
||||
fixmeIvy('unknown') &&
|
||||
it('should run queued zero duration timer on zero tick', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 0);
|
||||
it('should run queued zero duration timer on zero tick', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 0);
|
||||
|
||||
expect(ran).toEqual(false);
|
||||
expect(ran).toEqual(false);
|
||||
|
||||
tick();
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
tick();
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should run queued timer after sufficient clock ticks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
it('should run queued timer after sufficient clock ticks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
|
||||
tick(6);
|
||||
expect(ran).toEqual(false);
|
||||
tick(6);
|
||||
expect(ran).toEqual(false);
|
||||
|
||||
tick(6);
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
tick(6);
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should run queued timer only once', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
setTimeout(() => { cycles++; }, 10);
|
||||
it('should run queued timer only once', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
setTimeout(() => { cycles++; }, 10);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
}));
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should not run cancelled timer', fakeAsync(() => {
|
||||
let ran = false;
|
||||
const id = setTimeout(() => { ran = true; }, 10);
|
||||
clearTimeout(id);
|
||||
it('should not run cancelled timer', fakeAsync(() => {
|
||||
let ran = false;
|
||||
const id = setTimeout(() => { ran = true; }, 10);
|
||||
clearTimeout(id);
|
||||
|
||||
tick(10);
|
||||
expect(ran).toEqual(false);
|
||||
}));
|
||||
tick(10);
|
||||
expect(ran).toEqual(false);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should throw an error on dangling timers', () => {
|
||||
it('should throw an error on dangling timers', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => { setTimeout(() => {}, 10); })();
|
||||
}).toThrowError('1 timer(s) still in the queue.');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should throw an error on dangling periodic timers', () => {
|
||||
it('should throw an error on dangling periodic timers', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => { setInterval(() => {}, 10); })();
|
||||
}).toThrowError('1 periodic timer(s) still in the queue.');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should run periodic timers', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
const id = setInterval(() => { cycles++; }, 10);
|
||||
it('should run periodic timers', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
const id = setInterval(() => { cycles++; }, 10);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(2);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(2);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(3);
|
||||
clearInterval(id);
|
||||
}));
|
||||
tick(10);
|
||||
expect(cycles).toEqual(3);
|
||||
clearInterval(id);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should not run cancelled periodic timer', fakeAsync(() => {
|
||||
let ran = false;
|
||||
const id = setInterval(() => { ran = true; }, 10);
|
||||
clearInterval(id);
|
||||
it('should not run cancelled periodic timer', fakeAsync(() => {
|
||||
let ran = false;
|
||||
const id = setInterval(() => { ran = true; }, 10);
|
||||
clearInterval(id);
|
||||
|
||||
tick(10);
|
||||
expect(ran).toEqual(false);
|
||||
}));
|
||||
tick(10);
|
||||
expect(ran).toEqual(false);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should be able to cancel periodic timers from a callback', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
let id: any /** TODO #9100 */;
|
||||
it('should be able to cancel periodic timers from a callback', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
let id: any /** TODO #9100 */;
|
||||
|
||||
id = setInterval(() => {
|
||||
cycles++;
|
||||
clearInterval(id);
|
||||
}, 10);
|
||||
id = setInterval(() => {
|
||||
cycles++;
|
||||
clearInterval(id);
|
||||
}, 10);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
}));
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should clear periodic timers', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
const id = setInterval(() => { cycles++; }, 10);
|
||||
it('should clear periodic timers', fakeAsync(() => {
|
||||
let cycles = 0;
|
||||
const id = setInterval(() => { cycles++; }, 10);
|
||||
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
tick(10);
|
||||
expect(cycles).toEqual(1);
|
||||
|
||||
discardPeriodicTasks();
|
||||
discardPeriodicTasks();
|
||||
|
||||
// Tick once to clear out the timer which already started.
|
||||
tick(10);
|
||||
expect(cycles).toEqual(2);
|
||||
// Tick once to clear out the timer which already started.
|
||||
tick(10);
|
||||
expect(cycles).toEqual(2);
|
||||
|
||||
tick(10);
|
||||
// Nothing should change
|
||||
expect(cycles).toEqual(2);
|
||||
}));
|
||||
tick(10);
|
||||
// Nothing should change
|
||||
expect(cycles).toEqual(2);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should process microtasks before timers', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
it('should process microtasks before timers', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
|
||||
resolvedPromise.then((_) => log.add('microtask'));
|
||||
resolvedPromise.then((_) => log.add('microtask'));
|
||||
|
||||
setTimeout(() => log.add('timer'), 9);
|
||||
setTimeout(() => log.add('timer'), 9);
|
||||
|
||||
const id = setInterval(() => log.add('periodic timer'), 10);
|
||||
const id = setInterval(() => log.add('periodic timer'), 10);
|
||||
|
||||
expect(log.result()).toEqual('');
|
||||
expect(log.result()).toEqual('');
|
||||
|
||||
tick(10);
|
||||
expect(log.result()).toEqual('microtask; timer; periodic timer');
|
||||
clearInterval(id);
|
||||
}));
|
||||
tick(10);
|
||||
expect(log.result()).toEqual('microtask; timer; periodic timer');
|
||||
clearInterval(id);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should process micro-tasks created in timers before next timers', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
it('should process micro-tasks created in timers before next timers', fakeAsync(() => {
|
||||
const log = new Log();
|
||||
|
||||
resolvedPromise.then((_) => log.add('microtask'));
|
||||
resolvedPromise.then((_) => log.add('microtask'));
|
||||
|
||||
setTimeout(() => {
|
||||
log.add('timer');
|
||||
resolvedPromise.then((_) => log.add('t microtask'));
|
||||
}, 9);
|
||||
setTimeout(() => {
|
||||
log.add('timer');
|
||||
resolvedPromise.then((_) => log.add('t microtask'));
|
||||
}, 9);
|
||||
|
||||
const id = setInterval(() => {
|
||||
log.add('periodic timer');
|
||||
resolvedPromise.then((_) => log.add('pt microtask'));
|
||||
}, 10);
|
||||
const id = setInterval(() => {
|
||||
log.add('periodic timer');
|
||||
resolvedPromise.then((_) => log.add('pt microtask'));
|
||||
}, 10);
|
||||
|
||||
tick(10);
|
||||
expect(log.result())
|
||||
.toEqual('microtask; timer; t microtask; periodic timer; pt microtask');
|
||||
tick(10);
|
||||
expect(log.result())
|
||||
.toEqual('microtask; timer; t microtask; periodic timer; pt microtask');
|
||||
|
||||
tick(10);
|
||||
expect(log.result())
|
||||
.toEqual(
|
||||
'microtask; timer; t microtask; periodic timer; pt microtask; periodic timer; pt microtask');
|
||||
clearInterval(id);
|
||||
}));
|
||||
tick(10);
|
||||
expect(log.result())
|
||||
.toEqual(
|
||||
'microtask; timer; t microtask; periodic timer; pt microtask; periodic timer; pt microtask');
|
||||
clearInterval(id);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should flush tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
it('should flush tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
|
||||
flush();
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
flush();
|
||||
expect(ran).toEqual(true);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should flush multiple tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
let ran2 = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
setTimeout(() => { ran2 = true; }, 30);
|
||||
it('should flush multiple tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
let ran2 = false;
|
||||
setTimeout(() => { ran = true; }, 10);
|
||||
setTimeout(() => { ran2 = true; }, 30);
|
||||
|
||||
let elapsed = flush();
|
||||
let elapsed = flush();
|
||||
|
||||
expect(ran).toEqual(true);
|
||||
expect(ran2).toEqual(true);
|
||||
expect(elapsed).toEqual(30);
|
||||
}));
|
||||
expect(ran).toEqual(true);
|
||||
expect(ran2).toEqual(true);
|
||||
expect(elapsed).toEqual(30);
|
||||
}));
|
||||
|
||||
fixmeIvy('unknown') && it('should move periodic tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
let count = 0;
|
||||
setInterval(() => { count++; }, 10);
|
||||
setTimeout(() => { ran = true; }, 35);
|
||||
it('should move periodic tasks', fakeAsync(() => {
|
||||
let ran = false;
|
||||
let count = 0;
|
||||
setInterval(() => { count++; }, 10);
|
||||
setTimeout(() => { ran = true; }, 35);
|
||||
|
||||
let elapsed = flush();
|
||||
let elapsed = flush();
|
||||
|
||||
expect(count).toEqual(3);
|
||||
expect(ran).toEqual(true);
|
||||
expect(elapsed).toEqual(35);
|
||||
expect(count).toEqual(3);
|
||||
expect(ran).toEqual(true);
|
||||
expect(elapsed).toEqual(35);
|
||||
|
||||
discardPeriodicTasks();
|
||||
}));
|
||||
discardPeriodicTasks();
|
||||
}));
|
||||
});
|
||||
|
||||
describe('outside of the fakeAsync zone', () => {
|
||||
fixmeIvy('unknown') && it('calling flushMicrotasks should throw', () => {
|
||||
it('calling flushMicrotasks should throw', () => {
|
||||
expect(() => {
|
||||
flushMicrotasks();
|
||||
}).toThrowError('The code should be running in the fakeAsync zone to call this function');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('calling tick should throw', () => {
|
||||
it('calling tick should throw', () => {
|
||||
expect(() => {
|
||||
tick();
|
||||
}).toThrowError('The code should be running in the fakeAsync zone to call this function');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('calling flush should throw', () => {
|
||||
it('calling flush should throw', () => {
|
||||
expect(() => {
|
||||
flush();
|
||||
}).toThrowError('The code should be running in the fakeAsync zone to call this function');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('calling discardPeriodicTasks should throw', () => {
|
||||
it('calling discardPeriodicTasks should throw', () => {
|
||||
expect(() => {
|
||||
discardPeriodicTasks();
|
||||
}).toThrowError('The code should be running in the fakeAsync zone to call this function');
|
||||
|
@ -338,10 +333,10 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
|
|||
let zoneInTest1: Zone;
|
||||
beforeEach(fakeAsync(() => { zoneInBeforeEach = Zone.current; }));
|
||||
|
||||
fixmeIvy('unknown') && it('should use the same zone as in beforeEach', fakeAsync(() => {
|
||||
zoneInTest1 = Zone.current;
|
||||
expect(zoneInTest1).toBe(zoneInBeforeEach);
|
||||
}));
|
||||
it('should use the same zone as in beforeEach', fakeAsync(() => {
|
||||
zoneInTest1 = Zone.current;
|
||||
expect(zoneInTest1).toBe(zoneInBeforeEach);
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -350,21 +345,19 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
|
|||
|
||||
afterEach(() => { ProxyZoneSpec.assertPresent(); });
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should allow fakeAsync zone to retroactively set a zoneSpec outside of fakeAsync',
|
||||
() => {
|
||||
ProxyZoneSpec.assertPresent();
|
||||
let state: string = 'not run';
|
||||
const testZone = Zone.current.fork({name: 'test-zone'});
|
||||
(fakeAsync(() => {
|
||||
testZone.run(() => {
|
||||
Promise.resolve('works').then((v) => state = v);
|
||||
expect(state).toEqual('not run');
|
||||
flushMicrotasks();
|
||||
expect(state).toEqual('works');
|
||||
});
|
||||
}))();
|
||||
expect(state).toEqual('works');
|
||||
});
|
||||
it('should allow fakeAsync zone to retroactively set a zoneSpec outside of fakeAsync', () => {
|
||||
ProxyZoneSpec.assertPresent();
|
||||
let state: string = 'not run';
|
||||
const testZone = Zone.current.fork({name: 'test-zone'});
|
||||
(fakeAsync(() => {
|
||||
testZone.run(() => {
|
||||
Promise.resolve('works').then((v) => state = v);
|
||||
expect(state).toEqual('not run');
|
||||
flushMicrotasks();
|
||||
expect(state).toEqual('works');
|
||||
});
|
||||
}))();
|
||||
expect(state).toEqual('works');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
|||
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
|
||||
import {dispatchEvent, el} from '@angular/platform-browser/testing/src/browser_util';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
import {fixmeIvy, modifiedInIvy} from '@angular/private/testing';
|
||||
|
||||
import {stringify} from '../../src/util';
|
||||
|
||||
|
@ -209,20 +209,21 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
.toEqual('Some other <div>HTML</div>');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should consume binding to className using class alias', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template = '<div class="initial" [class]="ctxProp"></div>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
modifiedInIvy('Binding to the class property directly works differently') &&
|
||||
it('should consume binding to className using class alias', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template = '<div class="initial" [class]="ctxProp"></div>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
const nativeEl = fixture.debugElement.children[0].nativeElement;
|
||||
fixture.componentInstance.ctxProp = 'foo bar';
|
||||
fixture.detectChanges();
|
||||
const nativeEl = fixture.debugElement.children[0].nativeElement;
|
||||
fixture.componentInstance.ctxProp = 'foo bar';
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(nativeEl).toHaveCssClass('foo');
|
||||
expect(nativeEl).toHaveCssClass('bar');
|
||||
expect(nativeEl).not.toHaveCssClass('initial');
|
||||
});
|
||||
expect(nativeEl).toHaveCssClass('foo');
|
||||
expect(nativeEl).toHaveCssClass('bar');
|
||||
expect(nativeEl).not.toHaveCssClass('initial');
|
||||
});
|
||||
|
||||
it('should consume binding to htmlFor using for alias', () => {
|
||||
const template = '<label [for]="ctxProp"></label>';
|
||||
|
@ -373,7 +374,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
const fixture = TestBed.createComponent(MyComp);
|
||||
});
|
||||
|
||||
fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') &&
|
||||
modifiedInIvy('Comment node order changed') &&
|
||||
it('should support template directives via `<ng-template>` elements.', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
|
||||
const template =
|
||||
|
@ -401,7 +402,8 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
expect(fixture.nativeElement).toHaveText('baz');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
fixmeIvy(
|
||||
'FW-665: Discovery util fails with "Unable to find the given context data for the given target"') &&
|
||||
it('should not detach views in ViewContainers when the parent view is destroyed.', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
|
||||
const template =
|
||||
|
@ -565,7 +567,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
});
|
||||
|
||||
describe('variables', () => {
|
||||
fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') &&
|
||||
modifiedInIvy('Comment node order changed') &&
|
||||
it('should allow to use variables in a for loop', () => {
|
||||
const template =
|
||||
'<ng-template ngFor [ngForOf]="[1]" let-i><child-cmp-no-template #cmp></child-cmp-no-template>{{i}}-{{cmp.ctxProp}}</ng-template>';
|
||||
|
@ -583,7 +585,8 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
|
||||
describe('OnPush components', () => {
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
fixmeIvy(
|
||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template') &&
|
||||
it('should use ChangeDetectorRef to manually request a check', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]});
|
||||
const template = '<push-cmp-with-ref #cmp></push-cmp-with-ref>';
|
||||
|
@ -604,23 +607,25 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should be checked when its bindings got updated', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
||||
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixmeIvy(
|
||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template') &&
|
||||
it('should be checked when its bindings got updated', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
||||
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
const cmp = fixture.debugElement.children[0].references !['cmp'];
|
||||
const cmp = fixture.debugElement.children[0].references !['cmp'];
|
||||
|
||||
fixture.componentInstance.ctxProp = 'one';
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
fixture.componentInstance.ctxProp = 'one';
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
|
||||
fixture.componentInstance.ctxProp = 'two';
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
});
|
||||
fixture.componentInstance.ctxProp = 'two';
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
});
|
||||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
fixmeIvy('unknown') &&
|
||||
|
@ -643,43 +648,44 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
}));
|
||||
}
|
||||
|
||||
fixmeIvy('unknown') && it('should be checked when an event is fired', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
||||
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2') &&
|
||||
it('should be checked when an event is fired', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
||||
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
const cmpEl = fixture.debugElement.children[0];
|
||||
const cmp = cmpEl.componentInstance;
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
const cmpEl = fixture.debugElement.children[0];
|
||||
const cmp = cmpEl.componentInstance;
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
|
||||
// regular element
|
||||
cmpEl.children[0].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
// regular element
|
||||
cmpEl.children[0].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(2);
|
||||
|
||||
// element inside of an *ngIf
|
||||
cmpEl.children[1].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(3);
|
||||
// element inside of an *ngIf
|
||||
cmpEl.children[1].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(3);
|
||||
|
||||
// element inside a nested component
|
||||
cmpEl.children[2].children[0].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(4);
|
||||
// element inside a nested component
|
||||
cmpEl.children[2].children[0].triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(4);
|
||||
|
||||
// host element
|
||||
cmpEl.triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(5);
|
||||
});
|
||||
// host element
|
||||
cmpEl.triggerEventHandler('click', <Event>{});
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(5);
|
||||
});
|
||||
|
||||
it('should not affect updating properties on the component', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]});
|
||||
|
@ -767,7 +773,8 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
fixmeIvy(
|
||||
'FW-763: LView tree not properly constructed / destroyed for dynamically inserted components') &&
|
||||
it('should support events via EventEmitter on regular elements', async(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]});
|
||||
|
@ -1490,7 +1497,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
});
|
||||
|
||||
describe('error handling', () => {
|
||||
fixmeIvy('unknown') &&
|
||||
fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error') &&
|
||||
it('should report a meaningful error when a directive is missing annotation', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, SomeDirectiveMissingAnnotation]});
|
||||
|
@ -1500,7 +1507,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
`Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error') &&
|
||||
it('should report a meaningful error when a component is missing view annotation', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, ComponentWithoutView]});
|
||||
try {
|
||||
|
@ -1722,15 +1729,17 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
.toContain('"ng\-reflect\-ng\-if"\: "true"');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should indicate when toString() throws', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
|
||||
const template = '<div my-dir [elprop]="toStringThrow"></div>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
// also affected by FW-587: Inputs with aliases in component decorators don't work
|
||||
fixmeIvy('FW-664: ng-reflect-* is not supported') &&
|
||||
it('should indicate when toString() throws', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
|
||||
const template = '<div my-dir [elprop]="toStringThrow"></div>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]');
|
||||
});
|
||||
fixture.detectChanges();
|
||||
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]');
|
||||
});
|
||||
});
|
||||
|
||||
describe('property decorators', () => {
|
||||
|
|
|
@ -116,7 +116,7 @@ describe('TestBed', () => {
|
|||
expect(nameInjected).toEqual('World!');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should give access to the node injector for root node', () => {
|
||||
it('should give access to the node injector for root node', () => {
|
||||
const hello = TestBed.createComponent(HelloWorld);
|
||||
hello.detectChanges();
|
||||
const injector = hello.debugElement.injector;
|
||||
|
|
|
@ -117,7 +117,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
describe('deps', () => {
|
||||
class Dep {}
|
||||
|
||||
fixmeIvy('unknown') && it('should inject deps from the same element', () => {
|
||||
it('should inject deps from the same element', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, Dep, []),
|
||||
|
@ -127,7 +127,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject deps from a parent element', () => {
|
||||
it('should inject deps from a parent element', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 3, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, Dep, []),
|
||||
|
@ -167,7 +167,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
' NullInjectorError: No provider for Dep!');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject from a parent element in a parent view', () => {
|
||||
it('should inject from a parent element in a parent view', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(
|
||||
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||
|
@ -192,7 +192,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
' NullInjectorError: No provider for nonExistingDep!');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should use null for optional missing dependencies', () => {
|
||||
it('should use null for optional missing dependencies', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(
|
||||
|
@ -202,7 +202,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep).toBe(null);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should skip the current element when using SkipSelf', () => {
|
||||
it('should skip the current element when using SkipSelf', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 4, 'span'),
|
||||
providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someParentValue', []),
|
||||
|
@ -214,19 +214,18 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep).toBe('someParentValue');
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should ask the root injector',
|
||||
withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['rootDep'])
|
||||
]));
|
||||
it('should ask the root injector',
|
||||
withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['rootDep'])
|
||||
]));
|
||||
|
||||
expect(instance.dep).toBe('rootValue');
|
||||
}));
|
||||
expect(instance.dep).toBe('rootValue');
|
||||
}));
|
||||
|
||||
describe('builtin tokens', () => {
|
||||
fixmeIvy('unknown') && it('should inject ViewContainerRef', () => {
|
||||
it('should inject ViewContainerRef', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
anchorDef(NodeFlags.EmbeddedViews, null, null, 1),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ViewContainerRef]),
|
||||
|
@ -235,7 +234,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject TemplateRef', () => {
|
||||
it('should inject TemplateRef', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
anchorDef(NodeFlags.None, null, null, 1, null, compViewDefFactory([anchorDef(
|
||||
NodeFlags.None, null, null, 0)])),
|
||||
|
@ -245,7 +244,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject ElementRef', () => {
|
||||
it('should inject ElementRef', () => {
|
||||
const {view} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ElementRef]),
|
||||
|
@ -254,7 +253,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject Injector', () => {
|
||||
it('should inject Injector', () => {
|
||||
const {view} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, [Injector]),
|
||||
|
@ -263,32 +262,30 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep.get(SomeService)).toBe(instance);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should inject ChangeDetectorRef for non component providers', () => {
|
||||
const {view} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef])
|
||||
]));
|
||||
it('should inject ChangeDetectorRef for non component providers', () => {
|
||||
const {view} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef])
|
||||
]));
|
||||
|
||||
expect(instance.dep._view).toBe(view);
|
||||
});
|
||||
expect(instance.dep._view).toBe(view);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') &&
|
||||
it('should inject ChangeDetectorRef for component providers', () => {
|
||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(
|
||||
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||
() => compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||
])),
|
||||
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [ChangeDetectorRef]),
|
||||
]));
|
||||
it('should inject ChangeDetectorRef for component providers', () => {
|
||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||
elementDef(
|
||||
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||
() => compViewDef([
|
||||
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||
])),
|
||||
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [ChangeDetectorRef]),
|
||||
]));
|
||||
|
||||
const compView = asElementData(view, 0).componentView;
|
||||
expect(instance.dep._view).toBe(compView);
|
||||
});
|
||||
const compView = asElementData(view, 0).componentView;
|
||||
expect(instance.dep._view).toBe(compView);
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject RendererV1', () => {
|
||||
it('should inject RendererV1', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(
|
||||
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,
|
||||
|
@ -299,7 +296,7 @@ import {fixmeIvy} from '@angular/private/testing';
|
|||
expect(instance.dep.createElement).toBeTruthy();
|
||||
});
|
||||
|
||||
fixmeIvy('unknown') && it('should inject Renderer2', () => {
|
||||
it('should inject Renderer2', () => {
|
||||
createAndGetRootNodes(compViewDef([
|
||||
elementDef(
|
||||
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,
|
||||
|
|
Loading…
Reference in New Issue