diff --git a/packages/core/test/application_ref_spec.ts b/packages/core/test/application_ref_spec.ts index 84d2845802..8aa5efd244 100644 --- a/packages/core/test/application_ref_spec.ts +++ b/packages/core/test/application_ref_spec.ts @@ -74,7 +74,7 @@ class SomeComponent { 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', async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => { @Component({ @@ -103,7 +103,7 @@ class SomeComponent { 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', async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => { @Component({ @@ -176,12 +176,13 @@ class SomeComponent { }); }); - fixmeIvy('unknown') && it('should be called when a component is bootstrapped', - inject([ApplicationRef], (ref: ApplicationRef) => { - createRootEl(); - const compRef = ref.bootstrap(SomeComponent); - expect(capturedCompRefs).toEqual([compRef]); - })); + fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') && + it('should be called when a component is bootstrapped', + inject([ApplicationRef], (ref: ApplicationRef) => { + createRootEl(); + const compRef = ref.bootstrap(SomeComponent); + expect(capturedCompRefs).toEqual([compRef]); + })); }); describe('bootstrap', () => { diff --git a/packages/core/test/directive_lifecycle_integration_spec.ts b/packages/core/test/directive_lifecycle_integration_spec.ts index e1a1e3b0bd..84e944188a 100644 --- a/packages/core/test/directive_lifecycle_integration_spec.ts +++ b/packages/core/test/directive_lifecycle_integration_spec.ts @@ -10,46 +10,42 @@ import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, import {Component, Directive} from '@angular/core/src/metadata'; import {TestBed, inject} from '@angular/core/testing'; import {Log} from '@angular/core/testing/src/testing_internal'; -import {fixmeIvy} from '@angular/private/testing'; -{ - describe('directive lifecycle integration spec', () => { - let log: Log; +describe('directive lifecycle integration spec', () => { + let log: Log; - beforeEach(() => { - TestBed - .configureTestingModule({ - declarations: [ - LifecycleCmp, - LifecycleDir, - MyComp5, - ], - providers: [Log] - }) - .overrideComponent(MyComp5, {set: {template: '
'}}); - }); - - 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(() => { + TestBed + .configureTestingModule({ + declarations: [ + LifecycleCmp, + LifecycleDir, + MyComp5, + ], + providers: [Log] + }) + .overrideComponent(MyComp5, {set: {template: '
'}}); }); -} + + 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]'}) diff --git a/packages/core/test/forward_ref_integration_spec.ts b/packages/core/test/forward_ref_integration_spec.ts index 64e18f5c86..f9a6127cc8 100644 --- a/packages/core/test/forward_ref_integration_spec.ts +++ b/packages/core/test/forward_ref_integration_spec.ts @@ -12,20 +12,18 @@ import {TestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/src/matchers'; import {fixmeIvy} from '@angular/private/testing'; -{ - describe('forwardRef integration', function() { - beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); }); +describe('forwardRef integration', function() { + beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); }); - fixmeIvy('unknown') && - it('should instantiate components which are declared using forwardRef', () => { - const a = - TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App); - a.detectChanges(); - expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)'); - expect(TestBed.get(ModuleFrame)).toBeDefined(); - }); - }); -} + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && + it('should instantiate components which are declared using forwardRef', () => { + const a = + TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App); + a.detectChanges(); + expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)'); + expect(TestBed.get(ModuleFrame)).toBeDefined(); + }); +}); @NgModule({ imports: [CommonModule], diff --git a/packages/core/test/linker/entry_components_integration_spec.ts b/packages/core/test/linker/entry_components_integration_spec.ts index da6520d04b..d9904ea1a8 100644 --- a/packages/core/test/linker/entry_components_integration_spec.ts +++ b/packages/core/test/linker/entry_components_integration_spec.ts @@ -13,13 +13,11 @@ import {TestBed} from '@angular/core/testing'; import {fixmeIvy} from '@angular/private/testing'; -{ - if (ivyEnabled) { - describe('ivy', () => { declareTests(); }); - } else { - describe('jit', () => { declareTests({useJit: true}); }); - describe('no jit', () => { declareTests({useJit: false}); }); - } +if (ivyEnabled) { + describe('ivy', () => { declareTests(); }); +} else { + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } class DummyConsole implements Console { diff --git a/packages/core/test/linker/ng_container_integration_spec.ts b/packages/core/test/linker/ng_container_integration_spec.ts index 5b3ea1c78f..cebd470fc7 100644 --- a/packages/core/test/linker/ng_container_integration_spec.ts +++ b/packages/core/test/linker/ng_container_integration_spec.ts @@ -13,13 +13,11 @@ import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {expect} from '@angular/platform-browser/testing/src/matchers'; import {fixmeIvy, polyfillGoogGetMsg} from '@angular/private/testing'; -{ - if (ivyEnabled) { - describe('ivy', () => { declareTests(); }); - } else { - describe('jit', () => { declareTests({useJit: true}); }); - describe('no jit', () => { declareTests({useJit: false}); }); - } +if (ivyEnabled) { + describe('ivy', () => { declareTests(); }); +} else { + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } function declareTests(config?: {useJit: boolean}) { diff --git a/packages/core/test/linker/ng_module_integration_spec.ts b/packages/core/test/linker/ng_module_integration_spec.ts index 6a4fc85cf3..ad299661fe 100644 --- a/packages/core/test/linker/ng_module_integration_spec.ts +++ b/packages/core/test/linker/ng_module_integration_spec.ts @@ -142,8 +142,8 @@ function declareTests(config?: {useJit: boolean}) { 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', () => { @NgModule({exports: [SomeDirective]}) 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!`); }); + fixmeIvy('FW-682: Compiler error handling') && it('should error when exporting a pipe that was neither declared nor imported', () => { @NgModule({exports: [SomePipe]}) 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!`); }); + fixmeIvy('FW-682: Compiler error handling') && it('should error if a directive is declared in more than 1 module', () => { @NgModule({declarations: [SomeDirective]}) 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)}.`); }); + 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', () => { @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)}.`); }); + fixmeIvy('FW-682: Compiler error handling') && it('should error if a pipe is declared in more than 1 module', () => { @NgModule({declarations: [SomePipe]}) 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)}.`); }); + 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', () => { @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)}.`); }); - }); + }); describe('schemas', () => { fixmeIvy('FW-682: Compiler error handling') && @@ -1048,7 +1053,7 @@ function declareTests(config?: {useJit: boolean}) { 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', () => { let destroyed = false; @@ -1068,7 +1073,7 @@ function declareTests(config?: {useJit: boolean}) { 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', () => { let created = false; let destroyed = false; @@ -1330,7 +1335,7 @@ function declareTests(config?: {useJit: boolean}) { }); describe('tree shakable providers', () => { - fixmeIvy('providersByKey is not defined') && + fixmeIvy('unknown') && it('definition should not persist across NgModuleRef instances', () => { @NgModule() class SomeModule { diff --git a/packages/core/test/linker/regression_integration_spec.ts b/packages/core/test/linker/regression_integration_spec.ts index 646e95e67a..42c1776587 100644 --- a/packages/core/test/linker/regression_integration_spec.ts +++ b/packages/core/test/linker/regression_integration_spec.ts @@ -12,19 +12,17 @@ import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {expect} from '@angular/platform-browser/testing/src/matchers'; -import {fixmeIvy} from '@angular/private/testing'; +import {fixmeIvy, modifiedInIvy} from '@angular/private/testing'; -{ - if (ivyEnabled) { - describe('ivy', () => { declareTests(); }); - } else { - describe('jit', () => { declareTests({useJit: true}); }); - describe('no jit', () => { declareTests({useJit: false}); }); - } - - declareTestsUsingBootstrap(); +if (ivyEnabled) { + describe('ivy', () => { declareTests(); }); +} else { + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } +declareTestsUsingBootstrap(); + function declareTests(config?: {useJit: boolean}) { // Place to put reproductions for regressions describe('regressions', () => { @@ -162,14 +160,13 @@ function declareTests(config?: {useJit: boolean}) { 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', () => { - const token = 'a.b'; - const tokenValue = 1; - const injector = createInjector([{provide: token, useValue: tokenValue}]); + it('should support providers with string token with a `.` in it', () => { + const token = 'a.b'; + const tokenValue = 1; + 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', () => { const token = () => true; @@ -191,15 +188,14 @@ function declareTests(config?: {useJit: boolean}) { 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', () => { - class TestClass { - constructor(public name: number) {} - } - const data = [new TestClass(1), new TestClass(2)]; - const injector = createInjector([{provide: 'someToken', useValue: data}]); - expect(injector.get('someToken')).toEqual(data); - }); + it('should support providers that have a `name` property with a number value', () => { + class TestClass { + constructor(public name: number) {} + } + const data = [new TestClass(1), new TestClass(2)]; + const injector = createInjector([{provide: 'someToken', useValue: data}]); + expect(injector.get('someToken')).toEqual(data); + }); describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => { @@ -337,21 +333,22 @@ function declareTests(config?: {useJit: boolean}) { expect(fixture.debugElement.childNodes.length).toBe(0); }); - fixmeIvy('unknown') && it('should allow empty embedded templates', () => { - @Component({template: ''}) - class MyComp { - } + modifiedInIvy('Comment node order changed') && + it('should allow empty embedded templates', () => { + @Component({template: ''}) + class MyComp { + } - const fixture = - TestBed.configureTestingModule({declarations: [MyComp]}).createComponent(MyComp); - fixture.detectChanges(); + const fixture = + TestBed.configureTestingModule({declarations: [MyComp]}).createComponent(MyComp); + fixture.detectChanges(); - // Note: We always need to create at least a comment in an embedded template, - // so we can append other templates after it. - // 1 comment for the anchor, - // 1 comment for the empty embedded template. - expect(fixture.debugElement.childNodes.length).toBe(2); - }); + // Note: We always need to create at least a comment in an embedded template, + // so we can append other templates after it. + // 1 comment for the anchor, + // 1 comment for the empty embedded template. + expect(fixture.debugElement.childNodes.length).toBe(2); + }); }); fixmeIvy('unknown') && diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index 191419f791..0b0aeef96a 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -1608,216 +1608,206 @@ describe('ViewContainerRef', () => { }); } - fixmeIvy(`Hooks don't run`) && - it('should call all hooks in correct order when creating with createEmbeddedView', () => { - function SomeComponent_Template_0(rf: RenderFlags, ctx: any) { - if (rf & RenderFlags.Create) { - element(0, 'hooks'); - } - if (rf & RenderFlags.Update) { - elementProperty(0, 'name', bind('C')); - } - } + it('should call all hooks in correct order when creating with createEmbeddedView', () => { + function SomeComponent_Template_0(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { + element(0, 'hooks'); + } + if (rf & RenderFlags.Update) { + elementProperty(0, 'name', bind('C')); + } + } - @Component({ - template: ` + @Component({ + template: ` ` - }) - class SomeComponent { - static ngComponentDef = defineComponent({ - type: SomeComponent, - selectors: [['some-comp']], - factory: () => new SomeComponent(), - consts: 4, - vars: 3, - template: (rf: RenderFlags, cmp: SomeComponent) => { - if (rf & RenderFlags.Create) { - template( - 0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], - templateRefExtractor); - element(2, 'hooks', ['vcref', '']); - element(3, 'hooks'); - } - if (rf & RenderFlags.Update) { - const tplRef = reference(1); - elementProperty(2, 'tplRef', bind(tplRef)); - elementProperty(2, 'name', bind('A')); - elementProperty(3, 'name', bind('B')); - } - }, - 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('AB'); - expect(log).toEqual([]); - - log.length = 0; - fixture.update(); - expect(fixture.html).toEqual('ACB'); - 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' - ]); + }) + class SomeComponent { + static ngComponentDef = defineComponent({ + type: SomeComponent, + selectors: [['some-comp']], + factory: () => new SomeComponent(), + consts: 4, + vars: 3, + template: (rf: RenderFlags, cmp: SomeComponent) => { + if (rf & RenderFlags.Create) { + template( + 0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor); + element(2, 'hooks', ['vcref', '']); + element(3, 'hooks'); + } + if (rf & RenderFlags.Update) { + const tplRef = reference(1); + elementProperty(2, 'tplRef', bind(tplRef)); + elementProperty(2, 'name', bind('A')); + elementProperty(3, 'name', bind('B')); + } + }, + directives: [ComponentWithHooks, DirectiveWithVCRef] }); + } - fixmeIvy(`Hooks don't run`) && - it('should call all hooks in correct order when creating with createComponent', () => { - @Component({ - template: ` + 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('AB'); + expect(log).toEqual([]); + + log.length = 0; + fixture.update(); + expect(fixture.html).toEqual('ACB'); + 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: ` ` - }) - class SomeComponent { - static ngComponentDef = defineComponent({ - type: SomeComponent, - encapsulation: ViewEncapsulation.None, - selectors: [['some-comp']], - factory: () => new SomeComponent(), - consts: 2, - vars: 2, - template: (rf: RenderFlags, cmp: SomeComponent) => { - if (rf & RenderFlags.Create) { - element(0, 'hooks', ['vcref', '']); - element(1, 'hooks'); - } - if (rf & RenderFlags.Update) { - elementProperty(0, 'name', bind('A')); - elementProperty(1, 'name', bind('B')); - } - }, - 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('AB'); - expect(log).toEqual([]); - - componentRef.instance.name = 'D'; - log.length = 0; - fixture.update(); - expect(fixture.html).toEqual('ADB'); - 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' - ]); + }) + class SomeComponent { + static ngComponentDef = defineComponent({ + type: SomeComponent, + encapsulation: ViewEncapsulation.None, + selectors: [['some-comp']], + factory: () => new SomeComponent(), + consts: 2, + vars: 2, + template: (rf: RenderFlags, cmp: SomeComponent) => { + if (rf & RenderFlags.Create) { + element(0, 'hooks', ['vcref', '']); + element(1, 'hooks'); + } + if (rf & RenderFlags.Update) { + elementProperty(0, 'name', bind('A')); + elementProperty(1, 'name', bind('B')); + } + }, + 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('AB'); + expect(log).toEqual([]); + + componentRef.instance.name = 'D'; + log.length = 0; + fixture.update(); + expect(fixture.html).toEqual('ADB'); + 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', () => {