test(ivy): update root causes for @angular/core TestBed failures (#27419)
PR Close #27419
This commit is contained in:
parent
f5f323dae0
commit
a1470c94a6
|
@ -74,7 +74,7 @@ class SomeComponent {
|
||||||
return MyModule;
|
return MyModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') &&
|
||||||
it('should bootstrap a component from a child module',
|
it('should bootstrap a component from a child module',
|
||||||
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
|
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -103,7 +103,7 @@ class SomeComponent {
|
||||||
expect(component.injector.get('hello')).toEqual('component');
|
expect(component.injector.get('hello')).toEqual('component');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') &&
|
||||||
it('should bootstrap a component with a custom selector',
|
it('should bootstrap a component with a custom selector',
|
||||||
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
|
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -176,12 +176,13 @@ class SomeComponent {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown') && it('should be called when a component is bootstrapped',
|
fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') &&
|
||||||
inject([ApplicationRef], (ref: ApplicationRef) => {
|
it('should be called when a component is bootstrapped',
|
||||||
createRootEl();
|
inject([ApplicationRef], (ref: ApplicationRef) => {
|
||||||
const compRef = ref.bootstrap(SomeComponent);
|
createRootEl();
|
||||||
expect(capturedCompRefs).toEqual([compRef]);
|
const compRef = ref.bootstrap(SomeComponent);
|
||||||
}));
|
expect(capturedCompRefs).toEqual([compRef]);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('bootstrap', () => {
|
describe('bootstrap', () => {
|
||||||
|
|
|
@ -10,46 +10,42 @@ import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit,
|
||||||
import {Component, Directive} from '@angular/core/src/metadata';
|
import {Component, Directive} from '@angular/core/src/metadata';
|
||||||
import {TestBed, inject} from '@angular/core/testing';
|
import {TestBed, inject} from '@angular/core/testing';
|
||||||
import {Log} from '@angular/core/testing/src/testing_internal';
|
import {Log} from '@angular/core/testing/src/testing_internal';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
|
||||||
|
|
||||||
{
|
describe('directive lifecycle integration spec', () => {
|
||||||
describe('directive lifecycle integration spec', () => {
|
let log: Log;
|
||||||
let log: Log;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed
|
TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
LifecycleCmp,
|
LifecycleCmp,
|
||||||
LifecycleDir,
|
LifecycleDir,
|
||||||
MyComp5,
|
MyComp5,
|
||||||
],
|
],
|
||||||
providers: [Log]
|
providers: [Log]
|
||||||
})
|
})
|
||||||
.overrideComponent(MyComp5, {set: {template: '<div [field]="123" lifecycle></div>'}});
|
.overrideComponent(MyComp5, {set: {template: '<div [field]="123" lifecycle></div>'}});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(inject([Log], (_log: any) => { log = _log; }));
|
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
|
||||||
it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked',
|
|
||||||
() => {
|
|
||||||
const fixture = TestBed.createComponent(MyComp5);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(log.result())
|
|
||||||
.toEqual(
|
|
||||||
'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' +
|
|
||||||
'ngAfterViewInit; ngAfterViewChecked');
|
|
||||||
|
|
||||||
log.clear();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(log.result())
|
|
||||||
.toEqual('ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
beforeEach(inject([Log], (_log: any) => { log = _log; }));
|
||||||
|
|
||||||
|
it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked',
|
||||||
|
() => {
|
||||||
|
const fixture = TestBed.createComponent(MyComp5);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(log.result())
|
||||||
|
.toEqual(
|
||||||
|
'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' +
|
||||||
|
'ngAfterViewInit; ngAfterViewChecked');
|
||||||
|
|
||||||
|
log.clear();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(log.result())
|
||||||
|
.toEqual('ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
@Directive({selector: '[lifecycle-dir]'})
|
@Directive({selector: '[lifecycle-dir]'})
|
||||||
|
|
|
@ -12,20 +12,18 @@ import {TestBed} from '@angular/core/testing';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
|
|
||||||
{
|
describe('forwardRef integration', function() {
|
||||||
describe('forwardRef integration', function() {
|
beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); });
|
||||||
beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); });
|
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') &&
|
||||||
it('should instantiate components which are declared using forwardRef', () => {
|
it('should instantiate components which are declared using forwardRef', () => {
|
||||||
const a =
|
const a =
|
||||||
TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App);
|
TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App);
|
||||||
a.detectChanges();
|
a.detectChanges();
|
||||||
expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)');
|
expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)');
|
||||||
expect(TestBed.get(ModuleFrame)).toBeDefined();
|
expect(TestBed.get(ModuleFrame)).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule],
|
imports: [CommonModule],
|
||||||
|
|
|
@ -13,13 +13,11 @@ import {TestBed} from '@angular/core/testing';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
|
|
||||||
|
|
||||||
{
|
if (ivyEnabled) {
|
||||||
if (ivyEnabled) {
|
describe('ivy', () => { declareTests(); });
|
||||||
describe('ivy', () => { declareTests(); });
|
} else {
|
||||||
} else {
|
describe('jit', () => { declareTests({useJit: true}); });
|
||||||
describe('jit', () => { declareTests({useJit: true}); });
|
describe('no jit', () => { declareTests({useJit: false}); });
|
||||||
describe('no jit', () => { declareTests({useJit: false}); });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DummyConsole implements Console {
|
class DummyConsole implements Console {
|
||||||
|
|
|
@ -13,13 +13,11 @@ import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {fixmeIvy, polyfillGoogGetMsg} from '@angular/private/testing';
|
import {fixmeIvy, polyfillGoogGetMsg} from '@angular/private/testing';
|
||||||
|
|
||||||
{
|
if (ivyEnabled) {
|
||||||
if (ivyEnabled) {
|
describe('ivy', () => { declareTests(); });
|
||||||
describe('ivy', () => { declareTests(); });
|
} else {
|
||||||
} else {
|
describe('jit', () => { declareTests({useJit: true}); });
|
||||||
describe('jit', () => { declareTests({useJit: true}); });
|
describe('no jit', () => { declareTests({useJit: false}); });
|
||||||
describe('no jit', () => { declareTests({useJit: false}); });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function declareTests(config?: {useJit: boolean}) {
|
function declareTests(config?: {useJit: boolean}) {
|
||||||
|
|
|
@ -142,8 +142,8 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
return new ComponentFixture(comp, null !, false);
|
return new ComponentFixture(comp, null !, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixmeIvy('FW-682: Compiler error handling') && //
|
describe('errors', () => {
|
||||||
describe('errors', () => {
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error when exporting a directive that was neither declared nor imported', () => {
|
it('should error when exporting a directive that was neither declared nor imported', () => {
|
||||||
@NgModule({exports: [SomeDirective]})
|
@NgModule({exports: [SomeDirective]})
|
||||||
class SomeModule {
|
class SomeModule {
|
||||||
|
@ -154,6 +154,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
|
`Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error when exporting a pipe that was neither declared nor imported', () => {
|
it('should error when exporting a pipe that was neither declared nor imported', () => {
|
||||||
@NgModule({exports: [SomePipe]})
|
@NgModule({exports: [SomePipe]})
|
||||||
class SomeModule {
|
class SomeModule {
|
||||||
|
@ -164,6 +165,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
|
`Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error if a directive is declared in more than 1 module', () => {
|
it('should error if a directive is declared in more than 1 module', () => {
|
||||||
@NgModule({declarations: [SomeDirective]})
|
@NgModule({declarations: [SomeDirective]})
|
||||||
class Module1 {
|
class Module1 {
|
||||||
|
@ -182,6 +184,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error if a directive is declared in more than 1 module also if the module declaring it is imported',
|
it('should error if a directive is declared in more than 1 module also if the module declaring it is imported',
|
||||||
() => {
|
() => {
|
||||||
@NgModule({declarations: [SomeDirective], exports: [SomeDirective]})
|
@NgModule({declarations: [SomeDirective], exports: [SomeDirective]})
|
||||||
|
@ -199,6 +202,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error if a pipe is declared in more than 1 module', () => {
|
it('should error if a pipe is declared in more than 1 module', () => {
|
||||||
@NgModule({declarations: [SomePipe]})
|
@NgModule({declarations: [SomePipe]})
|
||||||
class Module1 {
|
class Module1 {
|
||||||
|
@ -217,6 +221,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported',
|
it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported',
|
||||||
() => {
|
() => {
|
||||||
@NgModule({declarations: [SomePipe], exports: [SomePipe]})
|
@NgModule({declarations: [SomePipe], exports: [SomePipe]})
|
||||||
|
@ -234,7 +239,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('schemas', () => {
|
describe('schemas', () => {
|
||||||
fixmeIvy('FW-682: Compiler error handling') &&
|
fixmeIvy('FW-682: Compiler error handling') &&
|
||||||
|
@ -1048,7 +1053,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(created).toBe(false);
|
expect(created).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('ngOnDestroy not running') &&
|
fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') &&
|
||||||
it('should support ngOnDestroy on any provider', () => {
|
it('should support ngOnDestroy on any provider', () => {
|
||||||
let destroyed = false;
|
let destroyed = false;
|
||||||
|
|
||||||
|
@ -1068,7 +1073,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(destroyed).toBe(true);
|
expect(destroyed).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('ngOnDestroy not running') &&
|
fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') &&
|
||||||
it('should support ngOnDestroy for lazy providers', () => {
|
it('should support ngOnDestroy for lazy providers', () => {
|
||||||
let created = false;
|
let created = false;
|
||||||
let destroyed = false;
|
let destroyed = false;
|
||||||
|
@ -1330,7 +1335,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tree shakable providers', () => {
|
describe('tree shakable providers', () => {
|
||||||
fixmeIvy('providersByKey is not defined') &&
|
fixmeIvy('unknown') &&
|
||||||
it('definition should not persist across NgModuleRef instances', () => {
|
it('definition should not persist across NgModuleRef instances', () => {
|
||||||
@NgModule()
|
@NgModule()
|
||||||
class SomeModule {
|
class SomeModule {
|
||||||
|
|
|
@ -12,19 +12,17 @@ import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser';
|
||||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
import {fixmeIvy, modifiedInIvy} from '@angular/private/testing';
|
||||||
|
|
||||||
{
|
if (ivyEnabled) {
|
||||||
if (ivyEnabled) {
|
describe('ivy', () => { declareTests(); });
|
||||||
describe('ivy', () => { declareTests(); });
|
} else {
|
||||||
} else {
|
describe('jit', () => { declareTests({useJit: true}); });
|
||||||
describe('jit', () => { declareTests({useJit: true}); });
|
describe('no jit', () => { declareTests({useJit: false}); });
|
||||||
describe('no jit', () => { declareTests({useJit: false}); });
|
|
||||||
}
|
|
||||||
|
|
||||||
declareTestsUsingBootstrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declareTestsUsingBootstrap();
|
||||||
|
|
||||||
function declareTests(config?: {useJit: boolean}) {
|
function declareTests(config?: {useJit: boolean}) {
|
||||||
// Place to put reproductions for regressions
|
// Place to put reproductions for regressions
|
||||||
describe('regressions', () => {
|
describe('regressions', () => {
|
||||||
|
@ -162,14 +160,13 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(injector.get(token)).toEqual(tokenValue);
|
expect(injector.get(token)).toEqual(tokenValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') &&
|
it('should support providers with string token with a `.` in it', () => {
|
||||||
it('should support providers with string token with a `.` in it', () => {
|
const token = 'a.b';
|
||||||
const token = 'a.b';
|
const tokenValue = 1;
|
||||||
const tokenValue = 1;
|
const injector = createInjector([{provide: token, useValue: tokenValue}]);
|
||||||
const injector = createInjector([{provide: token, useValue: tokenValue}]);
|
|
||||||
|
|
||||||
expect(injector.get(token)).toEqual(tokenValue);
|
expect(injector.get(token)).toEqual(tokenValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support providers with an anonymous function as token', () => {
|
it('should support providers with an anonymous function as token', () => {
|
||||||
const token = () => true;
|
const token = () => true;
|
||||||
|
@ -191,15 +188,14 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(injector.get(token2)).toEqual(tokenValue2);
|
expect(injector.get(token2)).toEqual(tokenValue2);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') &&
|
it('should support providers that have a `name` property with a number value', () => {
|
||||||
it('should support providers that have a `name` property with a number value', () => {
|
class TestClass {
|
||||||
class TestClass {
|
constructor(public name: number) {}
|
||||||
constructor(public name: number) {}
|
}
|
||||||
}
|
const data = [new TestClass(1), new TestClass(2)];
|
||||||
const data = [new TestClass(1), new TestClass(2)];
|
const injector = createInjector([{provide: 'someToken', useValue: data}]);
|
||||||
const injector = createInjector([{provide: 'someToken', useValue: data}]);
|
expect(injector.get('someToken')).toEqual(data);
|
||||||
expect(injector.get('someToken')).toEqual(data);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => {
|
describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => {
|
||||||
|
|
||||||
|
@ -337,21 +333,22 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(fixture.debugElement.childNodes.length).toBe(0);
|
expect(fixture.debugElement.childNodes.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown') && it('should allow empty embedded templates', () => {
|
modifiedInIvy('Comment node order changed') &&
|
||||||
@Component({template: '<ng-template [ngIf]="true"></ng-template>'})
|
it('should allow empty embedded templates', () => {
|
||||||
class MyComp {
|
@Component({template: '<ng-template [ngIf]="true"></ng-template>'})
|
||||||
}
|
class MyComp {
|
||||||
|
}
|
||||||
|
|
||||||
const fixture =
|
const fixture =
|
||||||
TestBed.configureTestingModule({declarations: [MyComp]}).createComponent(MyComp);
|
TestBed.configureTestingModule({declarations: [MyComp]}).createComponent(MyComp);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
// Note: We always need to create at least a comment in an embedded template,
|
// Note: We always need to create at least a comment in an embedded template,
|
||||||
// so we can append other templates after it.
|
// so we can append other templates after it.
|
||||||
// 1 comment for the anchor,
|
// 1 comment for the anchor,
|
||||||
// 1 comment for the empty embedded template.
|
// 1 comment for the empty embedded template.
|
||||||
expect(fixture.debugElement.childNodes.length).toBe(2);
|
expect(fixture.debugElement.childNodes.length).toBe(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('unknown') &&
|
||||||
|
|
|
@ -1608,216 +1608,206 @@ describe('ViewContainerRef', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fixmeIvy(`Hooks don't run`) &&
|
it('should call all hooks in correct order when creating with createEmbeddedView', () => {
|
||||||
it('should call all hooks in correct order when creating with createEmbeddedView', () => {
|
function SomeComponent_Template_0(rf: RenderFlags, ctx: any) {
|
||||||
function SomeComponent_Template_0(rf: RenderFlags, ctx: any) {
|
if (rf & RenderFlags.Create) {
|
||||||
if (rf & RenderFlags.Create) {
|
element(0, 'hooks');
|
||||||
element(0, 'hooks');
|
}
|
||||||
}
|
if (rf & RenderFlags.Update) {
|
||||||
if (rf & RenderFlags.Update) {
|
elementProperty(0, 'name', bind('C'));
|
||||||
elementProperty(0, 'name', bind('C'));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
<ng-template #foo>
|
<ng-template #foo>
|
||||||
<hooks [name]="'C'"></hooks>
|
<hooks [name]="'C'"></hooks>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<hooks vcref [tplRef]="foo" [name]="'A'"></hooks>
|
<hooks vcref [tplRef]="foo" [name]="'A'"></hooks>
|
||||||
<hooks [name]="'B'"></hooks>
|
<hooks [name]="'B'"></hooks>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class SomeComponent {
|
class SomeComponent {
|
||||||
static ngComponentDef = defineComponent({
|
static ngComponentDef = defineComponent({
|
||||||
type: SomeComponent,
|
type: SomeComponent,
|
||||||
selectors: [['some-comp']],
|
selectors: [['some-comp']],
|
||||||
factory: () => new SomeComponent(),
|
factory: () => new SomeComponent(),
|
||||||
consts: 4,
|
consts: 4,
|
||||||
vars: 3,
|
vars: 3,
|
||||||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
template(
|
template(
|
||||||
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''],
|
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor);
|
||||||
templateRefExtractor);
|
element(2, 'hooks', ['vcref', '']);
|
||||||
element(2, 'hooks', ['vcref', '']);
|
element(3, 'hooks');
|
||||||
element(3, 'hooks');
|
}
|
||||||
}
|
if (rf & RenderFlags.Update) {
|
||||||
if (rf & RenderFlags.Update) {
|
const tplRef = reference(1);
|
||||||
const tplRef = reference(1);
|
elementProperty(2, 'tplRef', bind(tplRef));
|
||||||
elementProperty(2, 'tplRef', bind(tplRef));
|
elementProperty(2, 'name', bind('A'));
|
||||||
elementProperty(2, 'name', bind('A'));
|
elementProperty(3, 'name', bind('B'));
|
||||||
elementProperty(3, 'name', bind('B'));
|
}
|
||||||
}
|
},
|
||||||
},
|
directives: [ComponentWithHooks, DirectiveWithVCRef]
|
||||||
directives: [ComponentWithHooks, DirectiveWithVCRef]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
|
|
||||||
const fixture = new ComponentFixture(SomeComponent);
|
|
||||||
expect(log).toEqual([
|
|
||||||
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
|
|
||||||
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
|
|
||||||
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
|
||||||
'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
directiveInstance !.vcref.createEmbeddedView(
|
|
||||||
directiveInstance !.tplRef, fixture.component);
|
|
||||||
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
|
|
||||||
expect(log).toEqual([]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>C</hooks><hooks>B</hooks>');
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'onChanges-C', 'onInit-C', 'doCheck-C', 'afterContentInit-C',
|
|
||||||
'afterContentChecked-C', 'afterViewInit-C', 'afterViewChecked-C',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
const viewRef = directiveInstance !.vcref.detach(0);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
|
||||||
'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
directiveInstance !.vcref.insert(viewRef !);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
directiveInstance !.vcref.remove(0);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'onDestroy-C', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A',
|
|
||||||
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fixmeIvy(`Hooks don't run`) &&
|
log.length = 0;
|
||||||
it('should call all hooks in correct order when creating with createComponent', () => {
|
|
||||||
@Component({
|
const fixture = new ComponentFixture(SomeComponent);
|
||||||
template: `
|
expect(log).toEqual([
|
||||||
|
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
|
||||||
|
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
|
||||||
|
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
|
||||||
|
'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
directiveInstance !.vcref.createEmbeddedView(directiveInstance !.tplRef, fixture.component);
|
||||||
|
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
|
||||||
|
expect(log).toEqual([]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>C</hooks><hooks>B</hooks>');
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'onChanges-C', 'onInit-C', 'doCheck-C', 'afterContentInit-C',
|
||||||
|
'afterContentChecked-C', 'afterViewInit-C', 'afterViewChecked-C', 'afterContentChecked-A',
|
||||||
|
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
|
||||||
|
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
const viewRef = directiveInstance !.vcref.detach(0);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
directiveInstance !.vcref.insert(viewRef !);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
|
||||||
|
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
directiveInstance !.vcref.remove(0);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'onDestroy-C', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call all hooks in correct order when creating with createComponent', () => {
|
||||||
|
@Component({
|
||||||
|
template: `
|
||||||
<hooks vcref [name]="'A'"></hooks>
|
<hooks vcref [name]="'A'"></hooks>
|
||||||
<hooks [name]="'B'"></hooks>
|
<hooks [name]="'B'"></hooks>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class SomeComponent {
|
class SomeComponent {
|
||||||
static ngComponentDef = defineComponent({
|
static ngComponentDef = defineComponent({
|
||||||
type: SomeComponent,
|
type: SomeComponent,
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
selectors: [['some-comp']],
|
selectors: [['some-comp']],
|
||||||
factory: () => new SomeComponent(),
|
factory: () => new SomeComponent(),
|
||||||
consts: 2,
|
consts: 2,
|
||||||
vars: 2,
|
vars: 2,
|
||||||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
element(0, 'hooks', ['vcref', '']);
|
element(0, 'hooks', ['vcref', '']);
|
||||||
element(1, 'hooks');
|
element(1, 'hooks');
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
elementProperty(0, 'name', bind('A'));
|
elementProperty(0, 'name', bind('A'));
|
||||||
elementProperty(1, 'name', bind('B'));
|
elementProperty(1, 'name', bind('B'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
directives: [ComponentWithHooks, DirectiveWithVCRef]
|
directives: [ComponentWithHooks, DirectiveWithVCRef]
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
|
|
||||||
const fixture = new ComponentFixture(SomeComponent);
|
|
||||||
expect(log).toEqual([
|
|
||||||
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
|
|
||||||
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
|
|
||||||
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
|
||||||
'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
const componentRef = directiveInstance !.vcref.createComponent(
|
|
||||||
directiveInstance !.cfr.resolveComponentFactory(ComponentWithHooks));
|
|
||||||
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
|
|
||||||
expect(log).toEqual([]);
|
|
||||||
|
|
||||||
componentRef.instance.name = 'D';
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>D</hooks><hooks>B</hooks>');
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'onChanges-D', 'onInit-D', 'doCheck-D', 'afterContentInit-D',
|
|
||||||
'afterContentChecked-D', 'afterViewInit-D', 'afterViewChecked-D',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
const viewRef = directiveInstance !.vcref.detach(0);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
|
||||||
'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
directiveInstance !.vcref.insert(viewRef !);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
|
|
||||||
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
|
|
||||||
'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
|
|
||||||
log.length = 0;
|
|
||||||
directiveInstance !.vcref.remove(0);
|
|
||||||
fixture.update();
|
|
||||||
expect(log).toEqual([
|
|
||||||
'onDestroy-D', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A',
|
|
||||||
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
|
||||||
|
const fixture = new ComponentFixture(SomeComponent);
|
||||||
|
expect(log).toEqual([
|
||||||
|
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
|
||||||
|
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
|
||||||
|
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
|
||||||
|
'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
const componentRef = directiveInstance !.vcref.createComponent(
|
||||||
|
directiveInstance !.cfr.resolveComponentFactory(ComponentWithHooks));
|
||||||
|
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
|
||||||
|
expect(log).toEqual([]);
|
||||||
|
|
||||||
|
componentRef.instance.name = 'D';
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>D</hooks><hooks>B</hooks>');
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'onChanges-D', 'onInit-D', 'doCheck-D', 'afterContentInit-D',
|
||||||
|
'afterContentChecked-D', 'afterViewInit-D', 'afterViewChecked-D', 'afterContentChecked-A',
|
||||||
|
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
|
||||||
|
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
const viewRef = directiveInstance !.vcref.detach(0);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
directiveInstance !.vcref.insert(viewRef !);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
|
||||||
|
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.length = 0;
|
||||||
|
directiveInstance !.vcref.remove(0);
|
||||||
|
fixture.update();
|
||||||
|
expect(log).toEqual([
|
||||||
|
'onDestroy-D', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
|
||||||
|
'afterViewChecked-A', 'afterViewChecked-B'
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('host bindings', () => {
|
describe('host bindings', () => {
|
||||||
|
|
Loading…
Reference in New Issue