diff --git a/packages/bazel/test/ng_package/core_package.spec.ts b/packages/bazel/test/ng_package/core_package.spec.ts index 0a41d7f386..fe30af67d8 100644 --- a/packages/bazel/test/ng_package/core_package.spec.ts +++ b/packages/bazel/test/ng_package/core_package.spec.ts @@ -74,9 +74,9 @@ describe('@angular/core ng_package', () => { describe('typescript support', () => { - fixmeIvy('FW-738: ngtsc doesn\'t generate flat index files') && - it('should have an index d.ts file', - () => { expect(shx.cat('core.d.ts')).toContain(`export *`); }); + fixmeIvy('FW-738: ngtsc doesn\'t generate flat index files') + .it('should have an index d.ts file', + () => { expect(shx.cat('core.d.ts')).toContain(`export *`); }); it('should not have amd module names', () => { expect(shx.cat('public_api.d.ts')).not.toContain(' { }); - obsoleteInIvy('metadata files are no longer needed or produced in Ivy') && - describe('angular metadata', () => { + obsoleteInIvy('metadata files are no longer needed or produced in Ivy') + .describe('angular metadata', () => { it('should have metadata.json files', () => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); }); @@ -112,8 +112,8 @@ describe('@angular/core ng_package', () => { .toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/); }); - obsoleteInIvy('we no longer need to export private symbols') && - it('should have been built from the generated bundle index', () => { + obsoleteInIvy('we no longer need to export private symbols') + .it('should have been built from the generated bundle index', () => { expect(shx.cat('fesm2015/core.js')).toMatch('export {.*makeParamDecorator'); }); }); @@ -147,9 +147,9 @@ describe('@angular/core ng_package', () => { expect(shx.cat('fesm5/core.js')).toMatch('import {.*__extends'); }); - obsoleteInIvy('we no longer need to export private symbols') && - it('should have been built from the generated bundle index', - () => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); }); + obsoleteInIvy('we no longer need to export private symbols') + .it('should have been built from the generated bundle index', + () => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); }); }); @@ -228,13 +228,13 @@ describe('@angular/core ng_package', () => { () => { expect(shx.cat(typingsFile)).toContain('export * from \'./public_api\';'); }); obsoleteInIvy( - 'now that we don\'t need metadata files, we don\'t need these redirects to help resolve paths to them') && - it('should have an \'redirect\' d.ts file in the parent dir', - () => { expect(shx.cat('testing.d.ts')).toContain(`export *`); }); + 'now that we don\'t need metadata files, we don\'t need these redirects to help resolve paths to them') + .it('should have an \'redirect\' d.ts file in the parent dir', + () => { expect(shx.cat('testing.d.ts')).toContain(`export *`); }); }); - obsoleteInIvy('metadata files are no longer needed or produced in Ivy') && - describe('angular metadata file', () => { + obsoleteInIvy('metadata files are no longer needed or produced in Ivy') + .describe('angular metadata file', () => { it('should have a \'redirect\' metadata.json file next to the d.ts file', () => { expect(shx.cat('testing.metadata.json')) .toContain( diff --git a/packages/bazel/test/ngc-wrapped/index_test.ts b/packages/bazel/test/ngc-wrapped/index_test.ts index 3c12370add..5d61112da7 100644 --- a/packages/bazel/test/ngc-wrapped/index_test.ts +++ b/packages/bazel/test/ngc-wrapped/index_test.ts @@ -17,7 +17,7 @@ describe('ngc_wrapped', () => { // fixmeIvy placeholder to prevent jasmine from erroring out because there are no specs it('should be removed once the fixmeIvy below is resolved', () => {}); - fixmeIvy('FW-741: ngtsc breaks tsc module resolution') && it('should work', () => { + fixmeIvy('FW-741: ngtsc breaks tsc module resolution').it('should work', () => { const {read, write, runOneBuild, writeConfig, shouldExist, basePath} = setup(); write('some_project/index.ts', ` diff --git a/packages/common/test/directives/ng_component_outlet_spec.ts b/packages/common/test/directives/ng_component_outlet_spec.ts index 1a0ce54240..cf3d56d96f 100644 --- a/packages/common/test/directives/ng_component_outlet_spec.ts +++ b/packages/common/test/directives/ng_component_outlet_spec.ts @@ -157,22 +157,22 @@ describe('insert/remove', () => { expect(fixture.nativeElement).toHaveText('baz'); })); - fixmeIvy('FW-739: destroy on NgModuleRef is not being called') && - it('should clean up moduleRef, if supplied', async(() => { - let destroyed = false; - const compiler = TestBed.get(Compiler) as Compiler; - const fixture = TestBed.createComponent(TestComponent); - fixture.componentInstance.module = compiler.compileModuleSync(TestModule2); - fixture.componentInstance.currentComponent = Module2InjectedComponent; - fixture.detectChanges(); + fixmeIvy('FW-739: destroy on NgModuleRef is not being called') + .it('should clean up moduleRef, if supplied', async(() => { + let destroyed = false; + const compiler = TestBed.get(Compiler) as Compiler; + const fixture = TestBed.createComponent(TestComponent); + fixture.componentInstance.module = compiler.compileModuleSync(TestModule2); + fixture.componentInstance.currentComponent = Module2InjectedComponent; + fixture.detectChanges(); - const moduleRef = fixture.componentInstance.ngComponentOutlet['_moduleRef'] !; - spyOn(moduleRef, 'destroy').and.callThrough(); + const moduleRef = fixture.componentInstance.ngComponentOutlet['_moduleRef'] !; + spyOn(moduleRef, 'destroy').and.callThrough(); - expect(moduleRef.destroy).not.toHaveBeenCalled(); - fixture.destroy(); - expect(moduleRef.destroy).toHaveBeenCalled(); - })); + expect(moduleRef.destroy).not.toHaveBeenCalled(); + fixture.destroy(); + expect(moduleRef.destroy).toHaveBeenCalled(); + })); it('should not re-create moduleRef when it didn\'t actually change', async(() => { const compiler = TestBed.get(Compiler) as Compiler; diff --git a/packages/compiler-cli/integrationtest/bazel/injectable_def/app/test/app_spec.ts b/packages/compiler-cli/integrationtest/bazel/injectable_def/app/test/app_spec.ts index b77bc09ddb..7d55145982 100644 --- a/packages/compiler-cli/integrationtest/bazel/injectable_def/app/test/app_spec.ts +++ b/packages/compiler-cli/integrationtest/bazel/injectable_def/app/test/app_spec.ts @@ -168,8 +168,8 @@ describe('ngInjectableDef Bazel Integration', () => { expect(TestBed.get(INJECTOR).get('foo')).toEqual('bar'); }); - fixmeIvy('FW-646: Directive providers don\'t support primitive types') && - it('Component injector understands requests for INJECTABLE', () => { + fixmeIvy('FW-646: Directive providers don\'t support primitive types') + .it('Component injector understands requests for INJECTABLE', () => { @Component({ selector: 'test-cmp', template: 'test', diff --git a/packages/compiler-cli/integrationtest/bazel/injector_def/ivy_build/app/test/module_spec.ts b/packages/compiler-cli/integrationtest/bazel/injector_def/ivy_build/app/test/module_spec.ts index df3edc685e..80b6517a01 100644 --- a/packages/compiler-cli/integrationtest/bazel/injector_def/ivy_build/app/test/module_spec.ts +++ b/packages/compiler-cli/integrationtest/bazel/injector_def/ivy_build/app/test/module_spec.ts @@ -41,8 +41,8 @@ describe('Ivy NgModule', () => { it('works', () => { createInjector(JitAppModule); }); - fixmeIvy('FW-645: jit doesn\'t support forwardRefs') && - it('throws an error on circular module dependencies', () => { + fixmeIvy('FW-645: jit doesn\'t support forwardRefs') + .it('throws an error on circular module dependencies', () => { @NgModule({ imports: [forwardRef(() => BModule)], }) diff --git a/packages/compiler-cli/test/ngtools_api_spec.ts b/packages/compiler-cli/test/ngtools_api_spec.ts index e0424bd3a9..3fd3832659 100644 --- a/packages/compiler-cli/test/ngtools_api_spec.ts +++ b/packages/compiler-cli/test/ngtools_api_spec.ts @@ -60,7 +60,7 @@ describe('ngtools_api (deprecated)', () => { }); } - fixmeIvy('FW-629: ngtsc lists lazy routes') && it('should list lazy routes recursively', () => { + fixmeIvy('FW-629: ngtsc lists lazy routes').it('should list lazy routes recursively', () => { writeSomeRoutes(); const {program, host, options} = createProgram(['src/main.ts']); const routes = NgTools_InternalApi_NG_2.listLazyRoutes({ diff --git a/packages/core/test/application_ref_integration_spec.ts b/packages/core/test/application_ref_integration_spec.ts index 3df76d2bd4..f66e946cfb 100644 --- a/packages/core/test/application_ref_integration_spec.ts +++ b/packages/core/test/application_ref_integration_spec.ts @@ -35,26 +35,26 @@ ivyEnabled && describe('ApplicationRef bootstrap', () => { class MyAppModule { } - fixmeIvy('unknown') && - it('should bootstrap hello world', withBody('', async() => { - const MyAppModuleFactory = new NgModuleFactory(MyAppModule); - const moduleRef = await getTestBed().platform.bootstrapModuleFactory( - MyAppModuleFactory, {ngZone: 'noop'}); - const appRef = moduleRef.injector.get(ApplicationRef); - const helloWorldComponent = appRef.components[0].instance as HelloWorldComponent; - expect(document.body.innerHTML) - .toEqual('
Hello World
'); - expect(helloWorldComponent.log).toEqual(['OnInit', 'DoCheck']); + fixmeIvy('unknown').it( + 'should bootstrap hello world', withBody('', async() => { + const MyAppModuleFactory = new NgModuleFactory(MyAppModule); + const moduleRef = await getTestBed().platform.bootstrapModuleFactory( + MyAppModuleFactory, {ngZone: 'noop'}); + const appRef = moduleRef.injector.get(ApplicationRef); + const helloWorldComponent = appRef.components[0].instance as HelloWorldComponent; + expect(document.body.innerHTML) + .toEqual('
Hello World
'); + expect(helloWorldComponent.log).toEqual(['OnInit', 'DoCheck']); - helloWorldComponent.name = 'Mundo'; - appRef.tick(); - expect(document.body.innerHTML) - .toEqual('
Hello Mundo
'); - expect(helloWorldComponent.log).toEqual(['OnInit', 'DoCheck', 'DoCheck']); + helloWorldComponent.name = 'Mundo'; + appRef.tick(); + expect(document.body.innerHTML) + .toEqual('
Hello Mundo
'); + expect(helloWorldComponent.log).toEqual(['OnInit', 'DoCheck', 'DoCheck']); - // Cleanup TestabilityRegistry - const registry: TestabilityRegistry = getTestBed().get(TestabilityRegistry); - registry.unregisterAllApplications(); - })); + // Cleanup TestabilityRegistry + const registry: TestabilityRegistry = getTestBed().get(TestabilityRegistry); + registry.unregisterAllApplications(); + })); }); diff --git a/packages/core/test/application_ref_spec.ts b/packages/core/test/application_ref_spec.ts index 508606ce77..0b194e7fea 100644 --- a/packages/core/test/application_ref_spec.ts +++ b/packages/core/test/application_ref_spec.ts @@ -74,63 +74,63 @@ class SomeComponent { return MyModule; } - 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({ - selector: 'bootstrap-app', - template: '', - }) - class SomeComponent { - } + 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({ + selector: 'bootstrap-app', + template: '', + }) + class SomeComponent { + } - @NgModule({ - providers: [{provide: 'hello', useValue: 'component'}], - declarations: [SomeComponent], - entryComponents: [SomeComponent], - }) - class SomeModule { - } + @NgModule({ + providers: [{provide: 'hello', useValue: 'component'}], + declarations: [SomeComponent], + entryComponents: [SomeComponent], + }) + class SomeModule { + } - createRootEl(); - const modFactory = compiler.compileModuleSync(SomeModule); - const module = modFactory.create(TestBed); - const cmpFactory = - module.componentFactoryResolver.resolveComponentFactory(SomeComponent) !; - const component = app.bootstrap(cmpFactory); + createRootEl(); + const modFactory = compiler.compileModuleSync(SomeModule); + const module = modFactory.create(TestBed); + const cmpFactory = + module.componentFactoryResolver.resolveComponentFactory(SomeComponent) !; + const component = app.bootstrap(cmpFactory); - // The component should see the child module providers - expect(component.injector.get('hello')).toEqual('component'); - }))); + // The component should see the child module providers + expect(component.injector.get('hello')).toEqual('component'); + }))); - 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({ - selector: 'bootstrap-app', - template: '', - }) - class SomeComponent { - } + 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({ + selector: 'bootstrap-app', + template: '', + }) + class SomeComponent { + } - @NgModule({ - providers: [{provide: 'hello', useValue: 'component'}], - declarations: [SomeComponent], - entryComponents: [SomeComponent], - }) - class SomeModule { - } + @NgModule({ + providers: [{provide: 'hello', useValue: 'component'}], + declarations: [SomeComponent], + entryComponents: [SomeComponent], + }) + class SomeModule { + } - createRootEl('custom-selector'); - const modFactory = compiler.compileModuleSync(SomeModule); - const module = modFactory.create(TestBed); - const cmpFactory = - module.componentFactoryResolver.resolveComponentFactory(SomeComponent) !; - const component = app.bootstrap(cmpFactory, 'custom-selector'); + createRootEl('custom-selector'); + const modFactory = compiler.compileModuleSync(SomeModule); + const module = modFactory.create(TestBed); + const cmpFactory = + module.componentFactoryResolver.resolveComponentFactory(SomeComponent) !; + const component = app.bootstrap(cmpFactory, 'custom-selector'); - // The component should see the child module providers - expect(component.injector.get('hello')).toEqual('component'); - }))); + // The component should see the child module providers + expect(component.injector.get('hello')).toEqual('component'); + }))); describe('ApplicationRef', () => { beforeEach(() => { TestBed.configureTestingModule({imports: [createModule()]}); }); diff --git a/packages/core/test/fake_async_spec.ts b/packages/core/test/fake_async_spec.ts index 2a07838283..84c9c05fdb 100644 --- a/packages/core/test/fake_async_spec.ts +++ b/packages/core/test/fake_async_spec.ts @@ -33,10 +33,10 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec' })('foo', 'bar'); }); - fixmeIvy('unknown') && it('should work with inject()', - fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => { - expect(parser).toBeAnInstanceOf(Parser); - }))); + fixmeIvy('unknown').it( + 'should work with inject()', fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => { + expect(parser).toBeAnInstanceOf(Parser); + }))); it('should throw on nested calls', () => { expect(() => { diff --git a/packages/core/test/forward_ref_integration_spec.ts b/packages/core/test/forward_ref_integration_spec.ts index f9a6127cc8..1389642298 100644 --- a/packages/core/test/forward_ref_integration_spec.ts +++ b/packages/core/test/forward_ref_integration_spec.ts @@ -15,8 +15,8 @@ import {fixmeIvy} from '@angular/private/testing'; describe('forwardRef integration', function() { beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); }); - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should instantiate components which are declared using forwardRef', () => { + 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(); diff --git a/packages/core/test/linker/entry_components_integration_spec.ts b/packages/core/test/linker/entry_components_integration_spec.ts index d9904ea1a8..ec9bf38a37 100644 --- a/packages/core/test/linker/entry_components_integration_spec.ts +++ b/packages/core/test/linker/entry_components_integration_spec.ts @@ -69,21 +69,20 @@ function declareTests(config?: {useJit: boolean}) { expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp); }); - fixmeIvy('unknown') && - it('should not be able to get components from a parent component (content hierarchy)', - () => { - TestBed.overrideComponent( - MainComp, {set: {template: ''}}); - TestBed.overrideComponent(ChildComp, {set: {template: ''}}); + fixmeIvy('unknown').it( + 'should not be able to get components from a parent component (content hierarchy)', () => { + TestBed.overrideComponent( + MainComp, {set: {template: ''}}); + TestBed.overrideComponent(ChildComp, {set: {template: ''}}); - const compFixture = TestBed.createComponent(MainComp); - const nestedChildCompEl = compFixture.debugElement.children[0].children[0]; - const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance; - expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType) - .toBe(ChildComp); - expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp)) - .toThrow(noComponentFactoryError(NestedChildComp)); - }); + const compFixture = TestBed.createComponent(MainComp); + const nestedChildCompEl = compFixture.debugElement.children[0].children[0]; + const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance; + expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType) + .toBe(ChildComp); + expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp)) + .toThrow(noComponentFactoryError(NestedChildComp)); + }); }); } diff --git a/packages/core/test/linker/integration_spec.ts b/packages/core/test/linker/integration_spec.ts index 8d9555d515..faf7c82b25 100644 --- a/packages/core/test/linker/integration_spec.ts +++ b/packages/core/test/linker/integration_spec.ts @@ -209,8 +209,8 @@ function declareTests(config?: {useJit: boolean}) { .toEqual('Some other
HTML
'); }); - modifiedInIvy('Binding to the class property directly works differently') && - it('should consume binding to className using class alias', () => { + modifiedInIvy('Binding to the class property directly works differently') + .it('should consume binding to className using class alias', () => { TestBed.configureTestingModule({declarations: [MyComp]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -238,8 +238,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo'); }); - fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && - it('should consume directive watch expression change.', () => { + fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') + .it('should consume directive watch expression change.', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); const template = '' + '
' + @@ -263,8 +263,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('pipes', () => { - fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && - it('should support pipes in bindings', () => { + fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') + .it('should support pipes in bindings', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir, DoublePipe]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -290,8 +290,8 @@ function declareTests(config?: {useJit: boolean}) { }); // GH issue 328 - https://github.com/angular/angular/issues/328 - fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && - it('should support different directive types on a single node', () => { + fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') + .it('should support different directive types on a single node', () => { TestBed.configureTestingModule({declarations: [MyComp, ChildComp, MyDir]}); const template = ''; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -350,8 +350,8 @@ function declareTests(config?: {useJit: boolean}) { expect(tc.injector.get(EventDir)).not.toBeNull(); }); - fixmeIvy('FW-680: Throw meaningful error for uninitialized @Output') && - it('should display correct error message for uninitialized @Output', () => { + fixmeIvy('FW-680: Throw meaningful error for uninitialized @Output') + .it('should display correct error message for uninitialized @Output', () => { @Component({selector: 'my-uninitialized-output', template: '

It works!

'}) class UninitializedOutputComp { @Output() customEvent !: EventEmitter; @@ -374,8 +374,8 @@ function declareTests(config?: {useJit: boolean}) { const fixture = TestBed.createComponent(MyComp); }); - modifiedInIvy('Comment node order changed') && - it('should support template directives via `` elements.', () => { + modifiedInIvy('Comment node order changed') + .it('should support template directives via `` elements.', () => { TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); const template = '{{greeting}}'; @@ -403,8 +403,8 @@ function declareTests(config?: {useJit: boolean}) { }); 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.', () => { + '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 = '
{{greeting}}
'; @@ -478,8 +478,8 @@ function declareTests(config?: {useJit: boolean}) { .toBeAnInstanceOf(ExportDir); }); - fixmeIvy('FW-708: Directives with multiple exports are not supported') && - it('should assign a directive to a ref when it has multiple exportAs names', () => { + fixmeIvy('FW-708: Directives with multiple exports are not supported') + .it('should assign a directive to a ref when it has multiple exportAs names', () => { TestBed.configureTestingModule( {declarations: [MyComp, DirectiveWithMultipleExportAsNames]}); @@ -543,8 +543,8 @@ function declareTests(config?: {useJit: boolean}) { expect(value.tagName.toLowerCase()).toEqual('div'); }); - fixmeIvy('FW-709: Context discovery does not support templates (comment nodes)') && - it('should assign the TemplateRef to a user-defined variable', () => { + fixmeIvy('FW-709: Context discovery does not support templates (comment nodes)') + .it('should assign the TemplateRef to a user-defined variable', () => { const fixture = TestBed.configureTestingModule({declarations: [MyComp]}) .overrideComponent( @@ -567,8 +567,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('variables', () => { - modifiedInIvy('Comment node order changed') && - it('should allow to use variables in a for loop', () => { + modifiedInIvy('Comment node order changed') + .it('should allow to use variables in a for loop', () => { const template = '{{i}}-{{cmp.ctxProp}}'; @@ -586,8 +586,8 @@ function declareTests(config?: {useJit: boolean}) { describe('OnPush components', () => { 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', () => { + '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 = ''; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -608,8 +608,8 @@ function declareTests(config?: {useJit: boolean}) { }); 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', () => { + '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 = ''; @@ -628,28 +628,27 @@ function declareTests(config?: {useJit: boolean}) { }); if (getDOM().supportsDOMEvents()) { - fixmeIvy('unknown') && - it('should allow to destroy a component from within a host event handler', - fakeAsync(() => { - TestBed.configureTestingModule( - {declarations: [MyComp, [[PushCmpWithHostEvent]]]}); - const template = ''; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown').it( + 'should allow to destroy a component from within a host event handler', + fakeAsync(() => { + TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]}); + const template = ''; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - const cmpEl = fixture.debugElement.children[0]; - const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent); - cmp.ctxCallback = (_: any) => fixture.destroy(); + const cmpEl = fixture.debugElement.children[0]; + const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent); + cmp.ctxCallback = (_: any) => fixture.destroy(); - expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); - })); + expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); + })); } - fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2') && - it('should be checked when an event is fired', () => { + 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 = ''; @@ -774,71 +773,71 @@ function declareTests(config?: {useJit: boolean}) { }); 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]}); - const template = '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + '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]}); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - const tc = fixture.debugElement.children[0]; - const emitter = tc.injector.get(DirectiveEmittingEvent); - const listener = tc.injector.get(DirectiveListeningEvent); + const tc = fixture.debugElement.children[0]; + const emitter = tc.injector.get(DirectiveEmittingEvent); + const listener = tc.injector.get(DirectiveListeningEvent); - expect(listener.msg).toEqual(''); - let eventCount = 0; + expect(listener.msg).toEqual(''); + let eventCount = 0; - emitter.event.subscribe({ - next: () => { - eventCount++; - if (eventCount === 1) { - expect(listener.msg).toEqual('fired !'); - fixture.destroy(); - emitter.fireEvent('fired again !'); - } else { - expect(listener.msg).toEqual('fired !'); - } - } - }); + emitter.event.subscribe({ + next: () => { + eventCount++; + if (eventCount === 1) { + expect(listener.msg).toEqual('fired !'); + fixture.destroy(); + emitter.fireEvent('fired again !'); + } else { + expect(listener.msg).toEqual('fired !'); + } + } + }); - emitter.fireEvent('fired !'); - })); + emitter.fireEvent('fired !'); + })); fixmeIvy( - 'FW-665: Discovery util fails with Unable to find the given context data for the given target') && - it('should support events via EventEmitter on template elements', async(() => { - const fixture = - TestBed - .configureTestingModule({ - declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent] - }) - .overrideComponent(MyComp, { - set: { - template: - '' - } - }) - .createComponent(MyComp); + 'FW-665: Discovery util fails with Unable to find the given context data for the given target') + .it('should support events via EventEmitter on template elements', async(() => { + const fixture = + TestBed + .configureTestingModule({ + declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent] + }) + .overrideComponent(MyComp, { + set: { + template: + '' + } + }) + .createComponent(MyComp); - const tc = fixture.debugElement.childNodes[0]; + const tc = fixture.debugElement.childNodes[0]; - const emitter = tc.injector.get(DirectiveEmittingEvent); - const myComp = fixture.debugElement.injector.get(MyComp); - const listener = tc.injector.get(DirectiveListeningEvent); + const emitter = tc.injector.get(DirectiveEmittingEvent); + const myComp = fixture.debugElement.injector.get(MyComp); + const listener = tc.injector.get(DirectiveListeningEvent); - myComp.ctxProp = ''; - expect(listener.msg).toEqual(''); + myComp.ctxProp = ''; + expect(listener.msg).toEqual(''); - emitter.event.subscribe({ - next: () => { - expect(listener.msg).toEqual('fired !'); - expect(myComp.ctxProp).toEqual('fired !'); - } - }); + emitter.event.subscribe({ + next: () => { + expect(listener.msg).toEqual('fired !'); + expect(myComp.ctxProp).toEqual('fired !'); + } + }); - emitter.fireEvent('fired !'); - })); + emitter.fireEvent('fired !'); + })); it('should support [()] syntax', async(() => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTwoWayBinding]}); @@ -860,8 +859,8 @@ function declareTests(config?: {useJit: boolean}) { })); fixmeIvy( - 'FW-743: Registering events on global objects (document, window, body) is not supported') && - it('should support render events', () => { + 'FW-743: Registering events on global objects (document, window, body) is not supported') + .it('should support render events', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -883,8 +882,8 @@ function declareTests(config?: {useJit: boolean}) { }); fixmeIvy( - 'FW-743: Registering events on global objects (document, window, body) is not supported') && - it('should support render global events', () => { + 'FW-743: Registering events on global objects (document, window, body) is not supported') + .it('should support render global events', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -947,8 +946,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId'); }); - fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && - it('should not use template variables for expressions in hostProperties', () => { + fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') + .it('should not use template variables for expressions in hostProperties', () => { @Directive( {selector: '[host-properties]', host: {'[id]': 'id', '[title]': 'unknownProp'}}) class DirectiveWithHostProps { @@ -968,8 +967,8 @@ function declareTests(config?: {useJit: boolean}) { expect(tc.properties['title']).toBe(undefined); }); - fixmeIvy('FW-725: Pipes in host bindings fail with a cryptic error') && - it('should not allow pipes in hostProperties', () => { + fixmeIvy('FW-725: Pipes in host bindings fail with a cryptic error') + .it('should not allow pipes in hostProperties', () => { @Directive({selector: '[host-properties]', host: {'[id]': 'id | uppercase'}}) class DirectiveWithHostProps { } @@ -1004,8 +1003,8 @@ function declareTests(config?: {useJit: boolean}) { expect(dir.receivedArgs).toEqual(['one', undefined]); }); - fixmeIvy('FW-742: Pipes in host listeners should throw a descriptive error') && - it('should not allow pipes in hostListeners', () => { + fixmeIvy('FW-742: Pipes in host listeners should throw a descriptive error') + .it('should not allow pipes in hostListeners', () => { @Directive({selector: '[host-listener]', host: {'(click)': 'doIt() | somePipe'}}) class DirectiveWithHostListener { } @@ -1042,8 +1041,8 @@ function declareTests(config?: {useJit: boolean}) { } fixmeIvy( - 'FW-743: Registering events on global objects (document, window, body) is not supported') && - it('should support render global events from multiple directives', () => { + 'FW-743: Registering events on global objects (document, window, body) is not supported') + .it('should support render global events from multiple directives', () => { TestBed.configureTestingModule({ declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther] }); @@ -1123,8 +1122,8 @@ function declareTests(config?: {useJit: boolean}) { .toHaveText('dynamic greet'); })); - fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && - it('should create a component that has been freshly compiled', () => { + fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') + .it('should create a component that has been freshly compiled', () => { @Component({template: ''}) class RootComp { constructor(public vc: ViewContainerRef) {} @@ -1163,8 +1162,8 @@ function declareTests(config?: {useJit: boolean}) { expect(compRef.instance.someToken).toBe('someRootValue'); }); - fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && - it('should create a component with the passed NgModuleRef', () => { + fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') + .it('should create a component with the passed NgModuleRef', () => { @Component({template: ''}) class RootComp { constructor(public vc: ViewContainerRef) {} @@ -1204,48 +1203,48 @@ function declareTests(config?: {useJit: boolean}) { expect(compRef.instance.someToken).toBe('someValue'); }); - fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && - it('should create a component with the NgModuleRef of the ComponentFactoryResolver', - () => { - @Component({template: ''}) - class RootComp { - constructor(public vc: ViewContainerRef) {} - } + fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') + .it('should create a component with the NgModuleRef of the ComponentFactoryResolver', + () => { + @Component({template: ''}) + class RootComp { + constructor(public vc: ViewContainerRef) {} + } - @NgModule({ - declarations: [RootComp], - providers: [{provide: 'someToken', useValue: 'someRootValue'}], - }) - class RootModule { - } + @NgModule({ + declarations: [RootComp], + providers: [{provide: 'someToken', useValue: 'someRootValue'}], + }) + class RootModule { + } - @Component({template: ''}) - class MyComp { - constructor(@Inject('someToken') public someToken: string) {} - } + @Component({template: ''}) + class MyComp { + constructor(@Inject('someToken') public someToken: string) {} + } - @NgModule({ - declarations: [MyComp], - entryComponents: [MyComp], - providers: [{provide: 'someToken', useValue: 'someValue'}], - }) - class MyModule { - } + @NgModule({ + declarations: [MyComp], + entryComponents: [MyComp], + providers: [{provide: 'someToken', useValue: 'someValue'}], + }) + class MyModule { + } - const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) - .createComponent(RootComp); - const compiler = TestBed.get(Compiler); - const myModule = - compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); - const myCompFactory = - myModule.componentFactoryResolver.resolveComponentFactory(MyComp); + const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) + .createComponent(RootComp); + const compiler = TestBed.get(Compiler); + const myModule = + compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); + const myCompFactory = + myModule.componentFactoryResolver.resolveComponentFactory(MyComp); - // Note: MyComp was declared as entryComponent in MyModule, - // and we don't pass an explicit ModuleRef to the createComponent call. - // -> expect the providers of MyModule! - const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); - expect(compRef.instance.someToken).toBe('someValue'); - }); + // Note: MyComp was declared as entryComponent in MyModule, + // and we don't pass an explicit ModuleRef to the createComponent call. + // -> expect the providers of MyModule! + const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); + expect(compRef.instance.someToken).toBe('someValue'); + }); }); describe('.insert', () => { @@ -1336,7 +1335,7 @@ function declareTests(config?: {useJit: boolean}) { expect(comp.injectable).toBeAnInstanceOf(InjectableService); }); - fixmeIvy('unknown') && it('should support viewProviders', () => { + fixmeIvy('unknown').it('should support viewProviders', () => { TestBed.configureTestingModule({ declarations: [MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable], schemas: [NO_ERRORS_SCHEMA], @@ -1448,8 +1447,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().querySelectorAll(fixture.nativeElement, 'script').length).toEqual(0); }); - fixmeIvy('FW-662: Components without selector are not supported') && - it('should throw when using directives without selector', () => { + fixmeIvy('FW-662: Components without selector are not supported') + .it('should throw when using directives without selector', () => { @Directive({}) class SomeDirective { } @@ -1496,8 +1495,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('error handling', () => { - fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error') && - it('should report a meaningful error when a directive is missing annotation', () => { + 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]}); @@ -1506,20 +1505,21 @@ function declareTests(config?: {useJit: boolean}) { `Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`); }); - 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 { - TestBed.createComponent(ComponentWithoutView); - expect(true).toBe(false); - } catch (e) { - expect(e.message).toContain( - `No template specified for component ${stringify(ComponentWithoutView)}`); - } - }); + 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 { + TestBed.createComponent(ComponentWithoutView); + expect(true).toBe(false); + } catch (e) { + expect(e.message).toContain( + `No template specified for component ${stringify(ComponentWithoutView)}`); + } + }); - fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && - it('should provide an error context when an error happens in DI', () => { + fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') + .it('should provide an error context when an error happens in DI', () => { TestBed.configureTestingModule({ declarations: [MyComp, DirectiveThrowingAnError], schemas: [NO_ERRORS_SCHEMA], @@ -1537,8 +1537,8 @@ function declareTests(config?: {useJit: boolean}) { } }); - fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && - it('should provide an error context when an error happens in change detection', () => { + fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') + .it('should provide an error context when an error happens in change detection', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]}); const template = ``; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -1556,50 +1556,50 @@ function declareTests(config?: {useJit: boolean}) { } }); - fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && - it('should provide an error context when an error happens in change detection (text node)', - () => { - TestBed.configureTestingModule({declarations: [MyComp]}); - const template = `
{{one.two.three}}
`; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - try { - fixture.detectChanges(); - throw 'Should throw'; - } catch (e) { - const c = getDebugContext(e); - expect(c.renderNode).toBeTruthy(); - } - }); + fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') + .it('should provide an error context when an error happens in change detection (text node)', + () => { + TestBed.configureTestingModule({declarations: [MyComp]}); + const template = `
{{one.two.three}}
`; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); + try { + fixture.detectChanges(); + throw 'Should throw'; + } catch (e) { + const c = getDebugContext(e); + expect(c.renderNode).toBeTruthy(); + } + }); if (getDOM().supportsDOMEvents()) { // this is required to use fakeAsync - fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && - it('should provide an error context when an error happens in an event handler', - fakeAsync(() => { - TestBed.configureTestingModule({ - declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent], - schemas: [NO_ERRORS_SCHEMA], - }); - const template = ``; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - tick(); + fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') + .it('should provide an error context when an error happens in an event handler', + fakeAsync(() => { + TestBed.configureTestingModule({ + declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent], + schemas: [NO_ERRORS_SCHEMA], + }); + const template = ``; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); + tick(); - const tc = fixture.debugElement.children[0]; + const tc = fixture.debugElement.children[0]; - const errorHandler = tc.injector.get(ErrorHandler); - let err: any; - spyOn(errorHandler, 'handleError').and.callFake((e: any) => err = e); - tc.injector.get(DirectiveEmittingEvent).fireEvent('boom'); + const errorHandler = tc.injector.get(ErrorHandler); + let err: any; + spyOn(errorHandler, 'handleError').and.callFake((e: any) => err = e); + tc.injector.get(DirectiveEmittingEvent).fireEvent('boom'); - expect(err).toBeTruthy(); - const c = getDebugContext(err); - expect(getDOM().nodeName(c.renderNode).toUpperCase()).toEqual('SPAN'); - expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); - expect((c.injector).get).toBeTruthy(); - expect(c.context).toBe(fixture.componentInstance); - expect(c.references['local']).toBeDefined(); - })); + expect(err).toBeTruthy(); + const c = getDebugContext(err); + expect(getDOM().nodeName(c.renderNode).toUpperCase()).toEqual('SPAN'); + expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); + expect((c.injector).get).toBeTruthy(); + expect(c.context).toBe(fixture.componentInstance); + expect(c.references['local']).toBeDefined(); + })); } }); @@ -1636,8 +1636,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('Property bindings', () => { - fixmeIvy('FW-721: Bindings to unknown properties are not reported as errors') && - it('should throw on bindings to unknown properties', () => { + fixmeIvy('FW-721: Bindings to unknown properties are not reported as errors') + .it('should throw on bindings to unknown properties', () => { TestBed.configureTestingModule({declarations: [MyComp]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -1671,8 +1671,8 @@ function declareTests(config?: {useJit: boolean}) { expect(el.title).toBeFalsy(); }); - fixmeIvy('FW-711: elementProperty instruction should not be used in host bindings') && - it('should work when a directive uses hostProperty to update the DOM element', () => { + fixmeIvy('FW-711: elementProperty instruction should not be used in host bindings') + .it('should work when a directive uses hostProperty to update the DOM element', () => { TestBed.configureTestingModule( {declarations: [MyComp, DirectiveWithTitleAndHostProperty]}); const template = ''; @@ -1688,8 +1688,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('logging property updates', () => { - fixmeIvy('FW-664: ng-reflect-* is not supported') && - it('should reflect property values as attributes', () => { + fixmeIvy('FW-664: ng-reflect-* is not supported') + .it('should reflect property values as attributes', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); const template = '
' + '
' + @@ -1712,8 +1712,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-test_="hello"'); }); - fixmeIvy('FW-664: ng-reflect-* is not supported') && - it('should reflect property values on template comments', () => { + fixmeIvy('FW-664: ng-reflect-* is not supported') + .it('should reflect property values on template comments', () => { const fixture = TestBed.configureTestingModule({declarations: [MyComp]}) .overrideComponent( @@ -1729,8 +1729,8 @@ function declareTests(config?: {useJit: boolean}) { }); // 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', () => { + fixmeIvy('FW-664: ng-reflect-* is not supported') + .it('should indicate when toString() throws', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); diff --git a/packages/core/test/linker/jit_summaries_integration_spec.ts b/packages/core/test/linker/jit_summaries_integration_spec.ts index 2716bb8ed5..320f318cbe 100644 --- a/packages/core/test/linker/jit_summaries_integration_spec.ts +++ b/packages/core/test/linker/jit_summaries_integration_spec.ts @@ -138,8 +138,8 @@ import {fixmeIvy} from '@angular/private/testing'; afterEach(() => { resetTestEnvironmentWithSummaries(); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should use directive metadata from summaries', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should use directive metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); @Component({template: '
'}) @@ -153,8 +153,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeDirective); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should use pipe metadata from summaries', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should use pipe metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); @Component({template: '{{1 | somePipe}}'}) @@ -166,8 +166,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomePipe); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should use Service metadata from summaries', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should use Service metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.configureTestingModule({ @@ -177,8 +177,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeService); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should use NgModule metadata from summaries', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should use NgModule metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed @@ -192,8 +192,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeService); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should allow to create private components from imported NgModule summaries', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should allow to create private components from imported NgModule summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) @@ -201,8 +201,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomePrivateComponent); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should throw when trying to mock a type with a summary', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should throw when trying to mock a type with a summary', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.resetTestingModule(); @@ -221,35 +221,35 @@ import {fixmeIvy} from '@angular/private/testing'; .toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.'); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should return stack trace and component data on resetTestingModule when error is thrown', - () => { - resetTestEnvironmentWithSummaries(); + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should return stack trace and component data on resetTestingModule when error is thrown', + () => { + resetTestEnvironmentWithSummaries(); - const fixture = - TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]}) - .createComponent(TestCompErrorOnDestroy); + const fixture = + TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]}) + .createComponent(TestCompErrorOnDestroy); - const expectedError = 'Error from ngOnDestroy'; + const expectedError = 'Error from ngOnDestroy'; - const component: TestCompErrorOnDestroy = fixture.componentInstance; + const component: TestCompErrorOnDestroy = fixture.componentInstance; - spyOn(console, 'error'); - spyOn(component, 'ngOnDestroy').and.throwError(expectedError); + spyOn(console, 'error'); + spyOn(component, 'ngOnDestroy').and.throwError(expectedError); - const expectedObject = { - stacktrace: new Error(expectedError), - component, - }; + const expectedObject = { + stacktrace: new Error(expectedError), + component, + }; - TestBed.resetTestingModule(); + TestBed.resetTestingModule(); - expect(console.error) - .toHaveBeenCalledWith('Error during cleanup of component', expectedObject); - }); + expect(console.error) + .toHaveBeenCalledWith('Error during cleanup of component', expectedObject); + }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should allow to add summaries via configureTestingModule', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should allow to add summaries via configureTestingModule', () => { resetTestEnvironmentWithSummaries(); @Component({template: '
'}) @@ -266,8 +266,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeDirective); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should allow to override a provider', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should allow to override a provider', () => { resetTestEnvironmentWithSummaries(summaries); const overwrittenValue = {}; @@ -280,8 +280,8 @@ import {fixmeIvy} from '@angular/private/testing'; expect(fixture.componentInstance.dep).toBe(overwrittenValue); }); - fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && - it('should allow to override a template', () => { + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') + .it('should allow to override a template', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten'); diff --git a/packages/core/test/linker/ng_container_integration_spec.ts b/packages/core/test/linker/ng_container_integration_spec.ts index cebd470fc7..af516d6ed2 100644 --- a/packages/core/test/linker/ng_container_integration_spec.ts +++ b/packages/core/test/linker/ng_container_integration_spec.ts @@ -52,8 +52,8 @@ function declareTests(config?: {useJit: boolean}) { expect(el).toHaveText('foo'); }); - fixmeIvy('FW-678: ivy generates different DOM structure for ') && - it('should be rendered as comment with children as siblings', () => { + fixmeIvy('FW-678: ivy generates different DOM structure for ') + .it('should be rendered as comment with children as siblings', () => { const template = '

'; TestBed.overrideComponent(MyComp, {set: {template}}); const fixture = TestBed.createComponent(MyComp); @@ -67,8 +67,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P'); }); - fixmeIvy('FW-678: ivy generates different DOM structure for ') && - it('should support nesting', () => { + fixmeIvy('FW-678: ivy generates different DOM structure for ') + .it('should support nesting', () => { const template = '12'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -86,8 +86,8 @@ function declareTests(config?: {useJit: boolean}) { expect(children[4]).toHaveText('2'); }); - fixmeIvy('FW-678: ivy generates different DOM structure for ') && - it('should group inner nodes', () => { + fixmeIvy('FW-678: ivy generates different DOM structure for ') + .it('should group inner nodes', () => { const template = '

'; TestBed.overrideComponent(MyComp, {set: {template}}); const fixture = TestBed.createComponent(MyComp); @@ -136,8 +136,8 @@ function declareTests(config?: {useJit: boolean}) { expect(dir.text).toEqual('container'); }); - fixmeIvy('unknown') && - it('should contain all direct child directives in a (content dom)', () => { + fixmeIvy('unknown').it( + 'should contain all direct child directives in a (content dom)', () => { const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); diff --git a/packages/core/test/linker/ng_module_integration_spec.ts b/packages/core/test/linker/ng_module_integration_spec.ts index 9cc6feae82..2846d8286a 100644 --- a/packages/core/test/linker/ng_module_integration_spec.ts +++ b/packages/core/test/linker/ng_module_integration_spec.ts @@ -143,8 +143,8 @@ function declareTests(config?: {useJit: boolean}) { } describe('errors', () => { - fixmeIvy('FW-682: Compiler error handling') && - it('should error when exporting a directive that was neither declared nor imported', () => { + 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,8 +154,8 @@ 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', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should error when exporting a pipe that was neither declared nor imported', () => { @NgModule({exports: [SomePipe]}) class SomeModule { } @@ -165,8 +165,8 @@ 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', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should error if a directive is declared in more than 1 module', () => { @NgModule({declarations: [SomeDirective]}) class Module1 { } @@ -184,26 +184,26 @@ 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]}) - class Module1 { - } + 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]}) + class Module1 { + } - @NgModule({declarations: [SomeDirective], imports: [Module1]}) - class Module2 { - } + @NgModule({declarations: [SomeDirective], imports: [Module1]}) + class Module2 { + } - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${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)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${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', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should error if a pipe is declared in more than 1 module', () => { @NgModule({declarations: [SomePipe]}) class Module1 { } @@ -221,29 +221,29 @@ 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]}) - class Module1 { - } + 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]}) + class Module1 { + } - @NgModule({declarations: [SomePipe], imports: [Module1]}) - class Module2 { - } + @NgModule({declarations: [SomePipe], imports: [Module1]}) + class Module2 { + } - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${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)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${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', () => { - fixmeIvy('FW-682: Compiler error handling') && - it('should error on unknown bound properties on custom elements by default', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should error on unknown bound properties on custom elements by default', () => { @Component({template: ''}) class ComponentUsingInvalidProperty { } @@ -281,16 +281,16 @@ function declareTests(config?: {useJit: boolean}) { afterEach(() => clearModulesForTest()); - fixmeIvy('FW-740: missing global registry of NgModules by id') && - it('should register loaded modules', () => { + fixmeIvy('FW-740: missing global registry of NgModules by id') + .it('should register loaded modules', () => { createModule(SomeModule); const factory = getModuleFactory(token); expect(factory).toBeTruthy(); expect(factory.moduleType).toBe(SomeModule); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when registering a duplicate module', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when registering a duplicate module', () => { createModule(SomeModule); expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/); }); @@ -311,37 +311,37 @@ function declareTests(config?: {useJit: boolean}) { .toBe(SomeComp); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw if we cannot find a module associated with a module-level entryComponent', - () => { - @Component({template: ''}) - class SomeCompWithEntryComponents { - } + fixmeIvy('FW-682: Compiler error handling') + .it('should throw if we cannot find a module associated with a module-level entryComponent', + () => { + @Component({template: ''}) + class SomeCompWithEntryComponents { + } - @NgModule({declarations: [], entryComponents: [SomeCompWithEntryComponents]}) - class SomeModule { - } + @NgModule({declarations: [], entryComponents: [SomeCompWithEntryComponents]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); + }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw if we cannot find a module associated with a component-level entryComponent', - () => { - @Component({template: '', entryComponents: [SomeComp]}) - class SomeCompWithEntryComponents { - } + fixmeIvy('FW-682: Compiler error handling') + .it('should throw if we cannot find a module associated with a component-level entryComponent', + () => { + @Component({template: '', entryComponents: [SomeComp]}) + class SomeCompWithEntryComponents { + } - @NgModule({declarations: [SomeCompWithEntryComponents]}) - class SomeModule { - } + @NgModule({declarations: [SomeCompWithEntryComponents]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - 'Component SomeComp is not part of any NgModule or the module has not been imported into your module.'); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + 'Component SomeComp is not part of any NgModule or the module has not been imported into your module.'); + }); it('should create ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => { @NgModule({ @@ -426,8 +426,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('directives and pipes', () => { - fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && - describe('declarations', () => { + fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') + .describe('declarations', () => { it('should be supported in root modules', () => { @NgModule({ declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], @@ -489,8 +489,8 @@ function declareTests(config?: {useJit: boolean}) { describe('import/export', () => { - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should support exported directives and pipes', () => { + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') + .it('should support exported directives and pipes', () => { @NgModule( {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) class SomeImportedModule { @@ -511,31 +511,31 @@ function declareTests(config?: {useJit: boolean}) { .toBe('transformed someValue'); }); - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', - () => { - @NgModule( - {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) - class SomeImportedModule { - } + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') + .it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', + () => { + @NgModule( + {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [{ngModule: SomeImportedModule}], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [{ngModule: SomeImportedModule}], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should support reexported modules', () => { + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') + .it('should support reexported modules', () => { @NgModule( {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) class SomeReexportedModule { @@ -559,8 +559,8 @@ function declareTests(config?: {useJit: boolean}) { .toBe('transformed someValue'); }); - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should support exporting individual directives of an imported module', () => { + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') + .it('should support exporting individual directives of an imported module', () => { @NgModule( {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) class SomeReexportedModule { @@ -584,8 +584,8 @@ function declareTests(config?: {useJit: boolean}) { .toBe('transformed someValue'); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should not use non exported pipes of an imported module', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should not use non exported pipes of an imported module', () => { @NgModule({ declarations: [SomePipe], }) @@ -604,8 +604,8 @@ function declareTests(config?: {useJit: boolean}) { .toThrowError(/The pipe 'somePipe' could not be found/); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should not use non exported directives of an imported module', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should not use non exported directives of an imported module', () => { @NgModule({ declarations: [SomeDirective], }) @@ -667,14 +667,14 @@ function declareTests(config?: {useJit: boolean}) { expect(car.engine).toBeAnInstanceOf(TurboEngine); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when no type and not @Inject (class case)', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when no type and not @Inject (class case)', () => { expect(() => createInjector([NoAnnotations])) .toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).'); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when no type and not @Inject (factory case)', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when no type and not @Inject (factory case)', () => { expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) .toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); }); @@ -745,8 +745,8 @@ function declareTests(config?: {useJit: boolean}) { expect(cars[0]).toBe(injector.get(SportsCar)); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when the aliased provider does not exist', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when the aliased provider does not exist', () => { const injector = createInjector([{provide: 'car', useExisting: SportsCar}]); const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`; expect(() => injector.get('car')).toThrowError(e); @@ -796,14 +796,13 @@ function declareTests(config?: {useJit: boolean}) { expect(injector.get('token')).toEqual('value'); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when given invalid providers', () => { - expect(() => createInjector(['blah'])) - .toThrowError( - `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); - }); + fixmeIvy('FW-682: Compiler error handling').it('should throw when given invalid providers', () => { + expect(() => createInjector(['blah'])) + .toThrowError( + `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); + }); - fixmeIvy('FW-682: Compiler error handling') && it('should throw when given blank providers', () => { + fixmeIvy('FW-682: Compiler error handling').it('should throw when given blank providers', () => { expect(() => createInjector([null, {provide: 'token', useValue: 'value'}])) .toThrowError( `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`); @@ -949,8 +948,8 @@ function declareTests(config?: {useJit: boolean}) { .toThrowError('NullInjectorError: No provider for NonExisting!'); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when trying to instantiate a cyclic dependency', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when trying to instantiate a cyclic dependency', () => { expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) .toThrowError(/Cannot instantiate cyclic dependency! Car/g); }); @@ -1053,8 +1052,8 @@ function declareTests(config?: {useJit: boolean}) { expect(created).toBe(false); }); - fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') && - it('should support ngOnDestroy on any provider', () => { + fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') + .it('should support ngOnDestroy on any provider', () => { let destroyed = false; class SomeInjectable { @@ -1073,8 +1072,8 @@ function declareTests(config?: {useJit: boolean}) { expect(destroyed).toBe(true); }); - fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') && - it('should support ngOnDestroy for lazy providers', () => { + fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') + .it('should support ngOnDestroy for lazy providers', () => { let created = false; let destroyed = false; @@ -1318,8 +1317,8 @@ function declareTests(config?: {useJit: boolean}) { expect(injector.get('token1')).toBe('imported2'); }); - fixmeIvy('FW-682: Compiler error handling') && - it('should throw when given invalid providers in an imported ModuleWithProviders', () => { + fixmeIvy('FW-682: Compiler error handling') + .it('should throw when given invalid providers in an imported ModuleWithProviders', () => { @NgModule() class ImportedModule1 { } @@ -1335,8 +1334,8 @@ function declareTests(config?: {useJit: boolean}) { }); describe('tree shakable providers', () => { - fixmeIvy('FW-794: NgModuleDefinition not exposed on NgModuleData') && - it('definition should not persist across NgModuleRef instances', () => { + fixmeIvy('FW-794: NgModuleDefinition not exposed on NgModuleData') + .it('definition should not persist across NgModuleRef instances', () => { @NgModule() class SomeModule { } diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts index 796faf1ad2..ecaa9e2fe9 100644 --- a/packages/core/test/linker/projection_integration_spec.ts +++ b/packages/core/test/linker/projection_integration_spec.ts @@ -82,8 +82,8 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText(''); }); - fixmeIvy('FW-789: select attribute on should not be case-sensitive') && - it('should support multiple content tags', () => { + fixmeIvy('FW-789: select attribute on should not be case-sensitive') + .it('should support multiple content tags', () => { TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]}); TestBed.overrideComponent(MainComp, { set: { @@ -114,8 +114,8 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('(, BAC)'); }); - fixmeIvy('FW-665: Unable to find the given context data for the given target') && - it('should redistribute direct child viewcontainers when the light dom changes', () => { + fixmeIvy('FW-665: Unable to find the given context data for the given target') + .it('should redistribute direct child viewcontainers when the light dom changes', () => { TestBed.configureTestingModule( {declarations: [MultipleContentTagsComponent, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { @@ -158,8 +158,8 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))'); }); - fixmeIvy('FW-665: Unable to find the given context data for the given target') && - it('should support nesting with content being direct child of a nested component', () => { + fixmeIvy('FW-665: Unable to find the given context data for the given target') + .it('should support nesting with content being direct child of a nested component', () => { TestBed.configureTestingModule({ declarations: [InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective] @@ -186,8 +186,8 @@ import {fixmeIvy} from '@angular/private/testing'; }); fixmeIvy( - 'FW-745: Compiler isn\'t generating projectionDefs for tags inside ') && - it('should redistribute when the shadow dom changes', () => { + 'FW-745: Compiler isn\'t generating projectionDefs for tags inside ') + .it('should redistribute when the shadow dom changes', () => { TestBed.configureTestingModule( {declarations: [ConditionalContentComponent, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { @@ -295,8 +295,8 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('SIMPLE()START(A)END'); }); - fixmeIvy('FW-665: Unable to find the given context data for the given target') && - it('should support moving ng-content around', () => { + fixmeIvy('FW-665: Unable to find the given context data for the given target') + .it('should support moving ng-content around', () => { TestBed.configureTestingModule({ declarations: [ConditionalContentComponent, ProjectDirective, ManualViewportDirective] @@ -435,8 +435,8 @@ import {fixmeIvy} from '@angular/private/testing'; }); } - fixmeIvy('FW-665: Unable to find the given context data for the given target') && - it('should support nested conditionals that contain ng-contents', () => { + fixmeIvy('FW-665: Unable to find the given context data for the given target') + .it('should support nested conditionals that contain ng-contents', () => { TestBed.configureTestingModule( {declarations: [ConditionalTextComponent, ManualViewportDirective]}); TestBed.overrideComponent( @@ -482,8 +482,8 @@ import {fixmeIvy} from '@angular/private/testing'; }); fixmeIvy( - 'FW-745: Compiler isn\'t generating projectionDefs for tags inside ') && - it('should project filled view containers into a view container', () => { + 'FW-745: Compiler isn\'t generating projectionDefs for tags inside ') + .it('should project filled view containers into a view container', () => { TestBed.configureTestingModule( {declarations: [ConditionalContentComponent, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { diff --git a/packages/core/test/linker/query_integration_spec.ts b/packages/core/test/linker/query_integration_spec.ts index 9ac11cefdd..7168b4ce59 100644 --- a/packages/core/test/linker/query_integration_spec.ts +++ b/packages/core/test/linker/query_integration_spec.ts @@ -54,8 +54,8 @@ describe('Query API', () => { describe('querying by directive type', () => { fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should contain all direct child directives in the light dom (constructor)', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should contain all direct child directives in the light dom (constructor)', () => { const template = `
@@ -97,23 +97,23 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should contain the first content child when target is on with embedded view (issue #16568)', - () => { - const template = - '
' + - '
'; - const view = createTestCmp(MyComp0, template); - view.detectChanges(); - const q: NeedsContentChild = view.debugElement.children[1].references !['q']; - expect(q.child.text).toEqual('foo'); - const directive: DirectiveNeedsContentChild = - view.debugElement.children[0].injector.get(DirectiveNeedsContentChild); - expect(directive.child.text).toEqual('foo'); - }); + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should contain the first content child when target is on with embedded view (issue #16568)', + () => { + const template = + '
' + + '
'; + const view = createTestCmp(MyComp0, template); + view.detectChanges(); + const q: NeedsContentChild = view.debugElement.children[1].references !['q']; + expect(q.child.text).toEqual('foo'); + const directive: DirectiveNeedsContentChild = + view.debugElement.children[0].injector.get(DirectiveNeedsContentChild); + expect(directive.child.text).toEqual('foo'); + }); - fixmeIvy('FW-782 - View queries are executed twice in some cases') && - it('should contain the first view child', () => { + fixmeIvy('FW-782 - View queries are executed twice in some cases') + .it('should contain the first view child', () => { const template = ''; const view = createTestCmpAndDetectChanges(MyComp0, template); @@ -128,8 +128,8 @@ describe('Query API', () => { ]); }); - fixmeIvy('FW-782 - View queries are executed twice in some cases') && - it('should set static view and content children already after the constructor call', () => { + fixmeIvy('FW-782 - View queries are executed twice in some cases') + .it('should set static view and content children already after the constructor call', () => { const template = '
'; const view = createTestCmp(MyComp0, template); @@ -142,8 +142,8 @@ describe('Query API', () => { expect(q.viewChild.text).toEqual('viewFoo'); }); - fixmeIvy('FW-782 - View queries are executed twice in some cases') && - it('should contain the first view child across embedded views', () => { + fixmeIvy('FW-782 - View queries are executed twice in some cases') + .it('should contain the first view child across embedded views', () => { TestBed.overrideComponent( MyComp0, {set: {template: ''}}); TestBed.overrideComponent(NeedsViewChild, { @@ -172,8 +172,8 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should contain all directives in the light dom when descendants flag is used', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should contain all directives in the light dom when descendants flag is used', () => { const template = '
' + '
' + '
' + @@ -185,8 +185,8 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should contain all directives in the light dom', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should contain all directives in the light dom', () => { const template = '
' + '
' + '
'; @@ -196,8 +196,8 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should reflect dynamically inserted directives', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should reflect dynamically inserted directives', () => { const template = '
' + '
' + '
'; @@ -221,8 +221,8 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should reflect moved directives', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should reflect moved directives', () => { const template = '
' + '
' + '
'; @@ -234,8 +234,8 @@ describe('Query API', () => { expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|'); }); - fixmeIvy('FW-682 - TestBed: tests assert that compilation produces specific error') && - it('should throw with descriptive error when query selectors are not present', () => { + fixmeIvy('FW-682 - TestBed: tests assert that compilation produces specific error') + .it('should throw with descriptive error when query selectors are not present', () => { TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]}); const template = ''; TestBed.overrideComponent(MyCompBroken0, {set: {template}}); @@ -268,8 +268,8 @@ describe('Query API', () => { describe('read a different token', () => { modifiedInIvy( - 'Breaking change in Ivy: no longer allow multiple local refs with the same name, all local refs are now unique') && - it('should contain all content children', () => { + 'Breaking change in Ivy: no longer allow multiple local refs with the same name, all local refs are now unique') + .it('should contain all content children', () => { const template = '
'; const view = createTestCmpAndDetectChanges(MyComp0, template); @@ -477,17 +477,19 @@ describe('Query API', () => { describe('querying in the view', () => { fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should contain all the elements in the view with that have the given directive', () => { - const template = '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); - }); + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should contain all the elements in the view with that have the given directive', + () => { + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); + }); fixmeIvy( - 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && - it('should not include directive present on the host element', () => { + 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') + .it('should not include directive present on the host element', () => { const template = ''; const view = createTestCmpAndDetectChanges(MyComp0, template); const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; @@ -588,8 +590,8 @@ describe('Query API', () => { }); // Note: this test is just document our current behavior, which we do for performance reasons. - fixmeIvy('FW-782 - View queries are executed twice in some cases') && - it('should not affected queries for projected templates if views are detached or moved', () => { + fixmeIvy('FW-782 - View queries are executed twice in some cases') + .it('should not affected queries for projected templates if views are detached or moved', () => { const template = '
'; const view = createTestCmpAndDetectChanges(MyComp0, template); @@ -615,8 +617,8 @@ describe('Query API', () => { }); fixmeIvy( - 'FW-763 - LView tree not properly constructed / destroyed for dynamically inserted components') && - it('should remove manually projected templates if their parent view is destroyed', () => { + 'FW-763 - LView tree not properly constructed / destroyed for dynamically inserted components') + .it('should remove manually projected templates if their parent view is destroyed', () => { const template = `
@@ -635,34 +637,34 @@ describe('Query API', () => { expect(q.query.length).toBe(0); }); - fixmeIvy('unknown') && - it('should not throw if a content template is queried and created in the view during change detection', - () => { - @Component( - {selector: 'auto-projecting', template: '
'}) - class AutoProjecting { - // TODO(issue/24571): - // remove '!'. - @ContentChild(TemplateRef) - content !: TemplateRef; + fixmeIvy('unknown').it( + 'should not throw if a content template is queried and created in the view during change detection', + () => { + @Component( + {selector: 'auto-projecting', template: '
'}) + class AutoProjecting { + // TODO(issue/24571): + // remove '!'. + @ContentChild(TemplateRef) + content !: TemplateRef; - // TODO(issue/24571): - // remove '!'. - @ContentChildren(TextDirective) - query !: QueryList; - } + // TODO(issue/24571): + // remove '!'. + @ContentChildren(TextDirective) + query !: QueryList; + } - TestBed.configureTestingModule({declarations: [AutoProjecting]}); - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); + TestBed.configureTestingModule({declarations: [AutoProjecting]}); + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - // This should be 1, but due to - // https://github.com/angular/angular/issues/15117 - // this is 0. - expect(q.query.length).toBe(0); - }); + const q = view.debugElement.children[0].references !['q']; + // This should be 1, but due to + // https://github.com/angular/angular/issues/15117 + // this is 0. + expect(q.query.length).toBe(0); + }); }); }); diff --git a/packages/core/test/linker/regression_integration_spec.ts b/packages/core/test/linker/regression_integration_spec.ts index cb8dc1566e..9b36d734a5 100644 --- a/packages/core/test/linker/regression_integration_spec.ts +++ b/packages/core/test/linker/regression_integration_spec.ts @@ -32,7 +32,7 @@ function declareTests(config?: {useJit: boolean}) { describe('platform pipes', () => { beforeEach(() => { TestBed.configureCompiler({...config}); }); - fixmeIvy('unknown') && it('should overwrite them by custom pipes', () => { + fixmeIvy('unknown').it('should overwrite them by custom pipes', () => { TestBed.configureTestingModule({declarations: [CustomPipe]}); const template = '{{true | somePipe}}'; TestBed.overrideComponent(MyComp1, {set: {template}}); @@ -74,46 +74,46 @@ function declareTests(config?: {useJit: boolean}) { expect(CountingPipe.calls).toBe(1); }); - fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && - it('should only update the bound property when using asyncPipe - #15205', - fakeAsync(() => { - @Component({template: '
'}) - class MyComp { - p = Promise.resolve(1); - } + fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') + .it('should only update the bound property when using asyncPipe - #15205', + fakeAsync(() => { + @Component({template: '
'}) + class MyComp { + p = Promise.resolve(1); + } - @Directive({selector: '[myDir]'}) - class MyDir { - setterCalls: {[key: string]: any} = {}; - // TODO(issue/24571): remove '!'. - changes !: SimpleChanges; + @Directive({selector: '[myDir]'}) + class MyDir { + setterCalls: {[key: string]: any} = {}; + // TODO(issue/24571): remove '!'. + changes !: SimpleChanges; - @Input() - set a(v: number) { this.setterCalls['a'] = v; } - @Input() - set b(v: number) { this.setterCalls['b'] = v; } + @Input() + set a(v: number) { this.setterCalls['a'] = v; } + @Input() + set b(v: number) { this.setterCalls['b'] = v; } - ngOnChanges(changes: SimpleChanges) { this.changes = changes; } - } + ngOnChanges(changes: SimpleChanges) { this.changes = changes; } + } - TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); - const fixture = TestBed.createComponent(MyComp); - const dir = - fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir; + TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); + const fixture = TestBed.createComponent(MyComp); + const dir = + fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir; - fixture.detectChanges(); - expect(dir.setterCalls).toEqual({'a': null, 'b': 2}); - expect(Object.keys(dir.changes)).toEqual(['a', 'b']); + fixture.detectChanges(); + expect(dir.setterCalls).toEqual({'a': null, 'b': 2}); + expect(Object.keys(dir.changes)).toEqual(['a', 'b']); - dir.setterCalls = {}; - dir.changes = {}; + dir.setterCalls = {}; + dir.changes = {}; - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - expect(dir.setterCalls).toEqual({'a': 1}); - expect(Object.keys(dir.changes)).toEqual(['a']); - })); + expect(dir.setterCalls).toEqual({'a': 1}); + expect(Object.keys(dir.changes)).toEqual(['a']); + })); it('should only evaluate methods once - #10639', () => { TestBed.configureTestingModule({declarations: [MyCountingComp]}); @@ -333,8 +333,8 @@ function declareTests(config?: {useJit: boolean}) { expect(fixture.debugElement.childNodes.length).toBe(0); }); - modifiedInIvy('Comment node order changed') && - it('should allow empty embedded templates', () => { + modifiedInIvy('Comment node order changed') + .it('should allow empty embedded templates', () => { @Component({template: ''}) class MyComp { } @@ -351,37 +351,36 @@ function declareTests(config?: {useJit: boolean}) { }); }); - fixmeIvy('unknown') && - it('should support @ContentChild and @Input on the same property for static queries', - () => { - @Directive({selector: 'test'}) - class Test { - // TODO(issue/24571): remove '!'. - @Input() @ContentChild(TemplateRef) tpl !: TemplateRef; - } + fixmeIvy('unknown').it( + 'should support @ContentChild and @Input on the same property for static queries', () => { + @Directive({selector: 'test'}) + class Test { + // TODO(issue/24571): remove '!'. + @Input() @ContentChild(TemplateRef) tpl !: TemplateRef; + } - @Component({ - selector: 'my-app', - template: ` + @Component({ + selector: 'my-app', + template: `
Custom as a child
Custom as a binding
` - }) - class App { - } + }) + class App { + } - const fixture = - TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App); - fixture.detectChanges(); + const fixture = + TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App); + fixture.detectChanges(); - const testDirs = - fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test)); - expect(testDirs[0].tpl).toBeUndefined(); - expect(testDirs[1].tpl).toBeDefined(); - expect(testDirs[2].tpl).toBeDefined(); - }); + const testDirs = + fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test)); + expect(testDirs[0].tpl).toBeUndefined(); + expect(testDirs[1].tpl).toBeDefined(); + expect(testDirs[2].tpl).toBeDefined(); + }); it('should not add ng-version for dynamically created components', () => { @Component({template: ''}) diff --git a/packages/core/test/linker/security_integration_spec.ts b/packages/core/test/linker/security_integration_spec.ts index a58da1d5bd..2eb3957165 100644 --- a/packages/core/test/linker/security_integration_spec.ts +++ b/packages/core/test/linker/security_integration_spec.ts @@ -52,8 +52,8 @@ function declareTests(config?: {useJit: boolean}) { afterEach(() => { getDOM().log = originalLog; }); describe('events', () => { - fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && - it('should disallow binding to attr.on*', () => { + fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') + .it('should disallow binding to attr.on*', () => { const template = `
`; TestBed.overrideComponent(SecuredComponent, {set: {template}}); @@ -62,8 +62,8 @@ function declareTests(config?: {useJit: boolean}) { /Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../); }); - fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && - it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => { + fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') + .it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => { const template = `
`; TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ schemas: [NO_ERRORS_SCHEMA] @@ -75,8 +75,8 @@ function declareTests(config?: {useJit: boolean}) { }); fixmeIvy( - 'FW-786: Element properties and directive inputs are not distinguished for sanitisation purposes') && - it('should disallow binding to on* unless it is consumed by a directive', () => { + 'FW-786: Element properties and directive inputs are not distinguished for sanitisation purposes') + .it('should disallow binding to on* unless it is consumed by a directive', () => { const template = `
`; TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ schemas: [NO_ERRORS_SCHEMA] @@ -173,8 +173,8 @@ function declareTests(config?: {useJit: boolean}) { checkEscapeOfHrefProperty(fixture, true); }); - fixmeIvy('FW-785: Host bindings are not sanitised') && - it('should escape unsafe properties if they are used in host bindings', () => { + fixmeIvy('FW-785: Host bindings are not sanitised') + .it('should escape unsafe properties if they are used in host bindings', () => { @Directive({selector: '[dirHref]'}) class HrefDirective { // TODO(issue/24571): remove '!'. @@ -190,8 +190,8 @@ function declareTests(config?: {useJit: boolean}) { checkEscapeOfHrefProperty(fixture, false); }); - fixmeIvy('FW-785: Host bindings are not sanitised') && - it('should escape unsafe attributes if they are used in host bindings', () => { + fixmeIvy('FW-785: Host bindings are not sanitised') + .it('should escape unsafe attributes if they are used in host bindings', () => { @Directive({selector: '[dirHref]'}) class HrefDirective { // TODO(issue/24571): remove '!'. @@ -227,8 +227,8 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().getStyle(e, 'background')).not.toContain('javascript'); }); - fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && - it('should escape unsafe SVG attributes', () => { + fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') + .it('should escape unsafe SVG attributes', () => { const template = `Text`; TestBed.overrideComponent(SecuredComponent, {set: {template}}); diff --git a/packages/core/test/linker/source_map_integration_node_only_spec.ts b/packages/core/test/linker/source_map_integration_node_only_spec.ts index 6192a08fb7..863f68fc73 100644 --- a/packages/core/test/linker/source_map_integration_node_only_spec.ts +++ b/packages/core/test/linker/source_map_integration_node_only_spec.ts @@ -102,167 +102,167 @@ import {fixmeIvy} from '@angular/private/testing'; function declareTests( {ngUrl, templateDecorator}: {ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) { - fixmeIvy('unknown') && - it('should use the right source url in html parse errors', fakeAsync(() => { - @Component({...templateDecorator('
\n ')}) - class MyComp { - } + fixmeIvy('unknown').it( + 'should use the right source url in html parse errors', fakeAsync(() => { + @Component({...templateDecorator('
\n ')}) + class MyComp { + } - expect(() => compileAndCreateComponent(MyComp)) - .toThrowError(new RegExp( - `Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`)); - })); + expect(() => compileAndCreateComponent(MyComp)) + .toThrowError( + new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`)); + })); - fixmeIvy('unknown') && - it('should use the right source url in template parse errors', fakeAsync(() => { - @Component({...templateDecorator('
\n
')}) - class MyComp { - } + fixmeIvy('unknown').it( + 'should use the right source url in template parse errors', fakeAsync(() => { + @Component({...templateDecorator('
\n
')}) + class MyComp { + } - expect(() => compileAndCreateComponent(MyComp)) - .toThrowError(new RegExp( - `Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`)); - })); + expect(() => compileAndCreateComponent(MyComp)) + .toThrowError( + new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`)); + })); - fixmeIvy('unknown') && it('should create a sourceMap for templates', fakeAsync(() => { - const template = `Hello World!`; + fixmeIvy('unknown').it('should create a sourceMap for templates', fakeAsync(() => { + const template = `Hello World!`; - @Component({...templateDecorator(template)}) - class MyComp { - } + @Component({...templateDecorator(template)}) + class MyComp { + } - compileAndCreateComponent(MyComp); + compileAndCreateComponent(MyComp); - const sourceMap = - getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js'); - expect(sourceMap.sources).toEqual([ - 'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl - ]); - expect(sourceMap.sourcesContent).toEqual([' ', template]); - })); + const sourceMap = + getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js'); + expect(sourceMap.sources).toEqual([ + 'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl + ]); + expect(sourceMap.sourcesContent).toEqual([' ', template]); + })); - fixmeIvy('unknown') && - it('should report source location for di errors', fakeAsync(() => { - const template = `
\n
`; + fixmeIvy('unknown').it( + 'should report source location for di errors', fakeAsync(() => { + const template = `
\n
`; - @Component({...templateDecorator(template)}) - class MyComp { - } + @Component({...templateDecorator(template)}) + class MyComp { + } - @Directive({selector: '[someDir]'}) - class SomeDir { - constructor() { throw new Error('Test'); } - } + @Directive({selector: '[someDir]'}) + class SomeDir { + constructor() { throw new Error('Test'); } + } - TestBed.configureTestingModule({declarations: [SomeDir]}); - let error: any; - try { - compileAndCreateComponent(MyComp); - } catch (e) { - error = e; - } - // The error should be logged from the element - expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ - line: 2, - column: 4, - source: ngUrl, - }); - })); + TestBed.configureTestingModule({declarations: [SomeDir]}); + let error: any; + try { + compileAndCreateComponent(MyComp); + } catch (e) { + error = e; + } + // The error should be logged from the element + expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ + line: 2, + column: 4, + source: ngUrl, + }); + })); - fixmeIvy('unknown') && - it('should report di errors with multiple elements and directives', fakeAsync(() => { - const template = `
`; + fixmeIvy('unknown').it( + 'should report di errors with multiple elements and directives', fakeAsync(() => { + const template = `
`; - @Component({...templateDecorator(template)}) - class MyComp { - } + @Component({...templateDecorator(template)}) + class MyComp { + } - @Directive({selector: '[someDir]'}) - class SomeDir { - constructor(@Attribute('someDir') someDir: string) { - if (someDir === 'throw') { - throw new Error('Test'); - } - } - } + @Directive({selector: '[someDir]'}) + class SomeDir { + constructor(@Attribute('someDir') someDir: string) { + if (someDir === 'throw') { + throw new Error('Test'); + } + } + } - TestBed.configureTestingModule({declarations: [SomeDir]}); - let error: any; - try { - compileAndCreateComponent(MyComp); - } catch (e) { - error = e; - } - // The error should be logged from the 2nd-element - expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ - line: 1, - column: 19, - source: ngUrl, - }); - })); + TestBed.configureTestingModule({declarations: [SomeDir]}); + let error: any; + try { + compileAndCreateComponent(MyComp); + } catch (e) { + error = e; + } + // The error should be logged from the 2nd-element + expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ + line: 1, + column: 19, + source: ngUrl, + }); + })); - fixmeIvy('unknown') && - it('should report source location for binding errors', fakeAsync(() => { - const template = `
\n
`; + fixmeIvy('unknown').it( + 'should report source location for binding errors', fakeAsync(() => { + const template = `
\n
`; - @Component({...templateDecorator(template)}) - class MyComp { - createError() { throw new Error('Test'); } - } + @Component({...templateDecorator(template)}) + class MyComp { + createError() { throw new Error('Test'); } + } - const comp = compileAndCreateComponent(MyComp); + const comp = compileAndCreateComponent(MyComp); - let error: any; - try { - comp.detectChanges(); - } catch (e) { - error = e; - } - // the stack should point to the binding - expect(getSourcePositionForStack(error.stack)).toEqual({ - line: 2, - column: 12, - source: ngUrl, - }); - // The error should be logged from the element - expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ - line: 2, - column: 4, - source: ngUrl, - }); - })); + let error: any; + try { + comp.detectChanges(); + } catch (e) { + error = e; + } + // the stack should point to the binding + expect(getSourcePositionForStack(error.stack)).toEqual({ + line: 2, + column: 12, + source: ngUrl, + }); + // The error should be logged from the element + expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ + line: 2, + column: 4, + source: ngUrl, + }); + })); - fixmeIvy('unknown') && - it('should report source location for event errors', fakeAsync(() => { - const template = `
\n
`; + fixmeIvy('unknown').it( + 'should report source location for event errors', fakeAsync(() => { + const template = `
\n
`; - @Component({...templateDecorator(template)}) - class MyComp { - createError() { throw new Error('Test'); } - } + @Component({...templateDecorator(template)}) + class MyComp { + createError() { throw new Error('Test'); } + } - const comp = compileAndCreateComponent(MyComp); + const comp = compileAndCreateComponent(MyComp); - let error: any; - const errorHandler = TestBed.get(ErrorHandler); - spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e); - comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT'); - expect(error).toBeTruthy(); - // the stack should point to the binding - expect(getSourcePositionForStack(error.stack)).toEqual({ - line: 2, - column: 12, - source: ngUrl, - }); - // The error should be logged from the element - expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ - line: 2, - column: 4, - source: ngUrl, - }); + let error: any; + const errorHandler = TestBed.get(ErrorHandler); + spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e); + comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT'); + expect(error).toBeTruthy(); + // the stack should point to the binding + expect(getSourcePositionForStack(error.stack)).toEqual({ + line: 2, + column: 12, + source: ngUrl, + }); + // The error should be logged from the element + expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({ + line: 2, + column: 4, + source: ngUrl, + }); - })); + })); } }); } diff --git a/packages/core/test/view/provider_spec.ts b/packages/core/test/view/provider_spec.ts index 62b37a77e9..95fe2d790c 100644 --- a/packages/core/test/view/provider_spec.ts +++ b/packages/core/test/view/provider_spec.ts @@ -138,7 +138,7 @@ import {fixmeIvy} from '@angular/private/testing'; expect(instance.dep instanceof Dep).toBeTruthy(); }); - fixmeIvy('unknown') && it('should not inject deps from sibling root elements', () => { + fixmeIvy('unknown').it('should not inject deps from sibling root elements', () => { const rootElNodes = [ elementDef(0, NodeFlags.None, null, null, 1, 'span'), directiveDef(1, NodeFlags.None, null, 0, Dep, []), @@ -181,7 +181,7 @@ import {fixmeIvy} from '@angular/private/testing'; expect(instance.dep instanceof Dep).toBeTruthy(); }); - fixmeIvy('unknown') && it('should throw for missing dependencies', () => { + fixmeIvy('unknown').it('should throw for missing dependencies', () => { expect(() => createAndGetRootNodes(compViewDef([ elementDef(0, NodeFlags.None, null, null, 1, 'span'), directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep']) diff --git a/packages/platform-browser/test/browser/bootstrap_spec.ts b/packages/platform-browser/test/browser/bootstrap_spec.ts index 56f7ec5356..073270b8f5 100644 --- a/packages/platform-browser/test/browser/bootstrap_spec.ts +++ b/packages/platform-browser/test/browser/bootstrap_spec.ts @@ -160,7 +160,8 @@ function bootstrap( afterEach(destroyPlatform); - fixmeIvy('FW-553: TestBed is unaware of async compilation') && + // TODO(misko): can't use `fixmeIvy.it` because the `it` is somehow special here. + fixmeIvy('FW-553: TestBed is unaware of async compilation').isEnabled && it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (done: AsyncTestCompleter) => { const logger = new MockConsole(); @@ -188,7 +189,8 @@ function bootstrap( }); })); - fixmeIvy('FW-553: TestBed is unaware of async compilation') && + // TODO(misko): can't use `fixmeIvy.it` because the `it` is somehow special here. + fixmeIvy('FW-553: TestBed is unaware of async compilation').isEnabled && it('should throw if no provider', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { const logger = new MockConsole(); diff --git a/packages/platform-browser/test/testing_public_spec.ts b/packages/platform-browser/test/testing_public_spec.ts index 3546181837..12445154f3 100644 --- a/packages/platform-browser/test/testing_public_spec.ts +++ b/packages/platform-browser/test/testing_public_spec.ts @@ -251,8 +251,8 @@ class CompWithUrlTemplate { expect(compFixture.componentInstance).toBeAnInstanceOf(CompUsingModuleDirectiveAndPipe); }); - fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && - it('should use set up directives and pipes', () => { + fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') + .it('should use set up directives and pipes', () => { const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe); const el = compFixture.debugElement; @@ -289,14 +289,14 @@ class CompWithUrlTemplate { expect(service.value).toEqual('real value'); })); - fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && - it('should use set up directives and pipes', withModule(moduleConfig, () => { - const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe); - const el = compFixture.debugElement; + fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') + .it('should use set up directives and pipes', withModule(moduleConfig, () => { + const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe); + const el = compFixture.debugElement; - compFixture.detectChanges(); - expect(el.children[0].properties['title']).toBe('transformed someValue'); - })); + compFixture.detectChanges(); + expect(el.children[0].properties['title']).toBe('transformed someValue'); + })); it('should use set up library modules', withModule(moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => { @@ -310,12 +310,13 @@ class CompWithUrlTemplate { TestBed.compileComponents(); })); - fixmeIvy('FW-553: TestBed is unaware of async compilation') && isBrowser && - it('should allow to createSync components with templateUrl after explicit async compilation', - () => { - const fixture = TestBed.createComponent(CompWithUrlTemplate); - expect(fixture.nativeElement).toHaveText('from external template'); - }); + isBrowser && + fixmeIvy('FW-553: TestBed is unaware of async compilation') + .it('should allow to createSync components with templateUrl after explicit async compilation', + () => { + const fixture = TestBed.createComponent(CompWithUrlTemplate); + expect(fixture.nativeElement).toHaveText('from external template'); + }); }); describe('overwriting metadata', () => { @@ -371,8 +372,8 @@ class CompWithUrlTemplate { .overrideDirective( SomeDirective, {set: {selector: '[someDir]', host: {'[title]': 'someProp'}}}); }); - fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && - it('should work', () => { + fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') + .it('should work', () => { const compFixture = TestBed.createComponent(SomeComponent); compFixture.detectChanges(); expect(compFixture.debugElement.children[0].properties['title']).toEqual('hello'); @@ -387,8 +388,8 @@ class CompWithUrlTemplate { .overridePipe(SomePipe, {set: {name: 'somePipe'}}) .overridePipe(SomePipe, {add: {pure: false}}); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should work', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should work', () => { const compFixture = TestBed.createComponent(SomeComponent); compFixture.detectChanges(); expect(compFixture.nativeElement).toHaveText('transformed hello'); @@ -458,8 +459,8 @@ class CompWithUrlTemplate { expect(TestBed.get('a')).toBe('mockA: depValue'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support SkipSelf', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support SkipSelf', () => { @NgModule({ providers: [ {provide: 'a', useValue: 'aValue'}, @@ -501,8 +502,8 @@ class CompWithUrlTemplate { expect(someModule).toBeAnInstanceOf(SomeModule); }); - obsoleteInIvy(`deprecated method, won't be reimplemented for Render3`) && - it('should keep imported NgModules lazy with deprecatedOverrideProvider', () => { + obsoleteInIvy(`deprecated method, won't be reimplemented for Render3`) + .it('should keep imported NgModules lazy with deprecatedOverrideProvider', () => { let someModule: SomeModule|undefined; @NgModule() @@ -553,8 +554,8 @@ class CompWithUrlTemplate { }); describe('in Components', () => { - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support useValue', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support useValue', () => { @Component({ template: '', providers: [ @@ -571,8 +572,8 @@ class CompWithUrlTemplate { expect(ctx.debugElement.injector.get('a')).toBe('mockValue'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support useFactory', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support useFactory', () => { @Component({ template: '', providers: [ @@ -591,8 +592,8 @@ class CompWithUrlTemplate { expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support @Optional without matches', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support @Optional without matches', () => { @Component({ template: '', providers: [ @@ -611,8 +612,8 @@ class CompWithUrlTemplate { expect(ctx.debugElement.injector.get('a')).toBe('mockA: null'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support Optional with matches', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support Optional with matches', () => { @Component({ template: '', providers: [ @@ -632,8 +633,8 @@ class CompWithUrlTemplate { expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support SkipSelf', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support SkipSelf', () => { @Directive({ selector: '[myDir]', providers: [ @@ -662,8 +663,8 @@ class CompWithUrlTemplate { .toBe('mockA: parentDepValue'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should support multiple providers in a template', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should support multiple providers in a template', () => { @Directive({ selector: '[myDir1]', providers: [ @@ -708,9 +709,8 @@ class CompWithUrlTemplate { constructor(@Inject('a') a: any, @Inject('b') b: any) {} } - fixmeIvy( - 'FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should inject providers that were declared before it', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should inject providers that were declared before it', () => { TestBed.overrideProvider( 'b', {useFactory: (a: string) => `mockB: ${a}`, deps: ['a']}); const ctx = TestBed.configureTestingModule({declarations: [MyComp]}) @@ -719,9 +719,8 @@ class CompWithUrlTemplate { expect(ctx.debugElement.injector.get('b')).toBe('mockB: aValue'); }); - fixmeIvy( - 'FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should inject providers that were declared after it', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should inject providers that were declared after it', () => { TestBed.overrideProvider( 'a', {useFactory: (b: string) => `mockA: ${b}`, deps: ['b']}); const ctx = TestBed.configureTestingModule({declarations: [MyComp]}) @@ -741,8 +740,8 @@ class CompWithUrlTemplate { }); describe('overrideTemplateUsingTestingModule', () => { - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should compile the template in the context of the testing module', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should compile the template in the context of the testing module', () => { @Component({selector: 'comp', template: 'a'}) class MyComponent { prop = 'some prop'; @@ -770,8 +769,8 @@ class CompWithUrlTemplate { expect(testDir !.test).toBe('some prop'); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should throw if the TestBed is already created', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should throw if the TestBed is already created', () => { @Component({selector: 'comp', template: 'a'}) class MyComponent { } @@ -783,8 +782,8 @@ class CompWithUrlTemplate { /Cannot override template when the test module has already been instantiated/); }); - fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && - it('should reset overrides when the testing module is resetted', () => { + fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') + .it('should reset overrides when the testing module is resetted', () => { @Component({selector: 'comp', template: 'a'}) class MyComponent { } @@ -809,30 +808,30 @@ class CompWithUrlTemplate { {providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]}); }); - fixmeIvy('FW-553: TestBed is unaware of async compilation') && - it('should use set up providers', fakeAsync(() => { - TestBed.compileComponents(); - tick(); - const compFixture = TestBed.createComponent(CompWithUrlTemplate); - expect(compFixture.nativeElement).toHaveText('Hello world!'); - })); + fixmeIvy('FW-553: TestBed is unaware of async compilation') + .it('should use set up providers', fakeAsync(() => { + TestBed.compileComponents(); + tick(); + const compFixture = TestBed.createComponent(CompWithUrlTemplate); + expect(compFixture.nativeElement).toHaveText('Hello world!'); + })); }); describe('useJit true', () => { beforeEach(() => TestBed.configureCompiler({useJit: true})); - obsoleteInIvy('the Render3 compiler JiT mode is not configurable') && - it('should set the value into CompilerConfig', - inject([CompilerConfig], (config: CompilerConfig) => { - expect(config.useJit).toBe(true); - })); + obsoleteInIvy('the Render3 compiler JiT mode is not configurable') + .it('should set the value into CompilerConfig', + inject([CompilerConfig], (config: CompilerConfig) => { + expect(config.useJit).toBe(true); + })); }); describe('useJit false', () => { beforeEach(() => TestBed.configureCompiler({useJit: false})); - obsoleteInIvy('the Render3 compiler JiT mode is not configurable') && - it('should set the value into CompilerConfig', - inject([CompilerConfig], (config: CompilerConfig) => { - expect(config.useJit).toBe(false); - })); + obsoleteInIvy('the Render3 compiler JiT mode is not configurable') + .it('should set the value into CompilerConfig', + inject([CompilerConfig], (config: CompilerConfig) => { + expect(config.useJit).toBe(false); + })); }); }); }); @@ -921,28 +920,28 @@ class CompWithUrlTemplate { {providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]}); }); - fixmeIvy('FW-553: TestBed is unaware of async compilation') && - it('should report an error for declared components with templateUrl which never call TestBed.compileComponents', - () => { - const itPromise = patchJasmineIt(); + fixmeIvy('FW-553: TestBed is unaware of async compilation') + .it('should report an error for declared components with templateUrl which never call TestBed.compileComponents', + () => { + const itPromise = patchJasmineIt(); - expect( - () => - it('should fail', withModule( - {declarations: [CompWithUrlTemplate]}, - () => TestBed.createComponent(CompWithUrlTemplate)))) - .toThrowError( - `This test module uses the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl" or "styleUrls", but they were never compiled. ` + - `Please call "TestBed.compileComponents" before your test.`); + expect( + () => it( + 'should fail', withModule( + {declarations: [CompWithUrlTemplate]}, + () => TestBed.createComponent(CompWithUrlTemplate)))) + .toThrowError( + `This test module uses the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl" or "styleUrls", but they were never compiled. ` + + `Please call "TestBed.compileComponents" before your test.`); - restoreJasmineIt(); - }); + restoreJasmineIt(); + }); }); - fixmeIvy(`FW-721: Bindings to unknown properties are not reported as errors`) && - it('should error on unknown bound properties on custom elements by default', () => { + fixmeIvy(`FW-721: Bindings to unknown properties are not reported as errors`) + .it('should error on unknown bound properties on custom elements by default', () => { @Component({template: ''}) class ComponentUsingInvalidProperty { } diff --git a/packages/platform-server/test/integration_spec.ts b/packages/platform-server/test/integration_spec.ts index 17d83515a7..ffe69f593a 100644 --- a/packages/platform-server/test/integration_spec.ts +++ b/packages/platform-server/test/integration_spec.ts @@ -579,28 +579,28 @@ class HiddenModule { }); }))); - fixmeIvy('FW-672: SVG xlink:href is sanitized to :xlink:href (extra ":")') && - it('works with SVG elements', async(() => { - renderModule(SVGServerModule, {document: doc}).then(output => { - expect(output).toBe( - '' + - ''); - called = true; - }); - })); + fixmeIvy('FW-672: SVG xlink:href is sanitized to :xlink:href (extra ":")') + .it('works with SVG elements', async(() => { + renderModule(SVGServerModule, {document: doc}).then(output => { + expect(output).toBe( + '' + + ''); + called = true; + }); + })); fixmeIvy( - `FW-643: Components with animations throw with "Failed to execute 'setAttribute' on 'Element'`) && - it('works with animation', async(() => { - renderModule(AnimationServerModule, {document: doc}).then(output => { - expect(output).toContain('Works!'); - expect(output).toContain('ng-trigger-myAnimation'); - expect(output).toContain('opacity:1;'); - expect(output).toContain('transform:translate3d(0 , 0 , 0);'); - expect(output).toContain('font-weight:bold;'); - called = true; - }); - })); + `FW-643: Components with animations throw with "Failed to execute 'setAttribute' on 'Element'`) + .it('works with animation', async(() => { + renderModule(AnimationServerModule, {document: doc}).then(output => { + expect(output).toContain('Works!'); + expect(output).toContain('ng-trigger-myAnimation'); + expect(output).toContain('opacity:1;'); + expect(output).toContain('transform:translate3d(0 , 0 , 0);'); + expect(output).toContain('font-weight:bold;'); + called = true; + }); + })); it('should handle ViewEncapsulation.Native', async(() => { renderModule(NativeExampleModule, {document: doc}).then(output => { diff --git a/packages/platform-webworker/test/web_workers/worker/renderer_v2_integration_spec.ts b/packages/platform-webworker/test/web_workers/worker/renderer_v2_integration_spec.ts index 54460a63e7..e2afac213a 100644 --- a/packages/platform-webworker/test/web_workers/worker/renderer_v2_integration_spec.ts +++ b/packages/platform-webworker/test/web_workers/worker/renderer_v2_integration_spec.ts @@ -95,44 +95,44 @@ let lastCreatedRenderer: Renderer2; expect(renderEl).toHaveText('Hello World!'); }); - fixmeIvy('#FW-750 - fixture.debugElement is null') && - it('should update any element property/attributes/class/style(s) independent of the compilation on the root element and other elements', - () => { - const fixture = - TestBed.overrideTemplate(MyComp2, '') - .createComponent(MyComp2); + fixmeIvy('#FW-750 - fixture.debugElement is null') + .it('should update any element property/attributes/class/style(s) independent of the compilation on the root element and other elements', + () => { + const fixture = + TestBed.overrideTemplate(MyComp2, '') + .createComponent(MyComp2); - const checkSetters = (componentRef: ComponentRef, workerEl: any) => { - expect(lastCreatedRenderer).not.toBeNull(); + const checkSetters = (componentRef: ComponentRef, workerEl: any) => { + expect(lastCreatedRenderer).not.toBeNull(); - const el = getRenderElement(workerEl); - lastCreatedRenderer.setProperty(workerEl, 'tabIndex', 1); - expect(el.tabIndex).toEqual(1); + const el = getRenderElement(workerEl); + lastCreatedRenderer.setProperty(workerEl, 'tabIndex', 1); + expect(el.tabIndex).toEqual(1); - lastCreatedRenderer.addClass(workerEl, 'a'); - expect(getDOM().hasClass(el, 'a')).toBe(true); + lastCreatedRenderer.addClass(workerEl, 'a'); + expect(getDOM().hasClass(el, 'a')).toBe(true); - lastCreatedRenderer.removeClass(workerEl, 'a'); - expect(getDOM().hasClass(el, 'a')).toBe(false); + lastCreatedRenderer.removeClass(workerEl, 'a'); + expect(getDOM().hasClass(el, 'a')).toBe(false); - lastCreatedRenderer.setStyle(workerEl, 'width', '10px'); - expect(getDOM().getStyle(el, 'width')).toEqual('10px'); + lastCreatedRenderer.setStyle(workerEl, 'width', '10px'); + expect(getDOM().getStyle(el, 'width')).toEqual('10px'); - lastCreatedRenderer.removeStyle(workerEl, 'width'); - expect(getDOM().getStyle(el, 'width')).toEqual(''); + lastCreatedRenderer.removeStyle(workerEl, 'width'); + expect(getDOM().getStyle(el, 'width')).toEqual(''); - lastCreatedRenderer.setAttribute(workerEl, 'someattr', 'someValue'); - expect(getDOM().getAttribute(el, 'someattr')).toEqual('someValue'); - }; + lastCreatedRenderer.setAttribute(workerEl, 'someattr', 'someValue'); + expect(getDOM().getAttribute(el, 'someattr')).toEqual('someValue'); + }; - // root element - checkSetters(fixture.componentRef, fixture.nativeElement); - // nested elements - checkSetters(fixture.componentRef, fixture.debugElement.children[0].nativeElement); - }); + // root element + checkSetters(fixture.componentRef, fixture.nativeElement); + // nested elements + checkSetters(fixture.componentRef, fixture.debugElement.children[0].nativeElement); + }); - fixmeIvy('#FW-664 ng-reflect-* is not supported') && - it('should update any template comment property/attributes', () => { + fixmeIvy('#FW-664 ng-reflect-* is not supported') + .it('should update any template comment property/attributes', () => { const fixture = TestBed.overrideTemplate(MyComp2, '') .createComponent(MyComp2); @@ -161,7 +161,7 @@ let lastCreatedRenderer: Renderer2; }); if (getDOM().supportsDOMEvents()) { - fixmeIvy('#FW-750 - fixture.debugElement is null') && it('should listen to events', () => { + fixmeIvy('#FW-750 - fixture.debugElement is null').it('should listen to events', () => { const fixture = TestBed.overrideTemplate(MyComp2, '') .createComponent(MyComp2); diff --git a/packages/private/testing/src/ivy_test_selectors.ts b/packages/private/testing/src/ivy_test_selectors.ts index 622d6cf589..03b2756ab5 100644 --- a/packages/private/testing/src/ivy_test_selectors.ts +++ b/packages/private/testing/src/ivy_test_selectors.ts @@ -8,6 +8,14 @@ import {bazelDefineCompileValue} from './bazel_define_compile_value'; +/** + * Set this constant to `true` to run all tests and report which of the tests marked with `fixmeIvy` + * are actually already passing. + * + * This is useful for locating already passing tests. The already passing tests should have their + * `fixmeIvy` removed. + */ +const FIND_PASSING_TESTS = false; /** * A function to conditionally include a test or a block of tests only when tests run against Ivy. @@ -33,17 +41,21 @@ export const ivyEnabled = 'aot' === (bazelDefineCompileValue as string); * when running against Ivy. * * ``` - * fixmeIvy('some reason') && describe(...); + * fixmeIvy('some reason').describe(...); * ``` * * or * * ``` - * fixmeIvy('some reason') && it(...); + * fixmeIvy('some reason').it(...); * ``` */ -export function fixmeIvy(reason: string): boolean { - return !ivyEnabled; +export function fixmeIvy(reason: string): JasmineMethods { + if (FIND_PASSING_TESTS) { + return ivyEnabled ? PASSTHROUGH : IGNORE; + } else { + return ivyEnabled ? IGNORE : PASSTHROUGH; + } } @@ -54,17 +66,17 @@ export function fixmeIvy(reason: string): boolean { * Any tests disabled using this switch should not be user-facing breaking changes. * * ``` - * obsoleteInIvy('some reason') && describe(...); + * obsoleteInIvy('some reason').describe(...); * ``` * * or * * ``` - * obsoleteInIvy('some reason') && it(...); + * obsoleteInIvy('some reason').it(...); * ``` */ -export function obsoleteInIvy(reason: string): boolean { - return !ivyEnabled; +export function obsoleteInIvy(reason: string): JasmineMethods { + return ivyEnabled ? IGNORE : PASSTHROUGH; } /** @@ -75,15 +87,87 @@ export function obsoleteInIvy(reason: string): boolean { * documented as a breaking change. * * ``` - * modifiedInIvy('some reason') && describe(...); + * modifiedInIvy('some reason').describe(...); * ``` * * or * * ``` - * modifiedInIvy('some reason') && it(...); + * modifiedInIvy('some reason').it(...); * ``` */ -export function modifiedInIvy(reason: string): boolean { - return !ivyEnabled; +export function modifiedInIvy(reason: string): JasmineMethods { + return ivyEnabled ? IGNORE : PASSTHROUGH; +} + +export interface JasmineMethods { + it: typeof it; + fit: typeof fit; + describe: typeof describe; + fdescribe: typeof fdescribe; + fixmeIvy: typeof fixmeIvy; + isEnabled: boolean; +} + +const PASSTHROUGH: JasmineMethods = { + it: maybeAppendFindPassingTestsMarker(it), + fit: maybeAppendFindPassingTestsMarker(fit), + describe: maybeAppendFindPassingTestsMarker(describe), + fdescribe: maybeAppendFindPassingTestsMarker(fdescribe), + fixmeIvy: maybeAppendFindPassingTestsMarker(fixmeIvy), + isEnabled: true, +}; + +const FIND_PASSING_TESTS_MARKER = '__FIND_PASSING_TESTS_MARKER__'; +function maybeAppendFindPassingTestsMarker(fn: T): T { + return FIND_PASSING_TESTS ? function(...args: any[]) { + if (typeof args[0] == 'string') { + args[0] += FIND_PASSING_TESTS_MARKER; + } + return fn.apply(this, args); + } : fn as any; +} + +function noop() {} + +const IGNORE: JasmineMethods = { + it: noop, + fit: noop, + describe: noop, + fdescribe: noop, + fixmeIvy: (reason) => IGNORE, + isEnabled: false, +}; + +if (FIND_PASSING_TESTS) { + const env = jasmine.getEnv(); + const passingTests: jasmine.CustomReporterResult[] = []; + const stillFailing: jasmine.CustomReporterResult[] = []; + let specCount = 0; + env.clearReporters(); + env.addReporter({ + specDone: function(result: jasmine.CustomReporterResult) { + specCount++; + if (result.fullName.indexOf(FIND_PASSING_TESTS_MARKER) != -1) { + (result.status == 'passed' ? passingTests : stillFailing).push(result); + } + }, + jasmineDone: function(details: jasmine.RunDetails) { + if (passingTests.length) { + passingTests.forEach((result) => { + // tslint:disable-next-line:no-console + console.log('ALREADY PASSING', result.fullName.replace(FIND_PASSING_TESTS_MARKER, '')); + }); + // tslint:disable-next-line:no-console + console.log( + `${specCount} specs,`, // + `${passingTests.length} passing specs,`, // + `${stillFailing.length} still failing specs`); + + } else { + // tslint:disable-next-line:no-console + console.log('NO PASSING TESTS FOUND.'); + } + } + }); } \ No newline at end of file diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 806a431e82..e411ca12cc 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -467,38 +467,38 @@ describe('Integration', () => { expect(location.path()).toEqual('/child/simple'); }))); - fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') && - it('should work when an outlet is added/removed', fakeAsync(() => { - @Component({ - selector: 'someRoot', - template: `[
]` - }) - class RootCmpWithLink { - cond: boolean = true; - } - TestBed.configureTestingModule({declarations: [RootCmpWithLink]}); + fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') + .it('should work when an outlet is added/removed', fakeAsync(() => { + @Component({ + selector: 'someRoot', + template: `[
]` + }) + class RootCmpWithLink { + cond: boolean = true; + } + TestBed.configureTestingModule({declarations: [RootCmpWithLink]}); - const router: Router = TestBed.get(Router); + const router: Router = TestBed.get(Router); - const fixture = createRoot(router, RootCmpWithLink); + const fixture = createRoot(router, RootCmpWithLink); - router.resetConfig([ - {path: 'simple', component: SimpleCmp}, - {path: 'blank', component: BlankCmp}, - ]); + router.resetConfig([ + {path: 'simple', component: SimpleCmp}, + {path: 'blank', component: BlankCmp}, + ]); - router.navigateByUrl('/simple'); - advance(fixture); - expect(fixture.nativeElement).toHaveText('[simple]'); + router.navigateByUrl('/simple'); + advance(fixture); + expect(fixture.nativeElement).toHaveText('[simple]'); - fixture.componentInstance.cond = false; - advance(fixture); - expect(fixture.nativeElement).toHaveText('[]'); + fixture.componentInstance.cond = false; + advance(fixture); + expect(fixture.nativeElement).toHaveText('[]'); - fixture.componentInstance.cond = true; - advance(fixture); - expect(fixture.nativeElement).toHaveText('[simple]'); - })); + fixture.componentInstance.cond = true; + advance(fixture); + expect(fixture.nativeElement).toHaveText('[simple]'); + })); it('should update location when navigating', fakeAsync(() => { @Component({template: `record`}) @@ -2595,46 +2595,46 @@ describe('Integration', () => { expect(canceledStatus).toEqual(false); }))); - fixmeIvy('FW-766: One router test is wrong') && - it('works with componentless routes', - fakeAsync(inject([Router, Location], (router: Router, location: Location) => { - const fixture = createRoot(router, RootCmp); + fixmeIvy('FW-766: One router test is wrong') + .it('works with componentless routes', + fakeAsync(inject([Router, Location], (router: Router, location: Location) => { + const fixture = createRoot(router, RootCmp); - router.resetConfig([ - { - path: 'grandparent', - canDeactivate: ['RecordingDeactivate'], - children: [{ - path: 'parent', - canDeactivate: ['RecordingDeactivate'], - children: [{ - path: 'child', - canDeactivate: ['RecordingDeactivate'], - children: [{ - path: 'simple', - component: SimpleCmp, - canDeactivate: ['RecordingDeactivate'] - }] - }] - }] - }, - {path: 'simple', component: SimpleCmp} - ]); + router.resetConfig([ + { + path: 'grandparent', + canDeactivate: ['RecordingDeactivate'], + children: [{ + path: 'parent', + canDeactivate: ['RecordingDeactivate'], + children: [{ + path: 'child', + canDeactivate: ['RecordingDeactivate'], + children: [{ + path: 'simple', + component: SimpleCmp, + canDeactivate: ['RecordingDeactivate'] + }] + }] + }] + }, + {path: 'simple', component: SimpleCmp} + ]); - router.navigateByUrl('/grandparent/parent/child/simple'); - advance(fixture); - expect(location.path()).toEqual('/grandparent/parent/child/simple'); + router.navigateByUrl('/grandparent/parent/child/simple'); + advance(fixture); + expect(location.path()).toEqual('/grandparent/parent/child/simple'); - router.navigateByUrl('/simple'); - advance(fixture); + router.navigateByUrl('/simple'); + advance(fixture); - const child = fixture.debugElement.children[1].componentInstance; + const child = fixture.debugElement.children[1].componentInstance; - expect(log.map((a: any) => a.path)).toEqual([ - 'simple', 'child', 'parent', 'grandparent' - ]); - expect(log.map((a: any) => a.component)).toEqual([child, null, null, null]); - }))); + expect(log.map((a: any) => a.path)).toEqual([ + 'simple', 'child', 'parent', 'grandparent' + ]); + expect(log.map((a: any) => a.component)).toEqual([child, null, null, null]); + }))); it('works with aux routes', fakeAsync(inject([Router, Location], (router: Router, location: Location) => { @@ -3524,94 +3524,94 @@ describe('Integration', () => { expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); }))); - fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') && - it('should have 2 injector trees: module and element', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Component({ - selector: 'lazy', - template: 'parent[]', - viewProviders: [ - {provide: 'shadow', useValue: 'from parent component'}, - ], - }) - class Parent { - } + fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') + .it('should have 2 injector trees: module and element', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Component({ + selector: 'lazy', + template: 'parent[]', + viewProviders: [ + {provide: 'shadow', useValue: 'from parent component'}, + ], + }) + class Parent { + } - @Component({selector: 'lazy', template: 'child'}) - class Child { - } + @Component({selector: 'lazy', template: 'child'}) + class Child { + } - @NgModule({ - declarations: [Parent], - imports: [RouterModule.forChild([{ - path: 'parent', - component: Parent, - children: [ - {path: 'child', loadChildren: 'child'}, - ] - }])], - providers: [ - {provide: 'moduleName', useValue: 'parent'}, - {provide: 'fromParent', useValue: 'from parent'}, - ], - }) - class ParentModule { - } + @NgModule({ + declarations: [Parent], + imports: [RouterModule.forChild([{ + path: 'parent', + component: Parent, + children: [ + {path: 'child', loadChildren: 'child'}, + ] + }])], + providers: [ + {provide: 'moduleName', useValue: 'parent'}, + {provide: 'fromParent', useValue: 'from parent'}, + ], + }) + class ParentModule { + } - @NgModule({ - declarations: [Child], - imports: [RouterModule.forChild([{path: '', component: Child}])], - providers: [ - {provide: 'moduleName', useValue: 'child'}, - {provide: 'fromChild', useValue: 'from child'}, - {provide: 'shadow', useValue: 'from child module'}, - ], - }) - class ChildModule { - } + @NgModule({ + declarations: [Child], + imports: [RouterModule.forChild([{path: '', component: Child}])], + providers: [ + {provide: 'moduleName', useValue: 'child'}, + {provide: 'fromChild', useValue: 'from child'}, + {provide: 'shadow', useValue: 'from child module'}, + ], + }) + class ChildModule { + } - loader.stubbedModules = { - parent: ParentModule, - child: ChildModule, - }; + loader.stubbedModules = { + parent: ParentModule, + child: ChildModule, + }; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'parent'}]); - router.navigateByUrl('/lazy/parent/child'); - advance(fixture); - expect(location.path()).toEqual('/lazy/parent/child'); - expect(fixture.nativeElement).toHaveText('parent[child]'); + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'parent'}]); + router.navigateByUrl('/lazy/parent/child'); + advance(fixture); + expect(location.path()).toEqual('/lazy/parent/child'); + expect(fixture.nativeElement).toHaveText('parent[child]'); - const pInj = fixture.debugElement.query(By.directive(Parent)).injector !; - const cInj = fixture.debugElement.query(By.directive(Child)).injector !; + const pInj = fixture.debugElement.query(By.directive(Parent)).injector !; + const cInj = fixture.debugElement.query(By.directive(Child)).injector !; - expect(pInj.get('moduleName')).toEqual('parent'); - expect(pInj.get('fromParent')).toEqual('from parent'); - expect(pInj.get(Parent)).toBeAnInstanceOf(Parent); - expect(pInj.get('fromChild', null)).toEqual(null); - expect(pInj.get(Child, null)).toEqual(null); + expect(pInj.get('moduleName')).toEqual('parent'); + expect(pInj.get('fromParent')).toEqual('from parent'); + expect(pInj.get(Parent)).toBeAnInstanceOf(Parent); + expect(pInj.get('fromChild', null)).toEqual(null); + expect(pInj.get(Child, null)).toEqual(null); - expect(cInj.get('moduleName')).toEqual('child'); - expect(cInj.get('fromParent')).toEqual('from parent'); - expect(cInj.get('fromChild')).toEqual('from child'); - expect(cInj.get(Parent)).toBeAnInstanceOf(Parent); - expect(cInj.get(Child)).toBeAnInstanceOf(Child); - // The child module can not shadow the parent component - expect(cInj.get('shadow')).toEqual('from parent component'); + expect(cInj.get('moduleName')).toEqual('child'); + expect(cInj.get('fromParent')).toEqual('from parent'); + expect(cInj.get('fromChild')).toEqual('from child'); + expect(cInj.get(Parent)).toBeAnInstanceOf(Parent); + expect(cInj.get(Child)).toBeAnInstanceOf(Child); + // The child module can not shadow the parent component + expect(cInj.get('shadow')).toEqual('from parent component'); - const pmInj = pInj.get(NgModuleRef).injector; - const cmInj = cInj.get(NgModuleRef).injector; + const pmInj = pInj.get(NgModuleRef).injector; + const cmInj = cInj.get(NgModuleRef).injector; - expect(pmInj.get('moduleName')).toEqual('parent'); - expect(cmInj.get('moduleName')).toEqual('child'); + expect(pmInj.get('moduleName')).toEqual('parent'); + expect(cmInj.get('moduleName')).toEqual('child'); - expect(pmInj.get(Parent, '-')).toEqual('-'); - expect(cmInj.get(Parent, '-')).toEqual('-'); - expect(pmInj.get(Child, '-')).toEqual('-'); - expect(cmInj.get(Child, '-')).toEqual('-'); - }))); + expect(pmInj.get(Parent, '-')).toEqual('-'); + expect(cmInj.get(Parent, '-')).toEqual('-'); + expect(pmInj.get(Child, '-')).toEqual('-'); + expect(cmInj.get(Child, '-')).toEqual('-'); + }))); // https://github.com/angular/angular/issues/12889 it('should create a single instance of lazy-loaded modules', @@ -3653,56 +3653,56 @@ describe('Integration', () => { // https://github.com/angular/angular/issues/13870 fixmeIvy( - 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') && - it('should create a single instance of guards for lazy-loaded modules', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - @Injectable() - class Service { - } + 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') + .it('should create a single instance of guards for lazy-loaded modules', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + @Injectable() + class Service { + } - @Injectable() - class Resolver implements Resolve { - constructor(public service: Service) {} - resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - return this.service; - } - } + @Injectable() + class Resolver implements Resolve { + constructor(public service: Service) {} + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return this.service; + } + } - @Component({selector: 'lazy', template: 'lazy'}) - class LazyLoadedComponent { - resolvedService: Service; - constructor(public injectedService: Service, route: ActivatedRoute) { - this.resolvedService = route.snapshot.data['service']; - } - } + @Component({selector: 'lazy', template: 'lazy'}) + class LazyLoadedComponent { + resolvedService: Service; + constructor(public injectedService: Service, route: ActivatedRoute) { + this.resolvedService = route.snapshot.data['service']; + } + } - @NgModule({ - declarations: [LazyLoadedComponent], - providers: [Service, Resolver], - imports: [ - RouterModule.forChild([{ - path: 'loaded', - component: LazyLoadedComponent, - resolve: {'service': Resolver}, - }]), - ] - }) - class LoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + providers: [Service, Resolver], + imports: [ + RouterModule.forChild([{ + path: 'loaded', + component: LazyLoadedComponent, + resolve: {'service': Resolver}, + }]), + ] + }) + class LoadedModule { + } - loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); - router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); - router.navigateByUrl('/lazy/loaded'); - advance(fixture); + loader.stubbedModules = {expected: LoadedModule}; + const fixture = createRoot(router, RootCmp); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + router.navigateByUrl('/lazy/loaded'); + advance(fixture); - expect(fixture.nativeElement).toHaveText('lazy'); - const lzc = fixture.debugElement.query(By.directive(LazyLoadedComponent)) - .componentInstance; - expect(lzc.injectedService).toBe(lzc.resolvedService); - }))); + expect(fixture.nativeElement).toHaveText('lazy'); + const lzc = fixture.debugElement.query(By.directive(LazyLoadedComponent)) + .componentInstance; + expect(lzc.injectedService).toBe(lzc.resolvedService); + }))); it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded', @@ -3954,27 +3954,27 @@ describe('Integration', () => { }); fixmeIvy( - 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') && - it('should use the injector of the lazily-loaded configuration', - fakeAsync(inject( - [Router, Location, NgModuleFactoryLoader], - (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { - loader.stubbedModules = {expected: LoadedModule}; + 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') + .it('should use the injector of the lazily-loaded configuration', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + loader.stubbedModules = {expected: LoadedModule}; - const fixture = createRoot(router, RootCmp); + const fixture = createRoot(router, RootCmp); - router.resetConfig([{ - path: 'eager-parent', - component: EagerParentComponent, - children: [{path: 'lazy', loadChildren: 'expected'}] - }]); + router.resetConfig([{ + path: 'eager-parent', + component: EagerParentComponent, + children: [{path: 'lazy', loadChildren: 'expected'}] + }]); - router.navigateByUrl('/eager-parent/lazy/lazy-parent/lazy-child'); - advance(fixture); + router.navigateByUrl('/eager-parent/lazy/lazy-parent/lazy-child'); + advance(fixture); - expect(location.path()).toEqual('/eager-parent/lazy/lazy-parent/lazy-child'); - expect(fixture.nativeElement).toHaveText('eager-parent lazy-parent lazy-child'); - }))); + expect(location.path()).toEqual('/eager-parent/lazy/lazy-parent/lazy-child'); + expect(fixture.nativeElement).toHaveText('eager-parent lazy-parent lazy-child'); + }))); }); it('works when given a callback', @@ -4439,82 +4439,82 @@ describe('Integration', () => { expect(simpleCmp1).not.toBe(simpleCmp2); }))); - fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') && - it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', - fakeAsync(() => { - @Component({ - selector: 'root-cmp', - template: - '
' - }) - class RootCmpWithCondOutlet implements OnDestroy { - private subscription: Subscription; - public isToolpanelShowing: boolean = false; + fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') + .it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', + fakeAsync(() => { + @Component({ + selector: 'root-cmp', + template: + '
' + }) + class RootCmpWithCondOutlet implements OnDestroy { + private subscription: Subscription; + public isToolpanelShowing: boolean = false; - constructor(router: Router) { - this.subscription = - router.events.pipe(filter(event => event instanceof NavigationEnd)) - .subscribe( - () => this.isToolpanelShowing = - !!router.parseUrl(router.url).root.children['toolpanel']); - } + constructor(router: Router) { + this.subscription = + router.events.pipe(filter(event => event instanceof NavigationEnd)) + .subscribe( + () => this.isToolpanelShowing = + !!router.parseUrl(router.url).root.children['toolpanel']); + } - public ngOnDestroy(): void { this.subscription.unsubscribe(); } - } + public ngOnDestroy(): void { this.subscription.unsubscribe(); } + } - @Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'}) - class Tool1Component { - } + @Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'}) + class Tool1Component { + } - @Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'}) - class Tool2Component { - } + @Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'}) + class Tool2Component { + } - @NgModule({ - declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component], - imports: [ - CommonModule, - RouterTestingModule.withRoutes([ - {path: 'a', outlet: 'toolpanel', component: Tool1Component}, - {path: 'b', outlet: 'toolpanel', component: Tool2Component}, - ]), - ], - }) - class TestModule { - } + @NgModule({ + declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component], + imports: [ + CommonModule, + RouterTestingModule.withRoutes([ + {path: 'a', outlet: 'toolpanel', component: Tool1Component}, + {path: 'b', outlet: 'toolpanel', component: Tool2Component}, + ]), + ], + }) + class TestModule { + } - TestBed.configureTestingModule({imports: [TestModule]}); + TestBed.configureTestingModule({imports: [TestModule]}); - const router: Router = TestBed.get(Router); - router.routeReuseStrategy = new AttachDetachReuseStrategy(); + const router: Router = TestBed.get(Router); + router.routeReuseStrategy = new AttachDetachReuseStrategy(); - const fixture = createRoot(router, RootCmpWithCondOutlet); + const fixture = createRoot(router, RootCmpWithCondOutlet); - // Activate 'tool-1' - router.navigate([{outlets: {toolpanel: 'a'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool1Component, '(a)'); + // Activate 'tool-1' + router.navigate([{outlets: {toolpanel: 'a'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool1Component, '(a)'); - // Deactivate 'tool-1' - router.navigate([{outlets: {toolpanel: null}}]); - advance(fixture); - expect(fixture).not.toContainComponent(Tool1Component, '(b)'); + // Deactivate 'tool-1' + router.navigate([{outlets: {toolpanel: null}}]); + advance(fixture); + expect(fixture).not.toContainComponent(Tool1Component, '(b)'); - // Activate 'tool-1' - router.navigate([{outlets: {toolpanel: 'a'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool1Component, '(c)'); + // Activate 'tool-1' + router.navigate([{outlets: {toolpanel: 'a'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool1Component, '(c)'); - // Deactivate 'tool-1' - router.navigate([{outlets: {toolpanel: null}}]); - advance(fixture); - expect(fixture).not.toContainComponent(Tool1Component, '(d)'); + // Deactivate 'tool-1' + router.navigate([{outlets: {toolpanel: null}}]); + advance(fixture); + expect(fixture).not.toContainComponent(Tool1Component, '(d)'); - // Activate 'tool-2' - router.navigate([{outlets: {toolpanel: 'b'}}]); - advance(fixture); - expect(fixture).toContainComponent(Tool2Component, '(e)'); - })); + // Activate 'tool-2' + router.navigate([{outlets: {toolpanel: 'b'}}]); + advance(fixture); + expect(fixture).toContainComponent(Tool2Component, '(e)'); + })); }); }); diff --git a/packages/router/test/router_preloader.spec.ts b/packages/router/test/router_preloader.spec.ts index 64ee811f08..4b0fabc2cc 100644 --- a/packages/router/test/router_preloader.spec.ts +++ b/packages/router/test/router_preloader.spec.ts @@ -62,64 +62,64 @@ describe('RouterPreloader', () => { fixmeIvy( - 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') && - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, - testModule: NgModuleRef) => { - const events: Array = []; - @NgModule({ - declarations: [LazyLoadedCmp], - imports: [RouterModule.forChild( - [{path: 'LoadedModule2', component: LazyLoadedCmp}])] - }) - class LoadedModule2 { - } + 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') + .it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, + testModule: NgModuleRef) => { + const events: Array = []; + @NgModule({ + declarations: [LazyLoadedCmp], + imports: [RouterModule.forChild( + [{path: 'LoadedModule2', component: LazyLoadedCmp}])] + }) + class LoadedModule2 { + } - @NgModule({ - imports: [RouterModule.forChild( - [{path: 'LoadedModule1', loadChildren: 'expected2'}])] - }) - class LoadedModule1 { - } + @NgModule({ + imports: [RouterModule.forChild( + [{path: 'LoadedModule1', loadChildren: 'expected2'}])] + }) + class LoadedModule1 { + } - router.events.subscribe(e => { - if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) { - events.push(e); - } - }); + router.events.subscribe(e => { + if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) { + events.push(e); + } + }); - loader.stubbedModules = { - expected: LoadedModule1, - expected2: LoadedModule2, - }; + loader.stubbedModules = { + expected: LoadedModule1, + expected2: LoadedModule2, + }; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; - expect(c[0].loadChildren).toEqual('expected'); + const c = router.config; + expect(c[0].loadChildren).toEqual('expected'); - const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; - const module: any = loadedConfig.module; - expect(loadedConfig.routes[0].path).toEqual('LoadedModule1'); - expect(module._parent).toBe(testModule); + const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; + const module: any = loadedConfig.module; + expect(loadedConfig.routes[0].path).toEqual('LoadedModule1'); + expect(module._parent).toBe(testModule); - const loadedConfig2: LoadedRouterConfig = - (loadedConfig.routes[0] as any)._loadedConfig !; - const module2: any = loadedConfig2.module; - expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2'); - expect(module2._parent).toBe(module); + const loadedConfig2: LoadedRouterConfig = + (loadedConfig.routes[0] as any)._loadedConfig !; + const module2: any = loadedConfig2.module; + expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2'); + expect(module2._parent).toBe(module); - expect(events.map(e => e.toString())).toEqual([ - 'RouteConfigLoadStart(path: lazy)', - 'RouteConfigLoadEnd(path: lazy)', - 'RouteConfigLoadStart(path: LoadedModule1)', - 'RouteConfigLoadEnd(path: LoadedModule1)', - ]); - }))); + expect(events.map(e => e.toString())).toEqual([ + 'RouteConfigLoadStart(path: lazy)', + 'RouteConfigLoadEnd(path: lazy)', + 'RouteConfigLoadStart(path: LoadedModule1)', + 'RouteConfigLoadEnd(path: LoadedModule1)', + ]); + }))); }); describe('should support modules that have already been loaded', () => { @@ -131,59 +131,59 @@ describe('RouterPreloader', () => { }); fixmeIvy( - 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') && - it('should work', - fakeAsync(inject( - [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], - (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, - testModule: NgModuleRef, compiler: Compiler) => { - @NgModule() - class LoadedModule2 { - } + 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') + .it('should work', + fakeAsync(inject( + [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], + (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, + testModule: NgModuleRef, compiler: Compiler) => { + @NgModule() + class LoadedModule2 { + } - const module2 = compiler.compileModuleSync(LoadedModule2).create(null); + const module2 = compiler.compileModuleSync(LoadedModule2).create(null); - @NgModule({ - imports: [RouterModule.forChild([ - { - path: 'LoadedModule2', - loadChildren: 'no', - _loadedConfig: { - routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}], - module: module2, - } - }, - ])] - }) - class LoadedModule1 { - } + @NgModule({ + imports: [RouterModule.forChild([ + { + path: 'LoadedModule2', + loadChildren: 'no', + _loadedConfig: { + routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}], + module: module2, + } + }, + ])] + }) + class LoadedModule1 { + } - @NgModule({imports: [RouterModule.forChild([])]}) - class LoadedModule3 { - } + @NgModule({imports: [RouterModule.forChild([])]}) + class LoadedModule3 { + } - loader.stubbedModules = { - expected: LoadedModule1, - expected3: LoadedModule3, - }; + loader.stubbedModules = { + expected: LoadedModule1, + expected3: LoadedModule3, + }; - preloader.preload().subscribe(() => {}); + preloader.preload().subscribe(() => {}); - tick(); + tick(); - const c = router.config; + const c = router.config; - const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; - const module: any = loadedConfig.module; - expect(module._parent).toBe(testModule); + const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; + const module: any = loadedConfig.module; + expect(module._parent).toBe(testModule); - const loadedConfig2: LoadedRouterConfig = - (loadedConfig.routes[0] as any)._loadedConfig !; - const loadedConfig3: LoadedRouterConfig = - (loadedConfig2.routes[0] as any)._loadedConfig !; - const module3: any = loadedConfig3.module; - expect(module3._parent).toBe(module2); - }))); + const loadedConfig2: LoadedRouterConfig = + (loadedConfig.routes[0] as any)._loadedConfig !; + const loadedConfig3: LoadedRouterConfig = + (loadedConfig2.routes[0] as any)._loadedConfig !; + const module3: any = loadedConfig3.module; + expect(module3._parent).toBe(module2); + }))); }); describe('should ignore errors', () => { diff --git a/packages/upgrade/test/dynamic/upgrade_spec.ts b/packages/upgrade/test/dynamic/upgrade_spec.ts index 51de32f600..a206e75f58 100644 --- a/packages/upgrade/test/dynamic/upgrade_spec.ts +++ b/packages/upgrade/test/dynamic/upgrade_spec.ts @@ -30,66 +30,66 @@ withEachNg1Version(() => { describe('(basic use)', () => { it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1)); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should instantiate ng2 in ng1 template and project content', async(() => { - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should instantiate ng2 in ng1 template and project content', async(() => { + const ng1Module = angular.module('ng1', []); - @Component({ - selector: 'ng2', - template: `{{ 'NG2' }}()`, - }) - class Ng2 { - } + @Component({ + selector: 'ng2', + template: `{{ 'NG2' }}()`, + }) + class Ng2 { + } - @NgModule({declarations: [Ng2], imports: [BrowserModule]}) - class Ng2Module { - } + @NgModule({declarations: [Ng2], imports: [BrowserModule]}) + class Ng2Module { + } - const element = - html('
{{ \'ng1[\' }}~{{ \'ng-content\' }}~{{ \']\' }}
'); + const element = + html('
{{ \'ng1[\' }}~{{ \'ng-content\' }}~{{ \']\' }}
'); - const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(document.body.textContent).toEqual('ng1[NG2(~ng-content~)]'); - ref.dispose(); - }); - })); + const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(document.body.textContent).toEqual('ng1[NG2(~ng-content~)]'); + ref.dispose(); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should instantiate ng1 in ng2 template and project content', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should instantiate ng1 in ng2 template and project content', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - @Component({ - selector: 'ng2', - template: `{{ 'ng2(' }}{{'transclude'}}{{ ')' }}`, - }) - class Ng2 { - } + @Component({ + selector: 'ng2', + template: `{{ 'ng2(' }}{{'transclude'}}{{ ')' }}`, + }) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng1', () => { - return { - transclude: true, - template: '{{ "ng1" }}()' - }; - }); - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + ng1Module.directive('ng1', () => { + return { + transclude: true, + template: '{{ "ng1" }}()' + }; + }); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html('
{{\'ng1(\'}}{{\')\'}}
'); + const element = html('
{{\'ng1(\'}}{{\')\'}}
'); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(document.body.textContent).toEqual('ng1(ng2(ng1(transclude)))'); - ref.dispose(); - }); - })); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(document.body.textContent).toEqual('ng1(ng2(ng1(transclude)))'); + ref.dispose(); + }); + })); it('supports the compilerOptions argument', async(() => { const platformRef = platformBrowserDynamic(); @@ -149,140 +149,138 @@ withEachNg1Version(() => { adapter = new UpgradeAdapter(Ng2Module); }); - fixmeIvy( - 'FW-682: JIT compilation occurs at component definition time rather than bootstrap') && - it('should throw an uncaught error', fakeAsync(() => { - const resolveSpy = jasmine.createSpy('resolveSpy'); - spyOn(console, 'error'); + fixmeIvy('FW-682: JIT compilation occurs at component definition time rather than bootstrap') + .it('should throw an uncaught error', fakeAsync(() => { + const resolveSpy = jasmine.createSpy('resolveSpy'); + spyOn(console, 'error'); - expect(() => { - adapter.bootstrap(html(''), ['ng1']).ready(resolveSpy); - flushMicrotasks(); - }).toThrowError(); - expect(resolveSpy).not.toHaveBeenCalled(); - })); + expect(() => { + adapter.bootstrap(html(''), ['ng1']).ready(resolveSpy); + flushMicrotasks(); + }).toThrowError(); + expect(resolveSpy).not.toHaveBeenCalled(); + })); - fixmeIvy( - 'FW-682: JIT compilation occurs at component definition time rather than bootstrap') && - it('should output an error message to the console and re-throw', fakeAsync(() => { - const consoleErrorSpy: jasmine.Spy = spyOn(console, 'error'); - expect(() => { - adapter.bootstrap(html(''), ['ng1']); - flushMicrotasks(); - }).toThrowError(); - const args: any[] = consoleErrorSpy.calls.mostRecent().args; - expect(consoleErrorSpy).toHaveBeenCalled(); - expect(args.length).toBeGreaterThan(0); - expect(args[0]).toEqual(jasmine.any(Error)); - })); + fixmeIvy('FW-682: JIT compilation occurs at component definition time rather than bootstrap') + .it('should output an error message to the console and re-throw', fakeAsync(() => { + const consoleErrorSpy: jasmine.Spy = spyOn(console, 'error'); + expect(() => { + adapter.bootstrap(html(''), ['ng1']); + flushMicrotasks(); + }).toThrowError(); + const args: any[] = consoleErrorSpy.calls.mostRecent().args; + expect(consoleErrorSpy).toHaveBeenCalled(); + expect(args.length).toBeGreaterThan(0); + expect(args[0]).toEqual(jasmine.any(Error)); + })); }); describe('scope/component change-detection', () => { - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should interleave scope and component expressions', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); - const log: string[] = []; - const l = (value: string) => { - log.push(value); - return value + ';'; - }; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should interleave scope and component expressions', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); + const log: string[] = []; + const l = (value: string) => { + log.push(value); + return value + ';'; + }; - ng1Module.directive('ng1a', () => ({template: '{{ l(\'ng1a\') }}'})); - ng1Module.directive('ng1b', () => ({template: '{{ l(\'ng1b\') }}'})); - ng1Module.run(($rootScope: any) => { - $rootScope.l = l; - $rootScope.reset = () => log.length = 0; - }); + ng1Module.directive('ng1a', () => ({template: '{{ l(\'ng1a\') }}'})); + ng1Module.directive('ng1b', () => ({template: '{{ l(\'ng1b\') }}'})); + ng1Module.run(($rootScope: any) => { + $rootScope.l = l; + $rootScope.reset = () => log.length = 0; + }); - @Component({ - selector: 'ng2', - template: `{{l('2A')}}{{l('2B')}}{{l('2C')}}` - }) - class Ng2 { - l: any; - constructor() { this.l = l; } - } + @Component({ + selector: 'ng2', + template: `{{l('2A')}}{{l('2B')}}{{l('2C')}}` + }) + class Ng2 { + l: any; + constructor() { this.l = l; } + } - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1a'), adapter.upgradeNg1Component('ng1b'), Ng2 - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1a'), adapter.upgradeNg1Component('ng1b'), Ng2 + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = - html('
{{reset(); l(\'1A\');}}{{l(\'1B\')}}{{l(\'1C\')}}
'); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(document.body.textContent).toEqual('1A;2A;ng1a;2B;ng1b;2C;1C;'); - // https://github.com/angular/angular.js/issues/12983 - expect(log).toEqual(['1A', '1C', '2A', '2B', '2C', 'ng1a', 'ng1b']); - ref.dispose(); - }); - })); + const element = + html('
{{reset(); l(\'1A\');}}{{l(\'1B\')}}{{l(\'1C\')}}
'); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(document.body.textContent).toEqual('1A;2A;ng1a;2B;ng1b;2C;1C;'); + // https://github.com/angular/angular.js/issues/12983 + expect(log).toEqual(['1A', '1C', '2A', '2B', '2C', 'ng1a', 'ng1b']); + ref.dispose(); + }); + })); fixmeIvy( - 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') && - it('should propagate changes to a downgraded component inside the ngZone', async(() => { - let appComponent: AppComponent; - let upgradeRef: UpgradeAdapterRef; + 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') + .it('should propagate changes to a downgraded component inside the ngZone', async(() => { + let appComponent: AppComponent; + let upgradeRef: UpgradeAdapterRef; - @Component({selector: 'my-app', template: ''}) - class AppComponent { - value?: number; - constructor() { appComponent = this; } - } + @Component({selector: 'my-app', template: ''}) + class AppComponent { + value?: number; + constructor() { appComponent = this; } + } - @Component({ - selector: 'my-child', - template: '
{{valueFromPromise}}', - }) - class ChildComponent { - valueFromPromise?: number; - @Input() - set value(v: number) { expect(NgZone.isInAngularZone()).toBe(true); } + @Component({ + selector: 'my-child', + template: '
{{valueFromPromise}}', + }) + class ChildComponent { + valueFromPromise?: number; + @Input() + set value(v: number) { expect(NgZone.isInAngularZone()).toBe(true); } - constructor(private zone: NgZone) {} + constructor(private zone: NgZone) {} - ngOnChanges(changes: SimpleChanges) { - if (changes['value'].isFirstChange()) return; + ngOnChanges(changes: SimpleChanges) { + if (changes['value'].isFirstChange()) return; - // HACK(ivy): Using setTimeout allows this test to pass but hides the ivy - // renderer timing BC. - // setTimeout(() => { - // expect(element.textContent).toEqual('5'); - // upgradeRef.dispose(); - // }, 0); - this.zone.onMicrotaskEmpty.subscribe(() => { - expect(element.textContent).toEqual('5'); - upgradeRef.dispose(); - }); + // HACK(ivy): Using setTimeout allows this test to pass but hides the ivy + // renderer timing BC. + // setTimeout(() => { + // expect(element.textContent).toEqual('5'); + // upgradeRef.dispose(); + // }, 0); + this.zone.onMicrotaskEmpty.subscribe(() => { + expect(element.textContent).toEqual('5'); + upgradeRef.dispose(); + }); - Promise.resolve().then( - () => this.valueFromPromise = changes['value'].currentValue); - } - } + Promise.resolve().then( + () => this.valueFromPromise = changes['value'].currentValue); + } + } - @NgModule({declarations: [AppComponent, ChildComponent], imports: [BrowserModule]}) - class Ng2Module { - } + @NgModule({declarations: [AppComponent, ChildComponent], imports: [BrowserModule]}) + class Ng2Module { + } - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []).directive( - 'myApp', adapter.downgradeNg2Component(AppComponent)); + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []).directive( + 'myApp', adapter.downgradeNg2Component(AppComponent)); - const element = html(''); + const element = html(''); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - upgradeRef = ref; - appComponent.value = 5; - }); - })); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + upgradeRef = ref; + appComponent.value = 5; + }); + })); // This test demonstrates https://github.com/angular/angular/issues/6385 // which was invalidly fixed by https://github.com/angular/angular/pull/6386 @@ -336,239 +334,239 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should bind properties, events', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []).value( - $EXCEPTION_HANDLER, (err: any) => { throw err; }); + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should bind properties, events', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []).value( + $EXCEPTION_HANDLER, (err: any) => { throw err; }); - ng1Module.run(($rootScope: any) => { - $rootScope.name = 'world'; - $rootScope.dataA = 'A'; - $rootScope.dataB = 'B'; - $rootScope.modelA = 'initModelA'; - $rootScope.modelB = 'initModelB'; - $rootScope.eventA = '?'; - $rootScope.eventB = '?'; - }); - @Component({ - selector: 'ng2', - inputs: ['literal', 'interpolate', 'oneWayA', 'oneWayB', 'twoWayA', 'twoWayB'], - outputs: [ - 'eventA', 'eventB', 'twoWayAEmitter: twoWayAChange', - 'twoWayBEmitter: twoWayBChange' - ], - template: 'ignore: {{ignore}}; ' + - 'literal: {{literal}}; interpolate: {{interpolate}}; ' + - 'oneWayA: {{oneWayA}}; oneWayB: {{oneWayB}}; ' + - 'twoWayA: {{twoWayA}}; twoWayB: {{twoWayB}}; ({{ngOnChangesCount}})' - }) - class Ng2 { - ngOnChangesCount = 0; - ignore = '-'; - literal = '?'; - interpolate = '?'; - oneWayA = '?'; - oneWayB = '?'; - twoWayA = '?'; - twoWayB = '?'; - eventA = new EventEmitter(); - eventB = new EventEmitter(); - twoWayAEmitter = new EventEmitter(); - twoWayBEmitter = new EventEmitter(); - ngOnChanges(changes: SimpleChanges) { - const assert = (prop: string, value: any) => { - if ((this as any)[prop] != value) { - throw new Error( - `Expected: '${prop}' to be '${value}' but was '${(this as any)[prop]}'`); - } - }; + ng1Module.run(($rootScope: any) => { + $rootScope.name = 'world'; + $rootScope.dataA = 'A'; + $rootScope.dataB = 'B'; + $rootScope.modelA = 'initModelA'; + $rootScope.modelB = 'initModelB'; + $rootScope.eventA = '?'; + $rootScope.eventB = '?'; + }); + @Component({ + selector: 'ng2', + inputs: ['literal', 'interpolate', 'oneWayA', 'oneWayB', 'twoWayA', 'twoWayB'], + outputs: [ + 'eventA', 'eventB', 'twoWayAEmitter: twoWayAChange', + 'twoWayBEmitter: twoWayBChange' + ], + template: 'ignore: {{ignore}}; ' + + 'literal: {{literal}}; interpolate: {{interpolate}}; ' + + 'oneWayA: {{oneWayA}}; oneWayB: {{oneWayB}}; ' + + 'twoWayA: {{twoWayA}}; twoWayB: {{twoWayB}}; ({{ngOnChangesCount}})' + }) + class Ng2 { + ngOnChangesCount = 0; + ignore = '-'; + literal = '?'; + interpolate = '?'; + oneWayA = '?'; + oneWayB = '?'; + twoWayA = '?'; + twoWayB = '?'; + eventA = new EventEmitter(); + eventB = new EventEmitter(); + twoWayAEmitter = new EventEmitter(); + twoWayBEmitter = new EventEmitter(); + ngOnChanges(changes: SimpleChanges) { + const assert = (prop: string, value: any) => { + if ((this as any)[prop] != value) { + throw new Error( + `Expected: '${prop}' to be '${value}' but was '${(this as any)[prop]}'`); + } + }; - const assertChange = (prop: string, value: any) => { - assert(prop, value); - if (!changes[prop]) { - throw new Error(`Changes record for '${prop}' not found.`); - } - const actValue = changes[prop].currentValue; - if (actValue != value) { - throw new Error( - `Expected changes record for'${prop}' to be '${value}' but was '${actValue}'`); - } - }; + const assertChange = (prop: string, value: any) => { + assert(prop, value); + if (!changes[prop]) { + throw new Error(`Changes record for '${prop}' not found.`); + } + const actValue = changes[prop].currentValue; + if (actValue != value) { + throw new Error( + `Expected changes record for'${prop}' to be '${value}' but was '${actValue}'`); + } + }; - switch (this.ngOnChangesCount++) { - case 0: - assert('ignore', '-'); - assertChange('literal', 'Text'); - assertChange('interpolate', 'Hello world'); - assertChange('oneWayA', 'A'); - assertChange('oneWayB', 'B'); - assertChange('twoWayA', 'initModelA'); - assertChange('twoWayB', 'initModelB'); + switch (this.ngOnChangesCount++) { + case 0: + assert('ignore', '-'); + assertChange('literal', 'Text'); + assertChange('interpolate', 'Hello world'); + assertChange('oneWayA', 'A'); + assertChange('oneWayB', 'B'); + assertChange('twoWayA', 'initModelA'); + assertChange('twoWayB', 'initModelB'); - this.twoWayAEmitter.emit('newA'); - this.twoWayBEmitter.emit('newB'); - this.eventA.emit('aFired'); - this.eventB.emit('bFired'); - break; - case 1: - assertChange('twoWayA', 'newA'); - assertChange('twoWayB', 'newB'); - break; - case 2: - assertChange('interpolate', 'Hello everyone'); - break; - default: - throw new Error('Called too many times! ' + JSON.stringify(changes)); - } - } - } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + this.twoWayAEmitter.emit('newA'); + this.twoWayBEmitter.emit('newB'); + this.eventA.emit('aFired'); + this.eventB.emit('bFired'); + break; + case 1: + assertChange('twoWayA', 'newA'); + assertChange('twoWayB', 'newB'); + break; + case 2: + assertChange('interpolate', 'Hello everyone'); + break; + default: + throw new Error('Called too many times! ' + JSON.stringify(changes)); + } + } + } + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - @NgModule({ - declarations: [Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
+ const element = html(`
| modelA: {{modelA}}; modelB: {{modelB}}; eventA: {{eventA}}; eventB: {{eventB}};
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent !)) - .toEqual( - 'ignore: -; ' + - 'literal: Text; interpolate: Hello world; ' + - 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (2) | ' + - 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent !)) + .toEqual( + 'ignore: -; ' + + 'literal: Text; interpolate: Hello world; ' + + 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (2) | ' + + 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); - ref.ng1RootScope.$apply('name = "everyone"'); - expect(multiTrim(document.body.textContent !)) - .toEqual( - 'ignore: -; ' + - 'literal: Text; interpolate: Hello everyone; ' + - 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (3) | ' + - 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); + ref.ng1RootScope.$apply('name = "everyone"'); + expect(multiTrim(document.body.textContent !)) + .toEqual( + 'ignore: -; ' + + 'literal: Text; interpolate: Hello everyone; ' + + 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (3) | ' + + 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); - ref.dispose(); - }); + ref.dispose(); + }); - })); + })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should support two-way binding and event listener', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const listenerSpy = jasmine.createSpy('$rootScope.listener'); - const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { - $rootScope['value'] = 'world'; - $rootScope['listener'] = listenerSpy; - }); + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should support two-way binding and event listener', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const listenerSpy = jasmine.createSpy('$rootScope.listener'); + const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { + $rootScope['value'] = 'world'; + $rootScope['listener'] = listenerSpy; + }); - @Component({selector: 'ng2', template: `model: {{model}};`}) - class Ng2Component implements OnChanges { - ngOnChangesCount = 0; - @Input() model = '?'; - @Output() modelChange = new EventEmitter(); + @Component({selector: 'ng2', template: `model: {{model}};`}) + class Ng2Component implements OnChanges { + ngOnChangesCount = 0; + @Input() model = '?'; + @Output() modelChange = new EventEmitter(); - ngOnChanges(changes: SimpleChanges) { - switch (this.ngOnChangesCount++) { - case 0: - expect(changes.model.currentValue).toBe('world'); - this.modelChange.emit('newC'); - break; - case 1: - expect(changes.model.currentValue).toBe('newC'); - break; - default: - throw new Error('Called too many times! ' + JSON.stringify(changes)); - } - } - } + ngOnChanges(changes: SimpleChanges) { + switch (this.ngOnChangesCount++) { + case 0: + expect(changes.model.currentValue).toBe('world'); + this.modelChange.emit('newC'); + break; + case 1: + expect(changes.model.currentValue).toBe('newC'); + break; + default: + throw new Error('Called too many times! ' + JSON.stringify(changes)); + } + } + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({declarations: [Ng2Component], imports: [BrowserModule]}) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({declarations: [Ng2Component], imports: [BrowserModule]}) + class Ng2Module { + ngDoBootstrap() {} + } - const element = html(` + const element = html(`
| value: {{value}}
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(element.textContent)).toEqual('model: newC; | value: newC'); - expect(listenerSpy).toHaveBeenCalledWith('newC'); - ref.dispose(); - }); - })); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(element.textContent)).toEqual('model: newC; | value: newC'); + expect(listenerSpy).toHaveBeenCalledWith('newC'); + ref.dispose(); + }); + })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should initialize inputs in time for `ngOnChanges`', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should initialize inputs in time for `ngOnChanges`', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - @Component({ - selector: 'ng2', - template: ` + @Component({ + selector: 'ng2', + template: ` ngOnChangesCount: {{ ngOnChangesCount }} | firstChangesCount: {{ firstChangesCount }} | initialValue: {{ initialValue }}` - }) - class Ng2Component implements OnChanges { - ngOnChangesCount = 0; - firstChangesCount = 0; - // TODO(issue/24571): remove '!'. - initialValue !: string; - // TODO(issue/24571): remove '!'. - @Input() foo !: string; + }) + class Ng2Component implements OnChanges { + ngOnChangesCount = 0; + firstChangesCount = 0; + // TODO(issue/24571): remove '!'. + initialValue !: string; + // TODO(issue/24571): remove '!'. + @Input() foo !: string; - ngOnChanges(changes: SimpleChanges) { - this.ngOnChangesCount++; + ngOnChanges(changes: SimpleChanges) { + this.ngOnChangesCount++; - if (this.ngOnChangesCount === 1) { - this.initialValue = this.foo; - } + if (this.ngOnChangesCount === 1) { + this.initialValue = this.foo; + } - if (changes['foo'] && changes['foo'].isFirstChange()) { - this.firstChangesCount++; - } - } - } + if (changes['foo'] && changes['foo'].isFirstChange()) { + this.firstChangesCount++; + } + } + } - @NgModule({imports: [BrowserModule], declarations: [Ng2Component]}) - class Ng2Module { - } + @NgModule({imports: [BrowserModule], declarations: [Ng2Component]}) + class Ng2Module { + } - const ng1Module = angular.module('ng1', []).directive( - 'ng2', adapter.downgradeNg2Component(Ng2Component)); + const ng1Module = angular.module('ng1', []).directive( + 'ng2', adapter.downgradeNg2Component(Ng2Component)); - const element = html(` + const element = html(` `); - adapter.bootstrap(element, ['ng1']).ready(ref => { - const nodes = element.querySelectorAll('ng2'); - const expectedTextWith = (value: string) => - `ngOnChangesCount: 1 | firstChangesCount: 1 | initialValue: ${value}`; + adapter.bootstrap(element, ['ng1']).ready(ref => { + const nodes = element.querySelectorAll('ng2'); + const expectedTextWith = (value: string) => + `ngOnChangesCount: 1 | firstChangesCount: 1 | initialValue: ${value}`; - expect(multiTrim(nodes[0].textContent)).toBe(expectedTextWith('foo')); - expect(multiTrim(nodes[1].textContent)).toBe(expectedTextWith('bar')); - expect(multiTrim(nodes[2].textContent)).toBe(expectedTextWith('baz')); - expect(multiTrim(nodes[3].textContent)).toBe(expectedTextWith('qux')); + expect(multiTrim(nodes[0].textContent)).toBe(expectedTextWith('foo')); + expect(multiTrim(nodes[1].textContent)).toBe(expectedTextWith('bar')); + expect(multiTrim(nodes[2].textContent)).toBe(expectedTextWith('baz')); + expect(multiTrim(nodes[3].textContent)).toBe(expectedTextWith('qux')); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); it('should bind to ng-model', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -661,49 +659,49 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should properly run cleanup with multiple levels of nesting', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let destroyed = false; + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should properly run cleanup with multiple levels of nesting', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let destroyed = false; - @Component( - {selector: 'ng2-outer', template: '
'}) - class Ng2OuterComponent { - @Input() destroyIt = false; - } + @Component( + {selector: 'ng2-outer', template: '
'}) + class Ng2OuterComponent { + @Input() destroyIt = false; + } - @Component({selector: 'ng2-inner', template: 'test'}) - class Ng2InnerComponent implements OnDestroy { - ngOnDestroy() { destroyed = true; } - } + @Component({selector: 'ng2-inner', template: 'test'}) + class Ng2InnerComponent implements OnDestroy { + ngOnDestroy() { destroyed = true; } + } - @NgModule({ - imports: [BrowserModule], - declarations: - [Ng2InnerComponent, Ng2OuterComponent, adapter.upgradeNg1Component('ng1')], - schemas: [NO_ERRORS_SCHEMA], - }) - class Ng2Module { - } + @NgModule({ + imports: [BrowserModule], + declarations: + [Ng2InnerComponent, Ng2OuterComponent, adapter.upgradeNg1Component('ng1')], + schemas: [NO_ERRORS_SCHEMA], + }) + class Ng2Module { + } - const ng1Module = - angular.module('ng1', []) - .directive('ng1', () => ({template: ''})) - .directive('ng2Inner', adapter.downgradeNg2Component(Ng2InnerComponent)) - .directive('ng2Outer', adapter.downgradeNg2Component(Ng2OuterComponent)); + const ng1Module = + angular.module('ng1', []) + .directive('ng1', () => ({template: ''})) + .directive('ng2Inner', adapter.downgradeNg2Component(Ng2InnerComponent)) + .directive('ng2Outer', adapter.downgradeNg2Component(Ng2OuterComponent)); - const element = html(''); + const element = html(''); - adapter.bootstrap(element, [ng1Module.name]).ready(ref => { - expect(element.textContent).toBe('test'); - expect(destroyed).toBe(false); + adapter.bootstrap(element, [ng1Module.name]).ready(ref => { + expect(element.textContent).toBe('test'); + expect(destroyed).toBe(false); - $apply(ref, 'destroyIt = true'); + $apply(ref, 'destroyIt = true'); - expect(element.textContent).toBe(''); - expect(destroyed).toBe(true); - }); - })); + expect(element.textContent).toBe(''); + expect(destroyed).toBe(true); + }); + })); it('should fallback to the root ng2.injector when compiled outside the dom', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -741,72 +739,72 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support multi-slot projection', async(() => { - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support multi-slot projection', async(() => { + const ng1Module = angular.module('ng1', []); - @Component({ - selector: 'ng2', - template: '2a()' + - '2b()' - }) - class Ng2 { - } + @Component({ + selector: 'ng2', + template: '2a()' + + '2b()' + }) + class Ng2 { + } - @NgModule({declarations: [Ng2], imports: [BrowserModule]}) - class Ng2Module { - } + @NgModule({declarations: [Ng2], imports: [BrowserModule]}) + class Ng2Module { + } - // The ng-if on one of the projected children is here to make sure - // the correct slot is targeted even with structural directives in play. - const element = html( - '
1a
1b
'); + // The ng-if on one of the projected children is here to make sure + // the correct slot is targeted even with structural directives in play. + const element = html( + '
1a
1b
'); - const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(document.body.textContent).toEqual('2a(1a)2b(1b)'); - ref.dispose(); - }); - })); + const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(document.body.textContent).toEqual('2a(1a)2b(1b)'); + ref.dispose(); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should correctly project structural directives', async(() => { - @Component( - {selector: 'ng2', template: 'ng2-{{ itemId }}()'}) - class Ng2Component { - // TODO(issue/24571): remove '!'. - @Input() itemId !: string; - } + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should correctly project structural directives', async(() => { + @Component( + {selector: 'ng2', template: 'ng2-{{ itemId }}()'}) + class Ng2Component { + // TODO(issue/24571): remove '!'. + @Input() itemId !: string; + } - @NgModule({imports: [BrowserModule], declarations: [Ng2Component]}) - class Ng2Module { - } + @NgModule({imports: [BrowserModule], declarations: [Ng2Component]}) + class Ng2Module { + } - const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); - const ng1Module = - angular.module('ng1', []) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)) - .run(($rootScope: angular.IRootScopeService) => { - $rootScope['items'] = [ - {id: 'a', subitems: [1, 2, 3]}, {id: 'b', subitems: [4, 5, 6]}, - {id: 'c', subitems: [7, 8, 9]} - ]; - }); + const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); + const ng1Module = + angular.module('ng1', []) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)) + .run(($rootScope: angular.IRootScopeService) => { + $rootScope['items'] = [ + {id: 'a', subitems: [1, 2, 3]}, {id: 'b', subitems: [4, 5, 6]}, + {id: 'c', subitems: [7, 8, 9]} + ]; + }); - const element = html(` + const element = html(`
{{ subitem }}
`); - adapter.bootstrap(element, [ng1Module.name]).ready(ref => { - expect(multiTrim(document.body.textContent)) - .toBe('ng2-a( 123 )ng2-b( 456 )ng2-c( 789 )'); - ref.dispose(); - }); - })); + adapter.bootstrap(element, [ng1Module.name]).ready(ref => { + expect(multiTrim(document.body.textContent)) + .toBe('ng2-a( 123 )ng2-b( 456 )ng2-c( 789 )'); + ref.dispose(); + }); + })); it('should allow attribute selectors for components in ng2', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => MyNg2Module)); @@ -835,519 +833,528 @@ withEachNg1Version(() => { }); describe('upgrade ng1 component', () => { - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support `@` bindings', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support `@` bindings', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'Inside: {{ $ctrl.inputA }}, {{ $ctrl.inputB }}', - bindings: {inputA: '@inputAttrA', inputB: '@'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'Inside: {{ $ctrl.inputA }}, {{ $ctrl.inputB }}', + bindings: {inputA: '@inputAttrA', inputB: '@'} + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` | Outside: {{ dataA }}, {{ dataB }} ` - }) - class Ng2Component { - dataA = 'foo'; - dataB = 'bar'; + }) + class Ng2Component { + dataA = 'foo'; + dataB = 'bar'; - constructor() { ng2ComponentInstance = this; } - } + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - const ng1 = element.querySelector('ng1') !; - const ng1Controller = angular.element(ng1).controller !('ng1'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + const ng1 = element.querySelector('ng1') !; + const ng1Controller = angular.element(ng1).controller !('ng1'); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo, bar | Outside: foo, bar'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo, bar | Outside: foo, bar'); - ng1Controller.inputA = 'baz'; - ng1Controller.inputB = 'qux'; - $digest(ref); + ng1Controller.inputA = 'baz'; + ng1Controller.inputB = 'qux'; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: baz, qux | Outside: foo, bar'); + expect(multiTrim(element.textContent)) + .toBe('Inside: baz, qux | Outside: foo, bar'); - ng2ComponentInstance.dataA = 'foo2'; - ng2ComponentInstance.dataB = 'bar2'; - $digest(ref); + ng2ComponentInstance.dataA = 'foo2'; + ng2ComponentInstance.dataB = 'bar2'; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support `<` bindings', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support `<` bindings', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB.value }}', - bindings: {inputA: ' | Outside: {{ dataA.value }}, {{ dataB.value }} ` - }) - class Ng2Component { - dataA = {value: 'foo'}; - dataB = {value: 'bar'}; + }) + class Ng2Component { + dataA = {value: 'foo'}; + dataB = {value: 'bar'}; - constructor() { ng2ComponentInstance = this; } - } + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - const ng1 = element.querySelector('ng1') !; - const ng1Controller = angular.element(ng1).controller !('ng1'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + const ng1 = element.querySelector('ng1') !; + const ng1Controller = angular.element(ng1).controller !('ng1'); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo, bar | Outside: foo, bar'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo, bar | Outside: foo, bar'); - ng1Controller.inputA = {value: 'baz'}; - ng1Controller.inputB = {value: 'qux'}; - $digest(ref); + ng1Controller.inputA = {value: 'baz'}; + ng1Controller.inputB = {value: 'qux'}; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: baz, qux | Outside: foo, bar'); + expect(multiTrim(element.textContent)) + .toBe('Inside: baz, qux | Outside: foo, bar'); - ng2ComponentInstance.dataA = {value: 'foo2'}; - ng2ComponentInstance.dataB = {value: 'bar2'}; - $digest(ref); + ng2ComponentInstance.dataA = {value: 'foo2'}; + ng2ComponentInstance.dataB = {value: 'bar2'}; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support `=` bindings', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support `=` bindings', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB.value }}', - bindings: {inputA: '=inputAttrA', inputB: '='} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB.value }}', + bindings: {inputA: '=inputAttrA', inputB: '='} + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` | Outside: {{ dataA.value }}, {{ dataB.value }} ` - }) - class Ng2Component { - dataA = {value: 'foo'}; - dataB = {value: 'bar'}; + }) + class Ng2Component { + dataA = {value: 'foo'}; + dataB = {value: 'bar'}; - constructor() { ng2ComponentInstance = this; } - } + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - const ng1 = element.querySelector('ng1') !; - const ng1Controller = angular.element(ng1).controller !('ng1'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + const ng1 = element.querySelector('ng1') !; + const ng1Controller = angular.element(ng1).controller !('ng1'); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo, bar | Outside: foo, bar'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo, bar | Outside: foo, bar'); - ng1Controller.inputA = {value: 'baz'}; - ng1Controller.inputB = {value: 'qux'}; - $digest(ref); + ng1Controller.inputA = {value: 'baz'}; + ng1Controller.inputB = {value: 'qux'}; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: baz, qux | Outside: baz, qux'); + expect(multiTrim(element.textContent)) + .toBe('Inside: baz, qux | Outside: baz, qux'); - ng2ComponentInstance.dataA = {value: 'foo2'}; - ng2ComponentInstance.dataB = {value: 'bar2'}; - $digest(ref); + ng2ComponentInstance.dataA = {value: 'foo2'}; + ng2ComponentInstance.dataB = {value: 'bar2'}; + $digest(ref); - expect(multiTrim(element.textContent)) - .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); + expect(multiTrim(element.textContent)) + .toBe('Inside: foo2, bar2 | Outside: foo2, bar2'); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support `&` bindings', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support `&` bindings', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'Inside: -', - bindings: {outputA: '&outputAttrA', outputB: '&'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'Inside: -', + bindings: {outputA: '&outputAttrA', outputB: '&'} + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` | Outside: {{ dataA }}, {{ dataB }} ` - }) - class Ng2Component { - dataA = 'foo'; - dataB = 'bar'; - } + }) + class Ng2Component { + dataA = 'foo'; + dataB = 'bar'; + } - // Define `ng1Module` - const ng1Module = angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - const ng1 = element.querySelector('ng1') !; - const ng1Controller = angular.element(ng1).controller !('ng1'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + const ng1 = element.querySelector('ng1') !; + const ng1Controller = angular.element(ng1).controller !('ng1'); - expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: foo, bar'); + expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: foo, bar'); - ng1Controller.outputA('baz'); - ng1Controller.outputB('qux'); - $digest(ref); + ng1Controller.outputA('baz'); + ng1Controller.outputB('qux'); + $digest(ref); - expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: baz, qux'); + expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: baz, qux'); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should bind properties, events', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should bind properties, events', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - template: 'Hello {{fullName}}; A: {{modelA}}; B: {{modelB}}; C: {{modelC}}; | ', - scope: - {fullName: '@', modelA: '=dataA', modelB: '=dataB', modelC: '=', event: '&'}, - link: function(scope: any) { - scope.$watch('modelB', (v: string) => { - if (v == 'Savkin') { - scope.modelB = 'SAVKIN'; - scope.event('WORKS'); + const ng1 = () => { + return { + template: 'Hello {{fullName}}; A: {{modelA}}; B: {{modelB}}; C: {{modelC}}; | ', + scope: { + fullName: '@', + modelA: '=dataA', + modelB: '=dataB', + modelC: '=', + event: '&' + }, + link: function(scope: any) { + scope.$watch('modelB', (v: string) => { + if (v == 'Savkin') { + scope.modelB = 'SAVKIN'; + scope.event('WORKS'); - // Should not update because [model-a] is uni directional - scope.modelA = 'VICTOR'; - } - }); - } - }; - }; - ng1Module.directive('ng1', ng1); - @Component({ - selector: 'ng2', - template: - '' + - '' + - '{{event}}-{{last}}, {{first}}, {{city}}' - }) - class Ng2 { - first = 'Victor'; - last = 'Savkin'; - city = 'SF'; - event = '?'; - } + // Should not update because [model-a] is uni directional + scope.modelA = 'VICTOR'; + } + }); + } + }; + }; + ng1Module.directive('ng1', ng1); + @Component({ + selector: 'ng2', + template: + '' + + '' + + '{{event}}-{{last}}, {{first}}, {{city}}' + }) + class Ng2 { + first = 'Victor'; + last = 'Savkin'; + city = 'SF'; + event = '?'; + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule - // events, and so without this we would not see the events processed. - setTimeout(() => { - expect(multiTrim(document.body.textContent)) - .toEqual( - 'Hello SAVKIN, Victor, SF; A: VICTOR; B: SAVKIN; C: SF; | Hello TEST; A: First; B: Last; C: City; | WORKS-SAVKIN, Victor, SF'); - ref.dispose(); - }, 0); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual( + 'Hello SAVKIN, Victor, SF; A: VICTOR; B: SAVKIN; C: SF; | Hello TEST; A: First; B: Last; C: City; | WORKS-SAVKIN, Victor, SF'); + ref.dispose(); + }, 0); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should bind optional properties', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should bind optional properties', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - template: 'Hello; A: {{modelA}}; B: {{modelB}}; | ', - scope: {modelA: '=?dataA', modelB: '=?'} - }; - }; - ng1Module.directive('ng1', ng1); - @Component({ - selector: 'ng2', - template: '' + - '' + - '' + - '' - }) - class Ng2 { - first = 'Victor'; - last = 'Savkin'; - } + const ng1 = () => { + return { + template: 'Hello; A: {{modelA}}; B: {{modelB}}; | ', + scope: {modelA: '=?dataA', modelB: '=?'} + }; + }; + ng1Module.directive('ng1', ng1); + @Component({ + selector: 'ng2', + template: '' + + '' + + '' + + '' + }) + class Ng2 { + first = 'Victor'; + last = 'Savkin'; + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule - // events, and so without this we would not see the events processed. - setTimeout(() => { - expect(multiTrim(document.body.textContent)) - .toEqual( - 'Hello; A: Victor; B: Savkin; | Hello; A: First; B: Last; | Hello; A: ; B: ; | Hello; A: ; B: ; |'); - ref.dispose(); - }, 0); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual( + 'Hello; A: Victor; B: Savkin; | Hello; A: First; B: Last; | Hello; A: ; B: ; | Hello; A: ; B: ; |'); + ref.dispose(); + }, 0); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should bind properties, events in controller when bindToController is not used', - async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should bind properties, events in controller when bindToController is not used', + async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - restrict: 'E', - template: '{{someText}} - Length: {{data.length}}', - scope: {data: '='}, - controller: function($scope: any) { - $scope.someText = 'ng1 - Data: ' + $scope.data; - } - }; - }; + const ng1 = () => { + return { + restrict: 'E', + template: '{{someText}} - Length: {{data.length}}', + scope: {data: '='}, + controller: function($scope: any) { + $scope.someText = 'ng1 - Data: ' + $scope.data; + } + }; + }; - ng1Module.directive('ng1', ng1); - @Component({ - selector: 'ng2', - template: - '{{someText}} - Length: {{dataList.length}} | ' - }) - class Ng2 { - dataList = [1, 2, 3]; - someText = 'ng2'; - } + ng1Module.directive('ng1', ng1); + @Component({ + selector: 'ng2', + template: + '{{someText}} - Length: {{dataList.length}} | ' + }) + class Ng2 { + dataList = [1, 2, 3]; + someText = 'ng2'; + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule - // events, and so without this we would not see the events processed. - setTimeout(() => { - expect(multiTrim(document.body.textContent)) - .toEqual('ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3'); - ref.dispose(); - }, 0); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual('ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3'); + ref.dispose(); + }, 0); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should bind properties, events in link function', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should bind properties, events in link function', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - restrict: 'E', - template: '{{someText}} - Length: {{data.length}}', - scope: {data: '='}, - link: function($scope: any) { $scope.someText = 'ng1 - Data: ' + $scope.data; } - }; - }; + const ng1 = () => { + return { + restrict: 'E', + template: '{{someText}} - Length: {{data.length}}', + scope: {data: '='}, + link: function($scope: any) { $scope.someText = 'ng1 - Data: ' + $scope.data; } + }; + }; - ng1Module.directive('ng1', ng1); - @Component({ - selector: 'ng2', - template: - '{{someText}} - Length: {{dataList.length}} | ' - }) - class Ng2 { - dataList = [1, 2, 3]; - someText = 'ng2'; - } + ng1Module.directive('ng1', ng1); + @Component({ + selector: 'ng2', + template: + '{{someText}} - Length: {{dataList.length}} | ' + }) + class Ng2 { + dataList = [1, 2, 3]; + someText = 'ng2'; + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule - // events, and so without this we would not see the events processed. - setTimeout(() => { - expect(multiTrim(document.body.textContent)) - .toEqual('ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3'); - ref.dispose(); - }, 0); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual('ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3'); + ref.dispose(); + }, 0); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support templateUrl fetched from $httpBackend', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); - ng1Module.value( - '$httpBackend', (method: string, url: string, post: any, cbFn: Function) => { - cbFn(200, `${method}:${url}`); - }); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support templateUrl fetched from $httpBackend', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); + ng1Module.value( + '$httpBackend', (method: string, url: string, post: any, cbFn: Function) => { + cbFn(200, `${method}:${url}`); + }); - const ng1 = () => { return {templateUrl: 'url.html'}; }; - ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + const ng1 = () => { return {templateUrl: 'url.html'}; }; + ng1Module.directive('ng1', ng1); + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('GET:url.html'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('GET:url.html'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support templateUrl as a function', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); - ng1Module.value( - '$httpBackend', (method: string, url: string, post: any, cbFn: Function) => { - cbFn(200, `${method}:${url}`); - }); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support templateUrl as a function', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); + ng1Module.value( + '$httpBackend', (method: string, url: string, post: any, cbFn: Function) => { + cbFn(200, `${method}:${url}`); + }); - const ng1 = () => { return {templateUrl() { return 'url.html'; }}; }; - ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + const ng1 = () => { return {templateUrl() { return 'url.html'; }}; }; + ng1Module.directive('ng1', ng1); + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('GET:url.html'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('GET:url.html'); + ref.dispose(); + }); + })); it('should support empty template', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -1401,285 +1408,285 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support templateUrl fetched from $templateCache', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); - ng1Module.run(($templateCache: any) => $templateCache.put('url.html', 'WORKS')); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support templateUrl fetched from $templateCache', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); + ng1Module.run(($templateCache: any) => $templateCache.put('url.html', 'WORKS')); - const ng1 = () => { return {templateUrl: 'url.html'}; }; - ng1Module.directive('ng1', ng1); + const ng1 = () => { return {templateUrl: 'url.html'}; }; + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('WORKS'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('WORKS'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support controller with controllerAs', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support controller with controllerAs', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - scope: true, - template: - '{{ctl.scope}}; {{ctl.isClass}}; {{ctl.hasElement}}; {{ctl.isPublished()}}', - controllerAs: 'ctl', - controller: class { - scope: any; hasElement: string; $element: any; isClass: any; - constructor($scope: any, $element: any) { - this.verifyIAmAClass(); - this.scope = - $scope.$parent.$parent == $scope.$root ? 'scope' : 'wrong-scope'; - this.hasElement = $element[0].nodeName; - this.$element = $element; - } verifyIAmAClass() { this.isClass = 'isClass'; } isPublished() { - return this.$element.controller('ng1') == this ? 'published' : - 'not-published'; - } - } - }; - }; - ng1Module.directive('ng1', ng1); + const ng1 = () => { + return { + scope: true, + template: + '{{ctl.scope}}; {{ctl.isClass}}; {{ctl.hasElement}}; {{ctl.isPublished()}}', + controllerAs: 'ctl', + controller: class { + scope: any; hasElement: string; $element: any; isClass: any; + constructor($scope: any, $element: any) { + this.verifyIAmAClass(); + this.scope = + $scope.$parent.$parent == $scope.$root ? 'scope' : 'wrong-scope'; + this.hasElement = $element[0].nodeName; + this.$element = $element; + } verifyIAmAClass() { this.isClass = 'isClass'; } isPublished() { + return this.$element.controller('ng1') == this ? 'published' : + 'not-published'; + } + } + }; + }; + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)) - .toEqual('scope; isClass; NG1; published'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)) + .toEqual('scope; isClass; NG1; published'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support bindToController', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support bindToController', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - scope: {title: '@'}, - bindToController: true, - template: '{{ctl.title}}', - controllerAs: 'ctl', - controller: class {} - }; - }; - ng1Module.directive('ng1', ng1); + const ng1 = () => { + return { + scope: {title: '@'}, + bindToController: true, + template: '{{ctl.title}}', + controllerAs: 'ctl', + controller: class {} + }; + }; + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('WORKS'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('WORKS'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support bindToController with bindings', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support bindToController with bindings', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = () => { - return { - scope: {}, - bindToController: {title: '@'}, - template: '{{ctl.title}}', - controllerAs: 'ctl', - controller: class {} - }; - }; - ng1Module.directive('ng1', ng1); + const ng1 = () => { + return { + scope: {}, + bindToController: {title: '@'}, + template: '{{ctl.title}}', + controllerAs: 'ctl', + controller: class {} + }; + }; + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('WORKS'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('WORKS'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support single require in linking fn', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support single require in linking fn', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = ($rootScope: any) => { - return { - scope: {title: '@'}, - bindToController: true, - template: '{{ctl.status}}', - require: 'ng1', - controllerAs: 'ctrl', - controller: class {status = 'WORKS';}, - link: function(scope: any, element: any, attrs: any, linkController: any) { - expect(scope.$root).toEqual($rootScope); - expect(element[0].nodeName).toEqual('NG1'); - expect(linkController.status).toEqual('WORKS'); - scope.ctl = linkController; - } - }; - }; - ng1Module.directive('ng1', ng1); + const ng1 = ($rootScope: any) => { + return { + scope: {title: '@'}, + bindToController: true, + template: '{{ctl.status}}', + require: 'ng1', + controllerAs: 'ctrl', + controller: class {status = 'WORKS';}, + link: function(scope: any, element: any, attrs: any, linkController: any) { + expect(scope.$root).toEqual($rootScope); + expect(element[0].nodeName).toEqual('NG1'); + expect(linkController.status).toEqual('WORKS'); + scope.ctl = linkController; + } + }; + }; + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('WORKS'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('WORKS'); + ref.dispose(); + }); + })); - fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && - it('should support array require in linking fn', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-724: upgraded ng1 components are not being rendered') + .it('should support array require in linking fn', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const parent = () => { return {controller: class {parent = 'PARENT';}}; }; - const ng1 = () => { - return { - scope: {title: '@'}, - bindToController: true, - template: '{{parent.parent}}:{{ng1.status}}', - require: ['ng1', '^parent', '?^^notFound'], - controllerAs: 'ctrl', - controller: class {status = 'WORKS';}, - link: function(scope: any, element: any, attrs: any, linkControllers: any) { - expect(linkControllers[0].status).toEqual('WORKS'); - expect(linkControllers[1].parent).toEqual('PARENT'); - expect(linkControllers[2]).toBe(undefined); - scope.ng1 = linkControllers[0]; - scope.parent = linkControllers[1]; - } - }; - }; - ng1Module.directive('parent', parent); - ng1Module.directive('ng1', ng1); + const parent = () => { return {controller: class {parent = 'PARENT';}}; }; + const ng1 = () => { + return { + scope: {title: '@'}, + bindToController: true, + template: '{{parent.parent}}:{{ng1.status}}', + require: ['ng1', '^parent', '?^^notFound'], + controllerAs: 'ctrl', + controller: class {status = 'WORKS';}, + link: function(scope: any, element: any, attrs: any, linkControllers: any) { + expect(linkControllers[0].status).toEqual('WORKS'); + expect(linkControllers[1].parent).toEqual('PARENT'); + expect(linkControllers[2]).toBe(undefined); + scope.ng1 = linkControllers[0]; + scope.parent = linkControllers[1]; + } + }; + }; + ng1Module.directive('parent', parent); + ng1Module.directive('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('PARENT:WORKS'); - ref.dispose(); - }); - })); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('PARENT:WORKS'); + ref.dispose(); + }); + })); describe('with lifecycle hooks', () => { - fixmeIvy('unknown') && - it('should call `$onInit()` on controller', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $onInitSpyA = jasmine.createSpy('$onInitA'); - const $onInitSpyB = jasmine.createSpy('$onInitB'); + fixmeIvy('unknown').it( + 'should call `$onInit()` on controller', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $onInitSpyA = jasmine.createSpy('$onInitA'); + const $onInitSpyB = jasmine.createSpy('$onInitB'); - @Component({selector: 'ng2', template: ' | '}) - class Ng2Component { - } + @Component({selector: 'ng2', template: ' | '}) + class Ng2Component { + } - angular.module('ng1', []) - .directive('ng1A', () => ({ - template: '', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: class {$onInit() { $onInitSpyA(); }} - })) - .directive('ng1B', () => ({ - template: '', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: function() { this.$onInit = $onInitSpyB; } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + angular.module('ng1', []) + .directive('ng1A', () => ({ + template: '', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: class {$onInit() { $onInitSpyA(); }} + })) + .directive('ng1B', () => ({ + template: '', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: function() { this.$onInit = $onInitSpyB; } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect($onInitSpyA).toHaveBeenCalled(); - expect($onInitSpyB).toHaveBeenCalled(); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect($onInitSpyA).toHaveBeenCalled(); + expect($onInitSpyB).toHaveBeenCalled(); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); it('should not call `$onInit()` on scope', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -1727,60 +1734,60 @@ withEachNg1Version(() => { }); })); - fixmeIvy('unknown') && - it('should call `$doCheck()` on controller', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $doCheckSpyA = jasmine.createSpy('$doCheckA'); - const $doCheckSpyB = jasmine.createSpy('$doCheckB'); - let changeDetector: ChangeDetectorRef; + fixmeIvy('unknown').it( + 'should call `$doCheck()` on controller', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $doCheckSpyA = jasmine.createSpy('$doCheckA'); + const $doCheckSpyB = jasmine.createSpy('$doCheckB'); + let changeDetector: ChangeDetectorRef; - @Component({selector: 'ng2', template: ' | '}) - class Ng2Component { - constructor(cd: ChangeDetectorRef) { changeDetector = cd; } - } + @Component({selector: 'ng2', template: ' | '}) + class Ng2Component { + constructor(cd: ChangeDetectorRef) { changeDetector = cd; } + } - angular.module('ng1', []) - .directive('ng1A', () => ({ - template: '', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: class {$doCheck() { $doCheckSpyA(); }} - })) - .directive('ng1B', () => ({ - template: '', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: function() { this.$doCheck = $doCheckSpyB; } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + angular.module('ng1', []) + .directive('ng1A', () => ({ + template: '', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: class {$doCheck() { $doCheckSpyA(); }} + })) + .directive('ng1B', () => ({ + template: '', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: function() { this.$doCheck = $doCheckSpyB; } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect($doCheckSpyA).toHaveBeenCalled(); - expect($doCheckSpyB).toHaveBeenCalled(); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect($doCheckSpyA).toHaveBeenCalled(); + expect($doCheckSpyB).toHaveBeenCalled(); - $doCheckSpyA.calls.reset(); - $doCheckSpyB.calls.reset(); - changeDetector.detectChanges(); + $doCheckSpyA.calls.reset(); + $doCheckSpyB.calls.reset(); + changeDetector.detectChanges(); - expect($doCheckSpyA).toHaveBeenCalled(); - expect($doCheckSpyB).toHaveBeenCalled(); + expect($doCheckSpyA).toHaveBeenCalled(); + expect($doCheckSpyB).toHaveBeenCalled(); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); it('should not call `$doCheck()` on scope', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -1837,51 +1844,51 @@ withEachNg1Version(() => { }); })); - fixmeIvy('unknown') && - it('should call `$postLink()` on controller', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $postLinkSpyA = jasmine.createSpy('$postLinkA'); - const $postLinkSpyB = jasmine.createSpy('$postLinkB'); + fixmeIvy('unknown').it( + 'should call `$postLink()` on controller', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $postLinkSpyA = jasmine.createSpy('$postLinkA'); + const $postLinkSpyB = jasmine.createSpy('$postLinkB'); - @Component({selector: 'ng2', template: ' | '}) - class Ng2Component { - } + @Component({selector: 'ng2', template: ' | '}) + class Ng2Component { + } - angular.module('ng1', []) - .directive('ng1A', () => ({ - template: '', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: class {$postLink() { $postLinkSpyA(); }} - })) - .directive('ng1B', () => ({ - template: '', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: function() { this.$postLink = $postLinkSpyB; } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + angular.module('ng1', []) + .directive('ng1A', () => ({ + template: '', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: class {$postLink() { $postLinkSpyA(); }} + })) + .directive('ng1B', () => ({ + template: '', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: function() { this.$postLink = $postLinkSpyB; } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect($postLinkSpyA).toHaveBeenCalled(); - expect($postLinkSpyB).toHaveBeenCalled(); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect($postLinkSpyA).toHaveBeenCalled(); + expect($postLinkSpyB).toHaveBeenCalled(); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); it('should not call `$postLink()` on scope', async(() => { const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); @@ -1929,804 +1936,799 @@ withEachNg1Version(() => { }); })); - fixmeIvy('unknown') && - it('should call `$onChanges()` on binding destination', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $onChangesControllerSpyA = jasmine.createSpy('$onChangesControllerA'); - const $onChangesControllerSpyB = jasmine.createSpy('$onChangesControllerB'); - const $onChangesScopeSpy = jasmine.createSpy('$onChangesScope'); - let ng2Instance: any; + fixmeIvy('unknown').it( + 'should call `$onChanges()` on binding destination', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $onChangesControllerSpyA = jasmine.createSpy('$onChangesControllerA'); + const $onChangesControllerSpyB = jasmine.createSpy('$onChangesControllerB'); + const $onChangesScopeSpy = jasmine.createSpy('$onChangesScope'); + let ng2Instance: any; - @Component({ - selector: 'ng2', - template: ' | ' - }) - class Ng2Component { - constructor() { ng2Instance = this; } - } + @Component({ + selector: 'ng2', + template: ' | ' + }) + class Ng2Component { + constructor() { ng2Instance = this; } + } - angular.module('ng1', []) - .directive('ng1A', () => ({ - template: '', - scope: {valA: '<'}, - bindToController: true, - controllerAs: '$ctrl', - controller: function($scope: angular.IScope) { - this.$onChanges = $onChangesControllerSpyA; - } - })) - .directive('ng1B', () => ({ - template: '', - scope: {valB: '<'}, - bindToController: false, - controllerAs: '$ctrl', - controller: class { - $onChanges(changes: SimpleChanges) { - $onChangesControllerSpyB(changes); - } - } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)) - .run(($rootScope: angular.IRootScopeService) => { - Object.getPrototypeOf($rootScope).$onChanges = $onChangesScopeSpy; - }); + angular.module('ng1', []) + .directive('ng1A', () => ({ + template: '', + scope: {valA: '<'}, + bindToController: true, + controllerAs: '$ctrl', + controller: function($scope: angular.IScope) { + this.$onChanges = $onChangesControllerSpyA; + } + })) + .directive( + 'ng1B', + () => ({ + template: '', + scope: {valB: '<'}, + bindToController: false, + controllerAs: '$ctrl', + controller: class { + $onChanges(changes: SimpleChanges) { $onChangesControllerSpyB(changes); } + } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)) + .run(($rootScope: angular.IRootScopeService) => { + Object.getPrototypeOf($rootScope).$onChanges = $onChangesScopeSpy; + }); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - // Initial `$onChanges()` call - tick(); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + // Initial `$onChanges()` call + tick(); - expect($onChangesControllerSpyA.calls.count()).toBe(1); - expect($onChangesControllerSpyA.calls.argsFor(0)[0]).toEqual({ - valA: jasmine.any(SimpleChange) - }); + expect($onChangesControllerSpyA.calls.count()).toBe(1); + expect($onChangesControllerSpyA.calls.argsFor(0)[0]).toEqual({ + valA: jasmine.any(SimpleChange) + }); - expect($onChangesControllerSpyB).not.toHaveBeenCalled(); + expect($onChangesControllerSpyB).not.toHaveBeenCalled(); - expect($onChangesScopeSpy.calls.count()).toBe(1); - expect($onChangesScopeSpy.calls.argsFor(0)[0]).toEqual({ - valB: jasmine.any(SimpleChange) - }); + expect($onChangesScopeSpy.calls.count()).toBe(1); + expect($onChangesScopeSpy.calls.argsFor(0)[0]).toEqual({ + valB: jasmine.any(SimpleChange) + }); - $onChangesControllerSpyA.calls.reset(); - $onChangesControllerSpyB.calls.reset(); - $onChangesScopeSpy.calls.reset(); + $onChangesControllerSpyA.calls.reset(); + $onChangesControllerSpyB.calls.reset(); + $onChangesScopeSpy.calls.reset(); - // `$onChanges()` call after a change - ng2Instance.val = 'new value'; - tick(); - ref.ng1RootScope.$digest(); + // `$onChanges()` call after a change + ng2Instance.val = 'new value'; + tick(); + ref.ng1RootScope.$digest(); - expect($onChangesControllerSpyA.calls.count()).toBe(1); - expect($onChangesControllerSpyA.calls.argsFor(0)[0]).toEqual({ - valA: jasmine.objectContaining({currentValue: 'new value'}) - }); + expect($onChangesControllerSpyA.calls.count()).toBe(1); + expect($onChangesControllerSpyA.calls.argsFor(0)[0]).toEqual({ + valA: jasmine.objectContaining({currentValue: 'new value'}) + }); - expect($onChangesControllerSpyB).not.toHaveBeenCalled(); + expect($onChangesControllerSpyB).not.toHaveBeenCalled(); - expect($onChangesScopeSpy.calls.count()).toBe(1); - expect($onChangesScopeSpy.calls.argsFor(0)[0]).toEqual({ - valB: jasmine.objectContaining({currentValue: 'new value'}) - }); + expect($onChangesScopeSpy.calls.count()).toBe(1); + expect($onChangesScopeSpy.calls.argsFor(0)[0]).toEqual({ + valB: jasmine.objectContaining({currentValue: 'new value'}) + }); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('unknown') && - it('should call `$onDestroy()` on controller', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $onDestroySpyA = jasmine.createSpy('$onDestroyA'); - const $onDestroySpyB = jasmine.createSpy('$onDestroyB'); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('unknown').it( + 'should call `$onDestroy()` on controller', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $onDestroySpyA = jasmine.createSpy('$onDestroyA'); + const $onDestroySpyB = jasmine.createSpy('$onDestroyB'); + let ng2ComponentInstance: Ng2Component; - @Component({ - selector: 'ng2', - template: ` + @Component({ + selector: 'ng2', + template: `
|
` - }) - class Ng2Component { - ng2Destroy: boolean = false; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + ng2Destroy: boolean = false; + constructor() { ng2ComponentInstance = this; } + } - // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), - // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be - // on - // the queue at the end of the test, causing it to fail. - // Mocking animations (via `ngAnimateMock`) avoids the issue. - angular.module('ng1', ['ngAnimateMock']) - .directive('ng1A', () => ({ - template: '', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: class {$onDestroy() { $onDestroySpyA(); }} - })) - .directive( - 'ng1B', () => ({ - template: '', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: function() { this.$onDestroy = $onDestroySpyB; } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), + // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be + // on + // the queue at the end of the test, causing it to fail. + // Mocking animations (via `ngAnimateMock`) avoids the issue. + angular.module('ng1', ['ngAnimateMock']) + .directive('ng1A', () => ({ + template: '', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: class {$onDestroy() { $onDestroySpyA(); }} + })) + .directive('ng1B', () => ({ + template: '', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: function() { this.$onDestroy = $onDestroySpyB; } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; - $rootScope.ng1Destroy = false; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = false; + tick(); + $rootScope.$digest(); - expect($onDestroySpyA).not.toHaveBeenCalled(); - expect($onDestroySpyB).not.toHaveBeenCalled(); + expect($onDestroySpyA).not.toHaveBeenCalled(); + expect($onDestroySpyB).not.toHaveBeenCalled(); - $rootScope.ng1Destroy = true; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = true; + tick(); + $rootScope.$digest(); - expect($onDestroySpyA).toHaveBeenCalled(); - expect($onDestroySpyB).toHaveBeenCalled(); + expect($onDestroySpyA).toHaveBeenCalled(); + expect($onDestroySpyB).toHaveBeenCalled(); - $onDestroySpyA.calls.reset(); - $onDestroySpyB.calls.reset(); + $onDestroySpyA.calls.reset(); + $onDestroySpyB.calls.reset(); - $rootScope.ng1Destroy = false; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = false; + tick(); + $rootScope.$digest(); - expect($onDestroySpyA).not.toHaveBeenCalled(); - expect($onDestroySpyB).not.toHaveBeenCalled(); + expect($onDestroySpyA).not.toHaveBeenCalled(); + expect($onDestroySpyB).not.toHaveBeenCalled(); - ng2ComponentInstance.ng2Destroy = true; - tick(); - $rootScope.$digest(); + ng2ComponentInstance.ng2Destroy = true; + tick(); + $rootScope.$digest(); - expect($onDestroySpyA).toHaveBeenCalled(); - expect($onDestroySpyB).toHaveBeenCalled(); + expect($onDestroySpyA).toHaveBeenCalled(); + expect($onDestroySpyB).toHaveBeenCalled(); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); - fixmeIvy('unknown') && - it('should not call `$onDestroy()` on scope', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const $onDestroySpy = jasmine.createSpy('$onDestroy'); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('unknown').it( + 'should not call `$onDestroy()` on scope', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const $onDestroySpy = jasmine.createSpy('$onDestroy'); + let ng2ComponentInstance: Ng2Component; - @Component({ - selector: 'ng2', - template: ` + @Component({ + selector: 'ng2', + template: `
|
` - }) - class Ng2Component { - ng2Destroy: boolean = false; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + ng2Destroy: boolean = false; + constructor() { ng2ComponentInstance = this; } + } - // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), - // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be - // on - // the queue at the end of the test, causing it to fail. - // Mocking animations (via `ngAnimateMock`) avoids the issue. - angular.module('ng1', ['ngAnimateMock']) - .directive('ng1A', () => ({ - template: '', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: function($scope: angular.IScope) { - Object.getPrototypeOf($scope).$onDestroy = - $onDestroySpy; - } - })) - .directive('ng1B', () => ({ - template: '', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: function($scope: angular.IScope) { - $scope['$onDestroy'] = $onDestroySpy; - } - })) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), + // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be + // on + // the queue at the end of the test, causing it to fail. + // Mocking animations (via `ngAnimateMock`) avoids the issue. + angular.module('ng1', ['ngAnimateMock']) + .directive('ng1A', () => ({ + template: '', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: function($scope: angular.IScope) { + Object.getPrototypeOf($scope).$onDestroy = $onDestroySpy; + } + })) + .directive('ng1B', () => ({ + template: '', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: function($scope: angular.IScope) { + $scope['$onDestroy'] = $onDestroySpy; + } + })) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [ - adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), - Ng2Component - ], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [ + adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'), + Ng2Component + ], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; - $rootScope.ng1Destroy = false; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = false; + tick(); + $rootScope.$digest(); - $rootScope.ng1Destroy = true; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = true; + tick(); + $rootScope.$digest(); - $rootScope.ng1Destroy = false; - tick(); - $rootScope.$digest(); + $rootScope.ng1Destroy = false; + tick(); + $rootScope.$digest(); - ng2ComponentInstance.ng2Destroy = true; - tick(); - $rootScope.$digest(); + ng2ComponentInstance.ng2Destroy = true; + tick(); + $rootScope.$digest(); - expect($onDestroySpy).not.toHaveBeenCalled(); + expect($onDestroySpy).not.toHaveBeenCalled(); - ref.dispose(); - }); - })); + ref.dispose(); + }); + })); }); describe('destroying the upgraded component', () => { - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should destroy `componentScope`', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const scopeDestroyListener = jasmine.createSpy('scopeDestroyListener'); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should destroy `componentScope`', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const scopeDestroyListener = jasmine.createSpy('scopeDestroyListener'); + let ng2ComponentInstance: Ng2Component; - @Component( - {selector: 'ng2', template: '
'}) - class Ng2Component { - ng2Destroy: boolean = false; - constructor() { ng2ComponentInstance = this; } - } + @Component( + {selector: 'ng2', template: '
'}) + class Ng2Component { + ng2Destroy: boolean = false; + constructor() { ng2ComponentInstance = this; } + } - // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), - // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be - // on - // the queue at the end of the test, causing it to fail. - // Mocking animations (via `ngAnimateMock`) avoids the issue. - angular.module('ng1', ['ngAnimateMock']) - .component('ng1', { - controller: function($scope: angular.IScope) { - $scope.$on('$destroy', scopeDestroyListener); - }, - }) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), + // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be + // on + // the queue at the end of the test, causing it to fail. + // Mocking animations (via `ngAnimateMock`) avoids the issue. + angular.module('ng1', ['ngAnimateMock']) + .component('ng1', { + controller: function($scope: angular.IScope) { + $scope.$on('$destroy', scopeDestroyListener); + }, + }) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(''); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; + const element = html(''); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; - expect(scopeDestroyListener).not.toHaveBeenCalled(); + expect(scopeDestroyListener).not.toHaveBeenCalled(); - ng2ComponentInstance.ng2Destroy = true; - tick(); - $rootScope.$digest(); + ng2ComponentInstance.ng2Destroy = true; + tick(); + $rootScope.$digest(); - expect(scopeDestroyListener).toHaveBeenCalledTimes(1); - }); - })); + expect(scopeDestroyListener).toHaveBeenCalledTimes(1); + }); + })); - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should emit `$destroy` on `$element` and descendants', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const elementDestroyListener = jasmine.createSpy('elementDestroyListener'); - const descendantDestroyListener = jasmine.createSpy('descendantDestroyListener'); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should emit `$destroy` on `$element` and descendants', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const elementDestroyListener = jasmine.createSpy('elementDestroyListener'); + const descendantDestroyListener = jasmine.createSpy('descendantDestroyListener'); + let ng2ComponentInstance: Ng2Component; - @Component( - {selector: 'ng2', template: '
'}) - class Ng2Component { - ng2Destroy: boolean = false; - constructor() { ng2ComponentInstance = this; } - } + @Component( + {selector: 'ng2', template: '
'}) + class Ng2Component { + ng2Destroy: boolean = false; + constructor() { ng2ComponentInstance = this; } + } - // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), - // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be - // on - // the queue at the end of the test, causing it to fail. - // Mocking animations (via `ngAnimateMock`) avoids the issue. - angular.module('ng1', ['ngAnimateMock']) - .component('ng1', { - controller: class { - constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { - this.$element.on !('$destroy', elementDestroyListener); - this.$element.contents !().on !('$destroy', descendantDestroyListener); - } - }, - template: '
' - }) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // On browsers that don't support `requestAnimationFrame` (IE 9, Android <= 4.3), + // `$animate` will use `setTimeout(..., 16.6)` instead. This timeout will still be + // on + // the queue at the end of the test, causing it to fail. + // Mocking animations (via `ngAnimateMock`) avoids the issue. + angular.module('ng1', ['ngAnimateMock']) + .component('ng1', { + controller: class { + constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { + this.$element.on !('$destroy', elementDestroyListener); + this.$element.contents !().on !('$destroy', descendantDestroyListener); + } + }, + template: '
' + }) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(''); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; - tick(); - $rootScope.$digest(); + const element = html(''); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; + tick(); + $rootScope.$digest(); - expect(elementDestroyListener).not.toHaveBeenCalled(); - expect(descendantDestroyListener).not.toHaveBeenCalled(); + expect(elementDestroyListener).not.toHaveBeenCalled(); + expect(descendantDestroyListener).not.toHaveBeenCalled(); - ng2ComponentInstance.ng2Destroy = true; - tick(); - $rootScope.$digest(); + ng2ComponentInstance.ng2Destroy = true; + tick(); + $rootScope.$digest(); - expect(elementDestroyListener).toHaveBeenCalledTimes(1); - expect(descendantDestroyListener).toHaveBeenCalledTimes(1); - }); - })); + expect(elementDestroyListener).toHaveBeenCalledTimes(1); + expect(descendantDestroyListener).toHaveBeenCalledTimes(1); + }); + })); - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should clear data on `$element` and descendants', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng1ComponentElement: angular.IAugmentedJQuery; - let ng2ComponentAInstance: Ng2ComponentA; + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should clear data on `$element` and descendants', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng1ComponentElement: angular.IAugmentedJQuery; + let ng2ComponentAInstance: Ng2ComponentA; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - controller: class { - constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { - this.$element.data !('test', 1); - this.$element.contents !().data !('test', 2); + // Define `ng1Component` + const ng1Component: angular.IComponent = { + controller: class { + constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { + this.$element.data !('test', 1); + this.$element.contents !().data !('test', 2); - ng1ComponentElement = this.$element; - } - }, - template: '
' - }; + ng1ComponentElement = this.$element; + } + }, + template: '
' + }; - // Define `Ng2Component` - @Component({selector: 'ng2A', template: ''}) - class Ng2ComponentA { - destroyIt = false; + // Define `Ng2Component` + @Component({selector: 'ng2A', template: ''}) + class Ng2ComponentA { + destroyIt = false; - constructor() { ng2ComponentAInstance = this; } - } + constructor() { ng2ComponentAInstance = this; } + } - @Component({selector: 'ng2B', template: ''}) - class Ng2ComponentB { - } + @Component({selector: 'ng2B', template: ''}) + class Ng2ComponentB { + } - // Define `ng1Module` - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); + // Define `ng1Module` + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], - entryComponents: [Ng2ComponentA], - imports: [BrowserModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // Define `Ng2Module` + @NgModule({ + declarations: + [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], + entryComponents: [Ng2ComponentA], + imports: [BrowserModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; - tick(); - $rootScope.$digest(); - expect(ng1ComponentElement.data !('test')).toBe(1); - expect(ng1ComponentElement.contents !().data !('test')).toBe(2); + adapter.bootstrap(element, ['ng1Module']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; + tick(); + $rootScope.$digest(); + expect(ng1ComponentElement.data !('test')).toBe(1); + expect(ng1ComponentElement.contents !().data !('test')).toBe(2); - ng2ComponentAInstance.destroyIt = true; - tick(); - $rootScope.$digest(); + ng2ComponentAInstance.destroyIt = true; + tick(); + $rootScope.$digest(); - expect(ng1ComponentElement.data !('test')).toBeUndefined(); - expect(ng1ComponentElement.contents !().data !('test')).toBeUndefined(); - }); - })); + expect(ng1ComponentElement.data !('test')).toBeUndefined(); + expect(ng1ComponentElement.contents !().data !('test')).toBeUndefined(); + }); + })); - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should clear dom listeners on `$element` and descendants`', fakeAsync(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const elementClickListener = jasmine.createSpy('elementClickListener'); - const descendantClickListener = jasmine.createSpy('descendantClickListener'); - let ng1DescendantElement: angular.IAugmentedJQuery; - let ng2ComponentAInstance: Ng2ComponentA; + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should clear dom listeners on `$element` and descendants`', fakeAsync(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const elementClickListener = jasmine.createSpy('elementClickListener'); + const descendantClickListener = jasmine.createSpy('descendantClickListener'); + let ng1DescendantElement: angular.IAugmentedJQuery; + let ng2ComponentAInstance: Ng2ComponentA; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - controller: class { - constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { - ng1DescendantElement = this.$element.contents !(); + // Define `ng1Component` + const ng1Component: angular.IComponent = { + controller: class { + constructor(private $element: angular.IAugmentedJQuery) {} $onInit() { + ng1DescendantElement = this.$element.contents !(); - this.$element.on !('click', elementClickListener); - ng1DescendantElement.on !('click', descendantClickListener); - } - }, - template: '
' - }; + this.$element.on !('click', elementClickListener); + ng1DescendantElement.on !('click', descendantClickListener); + } + }, + template: '
' + }; - // Define `Ng2Component` - @Component({selector: 'ng2A', template: ''}) - class Ng2ComponentA { - destroyIt = false; + // Define `Ng2Component` + @Component({selector: 'ng2A', template: ''}) + class Ng2ComponentA { + destroyIt = false; - constructor() { ng2ComponentAInstance = this; } - } + constructor() { ng2ComponentAInstance = this; } + } - @Component({selector: 'ng2B', template: ''}) - class Ng2ComponentB { - } + @Component({selector: 'ng2B', template: ''}) + class Ng2ComponentB { + } - // Define `ng1Module` - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); + // Define `ng1Module` + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); - // Define `Ng2Module` - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], - entryComponents: [Ng2ComponentA], - imports: [BrowserModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // Define `Ng2Module` + @NgModule({ + declarations: + [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], + entryComponents: [Ng2ComponentA], + imports: [BrowserModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready((ref) => { - const $rootScope = ref.ng1RootScope as any; - tick(); - $rootScope.$digest(); - (ng1DescendantElement[0] as HTMLElement).click(); - expect(elementClickListener).toHaveBeenCalledTimes(1); - expect(descendantClickListener).toHaveBeenCalledTimes(1); + adapter.bootstrap(element, ['ng1Module']).ready((ref) => { + const $rootScope = ref.ng1RootScope as any; + tick(); + $rootScope.$digest(); + (ng1DescendantElement[0] as HTMLElement).click(); + expect(elementClickListener).toHaveBeenCalledTimes(1); + expect(descendantClickListener).toHaveBeenCalledTimes(1); - ng2ComponentAInstance.destroyIt = true; - tick(); - $rootScope.$digest(); + ng2ComponentAInstance.destroyIt = true; + tick(); + $rootScope.$digest(); - (ng1DescendantElement[0] as HTMLElement).click(); - expect(elementClickListener).toHaveBeenCalledTimes(1); - expect(descendantClickListener).toHaveBeenCalledTimes(1); - }); - })); + (ng1DescendantElement[0] as HTMLElement).click(); + expect(elementClickListener).toHaveBeenCalledTimes(1); + expect(descendantClickListener).toHaveBeenCalledTimes(1); + }); + })); }); describe('linking', () => { - fixmeIvy('unknown') && - it('should run the pre-linking after instantiating the controller', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const log: string[] = []; + fixmeIvy('unknown').it( + 'should run the pre-linking after instantiating the controller', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const log: string[] = []; - // Define `ng1Directive` - const ng1Directive: angular.IDirective = { - template: '', - link: {pre: () => log.push('ng1-pre')}, - controller: class {constructor() { log.push('ng1-ctrl'); }} - }; + // Define `ng1Directive` + const ng1Directive: angular.IDirective = { + template: '', + link: {pre: () => log.push('ng1-pre')}, + controller: class {constructor() { log.push('ng1-ctrl'); }} + }; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1', []) - .directive('ng1', () => ng1Directive) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = angular.module('ng1', []) + .directive('ng1', () => ng1Directive) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1']).ready(() => { - setTimeout(() => expect(log).toEqual(['ng1-ctrl', 'ng1-pre']), 1000); - }); - })); + adapter.bootstrap(element, ['ng1']).ready(() => { + setTimeout(() => expect(log).toEqual(['ng1-ctrl', 'ng1-pre']), 1000); + }); + })); - fixmeIvy('unknown') && - it('should run the pre-linking function before linking', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const log: string[] = []; + fixmeIvy('unknown').it( + 'should run the pre-linking function before linking', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const log: string[] = []; - // Define `ng1Directive` - const ng1DirectiveA: angular.IDirective = { - template: '', - link: {pre: () => log.push('ng1A-pre')} - }; + // Define `ng1Directive` + const ng1DirectiveA: angular.IDirective = { + template: '', + link: {pre: () => log.push('ng1A-pre')} + }; - const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; + const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1', []) - .directive('ng1A', () => ng1DirectiveA) - .directive('ng1B', () => ng1DirectiveB) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = angular.module('ng1', []) + .directive('ng1A', () => ng1DirectiveA) + .directive('ng1B', () => ng1DirectiveB) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1']).ready(() => { - expect(log).toEqual(['ng1A-pre', 'ng1B-post']); - }); - })); + adapter.bootstrap(element, ['ng1']).ready(() => { + expect(log).toEqual(['ng1A-pre', 'ng1B-post']); + }); + })); - fixmeIvy('unknown') && - it('should run the post-linking function after linking (link: object)', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const log: string[] = []; + fixmeIvy('unknown').it( + 'should run the post-linking function after linking (link: object)', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const log: string[] = []; - // Define `ng1Directive` - const ng1DirectiveA: angular.IDirective = { - template: '', - link: {post: () => log.push('ng1A-post')} - }; + // Define `ng1Directive` + const ng1DirectiveA: angular.IDirective = { + template: '', + link: {post: () => log.push('ng1A-post')} + }; - const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; + const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1', []) - .directive('ng1A', () => ng1DirectiveA) - .directive('ng1B', () => ng1DirectiveB) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = angular.module('ng1', []) + .directive('ng1A', () => ng1DirectiveA) + .directive('ng1B', () => ng1DirectiveB) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1']).ready(() => { - expect(log).toEqual(['ng1B-post', 'ng1A-post']); - }); - })); + adapter.bootstrap(element, ['ng1']).ready(() => { + expect(log).toEqual(['ng1B-post', 'ng1A-post']); + }); + })); - fixmeIvy('unknown') && - it('should run the post-linking function after linking (link: function)', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const log: string[] = []; + fixmeIvy('unknown').it( + 'should run the post-linking function after linking (link: function)', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const log: string[] = []; - // Define `ng1Directive` - const ng1DirectiveA: angular.IDirective = { - template: '', - link: () => log.push('ng1A-post') - }; + // Define `ng1Directive` + const ng1DirectiveA: angular.IDirective = { + template: '', + link: () => log.push('ng1A-post') + }; - const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; + const ng1DirectiveB: angular.IDirective = {link: () => log.push('ng1B-post')}; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1', []) - .directive('ng1A', () => ng1DirectiveA) - .directive('ng1B', () => ng1DirectiveB) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = angular.module('ng1', []) + .directive('ng1A', () => ng1DirectiveA) + .directive('ng1B', () => ng1DirectiveB) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1A'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1']).ready(() => { - expect(log).toEqual(['ng1B-post', 'ng1A-post']); - }); - })); + adapter.bootstrap(element, ['ng1']).ready(() => { + expect(log).toEqual(['ng1B-post', 'ng1A-post']); + }); + })); - fixmeIvy('unknown') && - it('should run the post-linking function before `$postLink`', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const log: string[] = []; + fixmeIvy('unknown').it( + 'should run the post-linking function before `$postLink`', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const log: string[] = []; - // Define `ng1Directive` - const ng1Directive: angular.IDirective = { - template: '', - link: () => log.push('ng1-post'), - controller: class {$postLink() { log.push('ng1-$post'); }} - }; + // Define `ng1Directive` + const ng1Directive: angular.IDirective = { + template: '', + link: () => log.push('ng1-post'), + controller: class {$postLink() { log.push('ng1-$post'); }} + }; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1', []) - .directive('ng1', () => ng1Directive) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = angular.module('ng1', []) + .directive('ng1', () => ng1Directive) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1']).ready(() => { - expect(log).toEqual(['ng1-post', 'ng1-$post']); - }); - })); + adapter.bootstrap(element, ['ng1']).ready(() => { + expect(log).toEqual(['ng1-post', 'ng1-$post']); + }); + })); }); describe('transclusion', () => { - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support single-slot transclusion', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentAInstance: Ng2ComponentA; - let ng2ComponentBInstance: Ng2ComponentB; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support single-slot transclusion', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentAInstance: Ng2ComponentA; + let ng2ComponentBInstance: Ng2ComponentB; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'ng1(
)', - transclude: true - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'ng1(
)', + transclude: true + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2A', - template: 'ng2A({{ value }} | )' - }) - class Ng2ComponentA { - value = 'foo'; - showB = false; - constructor() { ng2ComponentAInstance = this; } - } + // Define `Ng2Component` + @Component({ + selector: 'ng2A', + template: 'ng2A({{ value }} | )' + }) + class Ng2ComponentA { + value = 'foo'; + showB = false; + constructor() { ng2ComponentAInstance = this; } + } - @Component({selector: 'ng2B', template: 'ng2B({{ value }})'}) - class Ng2ComponentB { - value = 'bar'; - constructor() { ng2ComponentBInstance = this; } - } + @Component({selector: 'ng2B', template: 'ng2B({{ value }})'}) + class Ng2ComponentB { + value = 'bar'; + constructor() { ng2ComponentBInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2A', adapter.downgradeNg2Component(Ng2ComponentA)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: - [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: + [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready((ref) => { - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(foo | ))'); + adapter.bootstrap(element, ['ng1Module']).ready((ref) => { + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(foo | ))'); - ng2ComponentAInstance.value = 'baz'; - ng2ComponentAInstance.showB = true; - $digest(ref); + ng2ComponentAInstance.value = 'baz'; + ng2ComponentAInstance.showB = true; + $digest(ref); - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(bar)))'); + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(bar)))'); - ng2ComponentBInstance.value = 'qux'; - $digest(ref); + ng2ComponentBInstance.value = 'qux'; + $digest(ref); - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(qux)))'); - }); - })); + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(qux)))'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support single-slot transclusion with fallback content', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng1ControllerInstances: any[] = []; - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support single-slot transclusion with fallback content', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng1ControllerInstances: any[] = []; + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'ng1(
{{ $ctrl.value }}
)', - transclude: true, - controller: class { - value = 'from-ng1'; constructor() { ng1ControllerInstances.push(this); } - } - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'ng1(
{{ $ctrl.value }}
)', + transclude: true, + controller: class { + value = 'from-ng1'; constructor() { ng1ControllerInstances.push(this); } + } + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2(
{{ value }}
| @@ -2735,58 +2737,58 @@ withEachNg1Version(() => { )` - }) - class Ng2Component { - value = 'from-ng2'; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + value = 'from-ng2'; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(from-ng2)|ng1(from-ng2)|ng1(from-ng1))'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(from-ng2)|ng1(from-ng2)|ng1(from-ng1))'); - ng1ControllerInstances.forEach(ctrl => ctrl.value = 'ng1-foo'); - ng2ComponentInstance.value = 'ng2-bar'; - $digest(ref); + ng1ControllerInstances.forEach(ctrl => ctrl.value = 'ng1-foo'); + ng2ComponentInstance.value = 'ng2-bar'; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(ng2-bar)|ng1(ng2-bar)|ng1(ng1-foo))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(ng2-bar)|ng1(ng2-bar)|ng1(ng1-foo))'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support multi-slot transclusion', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support multi-slot transclusion', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: - 'ng1(x(
) | y(
))', - transclude: {slotX: 'contentX', slotY: 'contentY'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: + 'ng1(x(
) | y(
))', + transclude: {slotX: 'contentX', slotY: 'contentY'} + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2( {{ x }}1 @@ -2795,62 +2797,64 @@ withEachNg1Version(() => { {{ y }}2 )` - }) - class Ng2Component { - x = 'foo'; - y = 'bar'; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + x = 'foo'; + y = 'bar'; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(foo1foo2)|y(bar1bar2)))'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(foo1foo2)|y(bar1bar2)))'); - ng2ComponentInstance.x = 'baz'; - ng2ComponentInstance.y = 'qux'; - $digest(ref); + ng2ComponentInstance.x = 'baz'; + ng2ComponentInstance.y = 'qux'; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(baz1baz2)|y(qux1qux2)))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(baz1baz2)|y(qux1qux2)))'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support default slot (with fallback content)', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng1ControllerInstances: any[] = []; - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support default slot (with fallback content)', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng1ControllerInstances: any[] = []; + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'ng1(default(
fallback-{{ $ctrl.value }}
))', - transclude: {slotX: 'contentX', slotY: 'contentY'}, - controller: - class {value = 'ng1'; constructor() { ng1ControllerInstances.push(this); }} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: + 'ng1(default(
fallback-{{ $ctrl.value }}
))', + transclude: {slotX: 'contentX', slotY: 'contentY'}, + controller: class { + value = 'ng1'; constructor() { ng1ControllerInstances.push(this); } + } + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2( ({{ x }}) @@ -2871,172 +2875,172 @@ withEachNg1Version(() => { --> {{ x }}ignored x{{ y + x }}ignored y{{ y }} )` - }) - class Ng2Component { - x = 'foo'; - y = 'bar'; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + x = 'foo'; + y = 'bar'; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(multiTrim(element.textContent, true)) - .toBe( - 'ng2(ng1(default((foo)foo-bar(bar)))|ng1(default(fallback-ng1))|ng1(default(foobarfoobar)))'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(multiTrim(element.textContent, true)) + .toBe( + 'ng2(ng1(default((foo)foo-bar(bar)))|ng1(default(fallback-ng1))|ng1(default(foobarfoobar)))'); - ng1ControllerInstances.forEach(ctrl => ctrl.value = 'ng1-plus'); - ng2ComponentInstance.x = 'baz'; - ng2ComponentInstance.y = 'qux'; - $digest(ref); + ng1ControllerInstances.forEach(ctrl => ctrl.value = 'ng1-plus'); + ng2ComponentInstance.x = 'baz'; + ng2ComponentInstance.y = 'qux'; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe( - 'ng2(ng1(default((baz)baz-qux(qux)))|ng1(default(fallback-ng1-plus))|ng1(default(bazquxbazqux)))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe( + 'ng2(ng1(default((baz)baz-qux(qux)))|ng1(default(fallback-ng1-plus))|ng1(default(bazquxbazqux)))'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support optional transclusion slots (with fallback content)', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng1ControllerInstances: any[] = []; - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support optional transclusion slots (with fallback content)', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng1ControllerInstances: any[] = []; + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: ` + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: ` ng1( x(
{{ $ctrl.x }}
) | y(
{{ $ctrl.y }}
) )`, - transclude: {slotX: '?contentX', slotY: '?contentY'}, - controller: class { - x = 'ng1X'; y = 'ng1Y'; constructor() { ng1ControllerInstances.push(this); } - } - }; + transclude: {slotX: '?contentX', slotY: '?contentY'}, + controller: class { + x = 'ng1X'; y = 'ng1Y'; constructor() { ng1ControllerInstances.push(this); } + } + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2( {{ x }} | {{ y }} )` - }) - class Ng2Component { - x = 'ng2X'; - y = 'ng2Y'; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + x = 'ng2X'; + y = 'ng2Y'; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(ng2X)|y(ng1Y))|ng1(x(ng1X)|y(ng2Y)))'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(ng2X)|y(ng1Y))|ng1(x(ng1X)|y(ng2Y)))'); - ng1ControllerInstances.forEach(ctrl => { - ctrl.x = 'ng1X-foo'; - ctrl.y = 'ng1Y-bar'; - }); - ng2ComponentInstance.x = 'ng2X-baz'; - ng2ComponentInstance.y = 'ng2Y-qux'; - $digest(ref); + ng1ControllerInstances.forEach(ctrl => { + ctrl.x = 'ng1X-foo'; + ctrl.y = 'ng1Y-bar'; + }); + ng2ComponentInstance.x = 'ng2X-baz'; + ng2ComponentInstance.y = 'ng2Y-qux'; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(ng2X-baz)|y(ng1Y-bar))|ng1(x(ng1X-foo)|y(ng2Y-qux)))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(ng2X-baz)|y(ng1Y-bar))|ng1(x(ng1X-foo)|y(ng2Y-qux)))'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should throw if a non-optional slot is not filled', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let errorMessage: string; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should throw if a non-optional slot is not filled', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let errorMessage: string; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: '', - transclude: {slotX: '?contentX', slotY: 'contentY'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: '', + transclude: {slotX: '?contentX', slotY: 'contentY'} + }; - // Define `Ng2Component` - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - } + // Define `Ng2Component` + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .value($EXCEPTION_HANDLER, (error: Error) => errorMessage = error.message) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .value($EXCEPTION_HANDLER, (error: Error) => errorMessage = error.message) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(errorMessage) - .toContain('Required transclusion slot \'slotY\' on directive: ng1'); - }); - })); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(errorMessage) + .toContain('Required transclusion slot \'slotY\' on directive: ng1'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support structural directives in transcluded content', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - let ng2ComponentInstance: Ng2Component; + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support structural directives in transcluded content', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: - 'ng1(x(
) | default(
))', - transclude: {slotX: 'contentX'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: + 'ng1(x(
) | default(
))', + transclude: {slotX: 'contentX'} + }; - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2(
{{ x }}1
@@ -3045,119 +3049,118 @@ withEachNg1Version(() => {
{{ y }}2
)` - }) - class Ng2Component { - x = 'foo'; - y = 'bar'; - show = true; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + x = 'foo'; + y = 'bar'; + show = true; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', adapter.downgradeNg2Component(Ng2Component)); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule], - declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule], + declarations: [adapter.upgradeNg1Component('ng1'), Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - adapter.bootstrap(element, ['ng1Module']).ready(ref => { - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(foo1)|default(bar2)))'); + adapter.bootstrap(element, ['ng1Module']).ready(ref => { + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(foo1)|default(bar2)))'); - ng2ComponentInstance.x = 'baz'; - ng2ComponentInstance.y = 'qux'; - ng2ComponentInstance.show = false; - $digest(ref); + ng2ComponentInstance.x = 'baz'; + ng2ComponentInstance.y = 'qux'; + ng2ComponentInstance.show = false; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(baz2)|default(qux1)))'); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(baz2)|default(qux1)))'); - ng2ComponentInstance.show = true; - $digest(ref); + ng2ComponentInstance.show = true; + $digest(ref); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(baz1)|default(qux2)))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(baz1)|default(qux2)))'); + }); + })); }); - fixmeIvy('unknown') && - it('should bind input properties (<) of components', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('unknown').it( + 'should bind input properties (<) of components', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = { - bindings: {personProfile: '<'}, - template: - 'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}', - controller: class {} - }; - ng1Module.component('ng1', ng1); + const ng1 = { + bindings: {personProfile: '<'}, + template: 'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}', + controller: class {} + }; + ng1Module.component('ng1', ng1); - @Component({selector: 'ng2', template: ''}) - class Ng2 { - goku = {firstName: 'GOKU', lastName: 'SAN'}; - } + @Component({selector: 'ng2', template: ''}) + class Ng2 { + goku = {firstName: 'GOKU', lastName: 'SAN'}; + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual(`Hello GOKU SAN`); - ref.dispose(); - }); - })); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual(`Hello GOKU SAN`); + ref.dispose(); + }); + })); - fixmeIvy('unknown') && - it('should support ng2 > ng1 > ng2', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const ng1Module = angular.module('ng1', []); + fixmeIvy('unknown').it( + 'should support ng2 > ng1 > ng2', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const ng1Module = angular.module('ng1', []); - const ng1 = { - template: 'ng1()', - }; - ng1Module.component('ng1', ng1); + const ng1 = { + template: 'ng1()', + }; + ng1Module.component('ng1', ng1); - @Component({selector: 'ng2a', template: 'ng2a()'}) - class Ng2a { - } - ng1Module.directive('ng2a', adapter.downgradeNg2Component(Ng2a)); + @Component({selector: 'ng2a', template: 'ng2a()'}) + class Ng2a { + } + ng1Module.directive('ng2a', adapter.downgradeNg2Component(Ng2a)); - @Component({selector: 'ng2b', template: 'ng2b'}) - class Ng2b { - } - ng1Module.directive('ng2b', adapter.downgradeNg2Component(Ng2b)); + @Component({selector: 'ng2b', template: 'ng2b'}) + class Ng2b { + } + ng1Module.directive('ng2b', adapter.downgradeNg2Component(Ng2b)); - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2a, Ng2b], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2a, Ng2b], + imports: [BrowserModule], + }) + class Ng2Module { + } - const element = html(`
`); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(multiTrim(document.body.textContent)).toEqual('ng2a(ng1(ng2b))'); - }); - })); + const element = html(`
`); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(multiTrim(document.body.textContent)).toEqual('ng2a(ng1(ng2b))'); + }); + })); }); describe('injection', () => { @@ -3199,33 +3202,33 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should respect hierarchical dependency injection for ng2', async(() => { - const ng1Module = angular.module('ng1', []); + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should respect hierarchical dependency injection for ng2', async(() => { + const ng1Module = angular.module('ng1', []); - @Component( - {selector: 'ng2-parent', template: `ng2-parent()`}) - class Ng2Parent { - } - @Component({selector: 'ng2-child', template: `ng2-child`}) - class Ng2Child { - constructor(parent: Ng2Parent) {} - } + @Component( + {selector: 'ng2-parent', template: `ng2-parent()`}) + class Ng2Parent { + } + @Component({selector: 'ng2-child', template: `ng2-child`}) + class Ng2Child { + constructor(parent: Ng2Parent) {} + } - @NgModule({declarations: [Ng2Parent, Ng2Child], imports: [BrowserModule]}) - class Ng2Module { - } + @NgModule({declarations: [Ng2Parent, Ng2Child], imports: [BrowserModule]}) + class Ng2Module { + } - const element = html(''); + const element = html(''); - const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); - ng1Module.directive('ng2Parent', adapter.downgradeNg2Component(Ng2Parent)) - .directive('ng2Child', adapter.downgradeNg2Component(Ng2Child)); - adapter.bootstrap(element, ['ng1']).ready((ref) => { - expect(document.body.textContent).toEqual('ng2-parent(ng2-child)'); - ref.dispose(); - }); - })); + const adapter: UpgradeAdapter = new UpgradeAdapter(Ng2Module); + ng1Module.directive('ng2Parent', adapter.downgradeNg2Component(Ng2Parent)) + .directive('ng2Child', adapter.downgradeNg2Component(Ng2Child)); + adapter.bootstrap(element, ['ng1']).ready((ref) => { + expect(document.body.textContent).toEqual('ng2-parent(ng2-child)'); + ref.dispose(); + }); + })); }); describe('testability', () => { @@ -3302,45 +3305,45 @@ withEachNg1Version(() => { }); describe('examples', () => { - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should verify UpgradeAdapter example', async(() => { - const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); - const module = angular.module('myExample', []); + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should verify UpgradeAdapter example', async(() => { + const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); + const module = angular.module('myExample', []); - const ng1 = () => { - return { - scope: {title: '='}, - transclude: true, - template: 'ng1[Hello {{title}}!]()' - }; - }; - module.directive('ng1', ng1); + const ng1 = () => { + return { + scope: {title: '='}, + transclude: true, + template: 'ng1[Hello {{title}}!]()' + }; + }; + module.directive('ng1', ng1); - @Component({ - selector: 'ng2', - inputs: ['name'], - template: 'ng2[transclude]()' - }) - class Ng2 { - } + @Component({ + selector: 'ng2', + inputs: ['name'], + template: 'ng2[transclude]()' + }) + class Ng2 { + } - @NgModule({ - declarations: [adapter.upgradeNg1Component('ng1'), Ng2], - imports: [BrowserModule], - }) - class Ng2Module { - } + @NgModule({ + declarations: [adapter.upgradeNg1Component('ng1'), Ng2], + imports: [BrowserModule], + }) + class Ng2Module { + } - module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + module.directive('ng2', adapter.downgradeNg2Component(Ng2)); - document.body.innerHTML = 'project'; + document.body.innerHTML = 'project'; - adapter.bootstrap(document.body.firstElementChild !, ['myExample']).ready((ref) => { - expect(multiTrim(document.body.textContent)) - .toEqual('ng2[ng1[Hello World!](transclude)](project)'); - ref.dispose(); - }); - })); + adapter.bootstrap(document.body.firstElementChild !, ['myExample']).ready((ref) => { + expect(multiTrim(document.body.textContent)) + .toEqual('ng2[ng1[Hello World!](transclude)](project)'); + ref.dispose(); + }); + })); }); describe('registerForNg1Tests', () => { diff --git a/packages/upgrade/test/static/integration/change_detection_spec.ts b/packages/upgrade/test/static/integration/change_detection_spec.ts index d2f472eaa7..9268165ce4 100644 --- a/packages/upgrade/test/static/integration/change_detection_spec.ts +++ b/packages/upgrade/test/static/integration/change_detection_spec.ts @@ -77,59 +77,59 @@ withEachNg1Version(() => { })); fixmeIvy( - 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') && - it('should propagate changes to a downgraded component inside the ngZone', async(() => { - const element = html(''); - let appComponent: AppComponent; + 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') + .it('should propagate changes to a downgraded component inside the ngZone', async(() => { + const element = html(''); + let appComponent: AppComponent; - @Component({selector: 'my-app', template: ''}) - class AppComponent { - value?: number; - constructor() { appComponent = this; } - } + @Component({selector: 'my-app', template: ''}) + class AppComponent { + value?: number; + constructor() { appComponent = this; } + } - @Component({ - selector: 'my-child', - template: '
{{ valueFromPromise }}
', - }) - class ChildComponent { - valueFromPromise?: number; - @Input() - set value(v: number) { expect(NgZone.isInAngularZone()).toBe(true); } + @Component({ + selector: 'my-child', + template: '
{{ valueFromPromise }}
', + }) + class ChildComponent { + valueFromPromise?: number; + @Input() + set value(v: number) { expect(NgZone.isInAngularZone()).toBe(true); } - constructor(private zone: NgZone) {} + constructor(private zone: NgZone) {} - ngOnChanges(changes: SimpleChanges) { - if (changes['value'].isFirstChange()) return; + ngOnChanges(changes: SimpleChanges) { + if (changes['value'].isFirstChange()) return; - // HACK(ivy): Using setTimeout allows this test to pass but hides the ivy renderer - // timing BC. - // setTimeout(() => expect(element.textContent).toEqual('5'), 0); - this.zone.onMicrotaskEmpty.subscribe( - () => { expect(element.textContent).toEqual('5'); }); + // HACK(ivy): Using setTimeout allows this test to pass but hides the ivy renderer + // timing BC. + // setTimeout(() => expect(element.textContent).toEqual('5'), 0); + this.zone.onMicrotaskEmpty.subscribe( + () => { expect(element.textContent).toEqual('5'); }); - // Create a micro-task to update the value to be rendered asynchronously. - Promise.resolve().then( - () => this.valueFromPromise = changes['value'].currentValue); - } - } + // Create a micro-task to update the value to be rendered asynchronously. + Promise.resolve().then( + () => this.valueFromPromise = changes['value'].currentValue); + } + } - @NgModule({ - declarations: [AppComponent, ChildComponent], - entryComponents: [AppComponent], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [AppComponent, ChildComponent], + entryComponents: [AppComponent], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const ng1Module = angular.module('ng1', []).directive( - 'myApp', downgradeComponent({component: AppComponent})); + const ng1Module = angular.module('ng1', []).directive( + 'myApp', downgradeComponent({component: AppComponent})); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { - appComponent.value = 5; - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { + appComponent.value = 5; + }); + })); // This test demonstrates https://github.com/angular/angular/issues/6385 // which was invalidly fixed by https://github.com/angular/angular/pull/6386 diff --git a/packages/upgrade/test/static/integration/content_projection_spec.ts b/packages/upgrade/test/static/integration/content_projection_spec.ts index b5d0d31a24..b385dec9c1 100644 --- a/packages/upgrade/test/static/integration/content_projection_spec.ts +++ b/packages/upgrade/test/static/integration/content_projection_spec.ts @@ -22,82 +22,82 @@ withEachNg1Version(() => { beforeEach(() => destroyPlatform()); afterEach(() => destroyPlatform()); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should instantiate ng2 in ng1 template and project content', async(() => { + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should instantiate ng2 in ng1 template and project content', async(() => { - // the ng2 component that will be used in ng1 (downgraded) - @Component({selector: 'ng2', template: `{{ prop }}()`}) - class Ng2Component { - prop = 'NG2'; - ngContent = 'ng2-content'; - } + // the ng2 component that will be used in ng1 (downgraded) + @Component({selector: 'ng2', template: `{{ prop }}()`}) + class Ng2Component { + prop = 'NG2'; + ngContent = 'ng2-content'; + } - // our upgrade module to host the component to downgrade - @NgModule({ - imports: [BrowserModule, UpgradeModule], - declarations: [Ng2Component], - entryComponents: [Ng2Component] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // our upgrade module to host the component to downgrade + @NgModule({ + imports: [BrowserModule, UpgradeModule], + declarations: [Ng2Component], + entryComponents: [Ng2Component] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // the ng1 app module that will consume the downgraded component - const ng1Module = angular - .module('ng1', []) - // create an ng1 facade of the ng2 component - .directive('ng2', downgradeComponent({component: Ng2Component})) - .run(($rootScope: angular.IRootScopeService) => { - $rootScope['prop'] = 'NG1'; - $rootScope['ngContent'] = 'ng1-content'; - }); + // the ng1 app module that will consume the downgraded component + const ng1Module = angular + .module('ng1', []) + // create an ng1 facade of the ng2 component + .directive('ng2', downgradeComponent({component: Ng2Component})) + .run(($rootScope: angular.IRootScopeService) => { + $rootScope['prop'] = 'NG1'; + $rootScope['ngContent'] = 'ng1-content'; + }); - const element = - html('
{{ \'ng1[\' }}~{{ ngContent }}~{{ \']\' }}
'); + const element = + html('
{{ \'ng1[\' }}~{{ ngContent }}~{{ \']\' }}
'); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { - expect(document.body.textContent).toEqual('ng1[NG2(~ng1-content~)]'); - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { + expect(document.body.textContent).toEqual('ng1[NG2(~ng1-content~)]'); + }); + })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should correctly project structural directives', async(() => { - @Component({selector: 'ng2', template: 'ng2-{{ itemId }}()'}) - class Ng2Component { - // TODO(issue/24571): remove '!'. - @Input() itemId !: string; - } + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should correctly project structural directives', async(() => { + @Component({selector: 'ng2', template: 'ng2-{{ itemId }}()'}) + class Ng2Component { + // TODO(issue/24571): remove '!'. + @Input() itemId !: string; + } - @NgModule({ - imports: [BrowserModule, UpgradeModule], - declarations: [Ng2Component], - entryComponents: [Ng2Component] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + imports: [BrowserModule, UpgradeModule], + declarations: [Ng2Component], + entryComponents: [Ng2Component] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const ng1Module = - angular.module('ng1', []) - .directive('ng2', downgradeComponent({component: Ng2Component})) - .run(($rootScope: angular.IRootScopeService) => { - $rootScope['items'] = [ - {id: 'a', subitems: [1, 2, 3]}, {id: 'b', subitems: [4, 5, 6]}, - {id: 'c', subitems: [7, 8, 9]} - ]; - }); + const ng1Module = + angular.module('ng1', []) + .directive('ng2', downgradeComponent({component: Ng2Component})) + .run(($rootScope: angular.IRootScopeService) => { + $rootScope['items'] = [ + {id: 'a', subitems: [1, 2, 3]}, {id: 'b', subitems: [4, 5, 6]}, + {id: 'c', subitems: [7, 8, 9]} + ]; + }); - const element = html(` + const element = html(`
{{ subitem }}
`); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { - expect(multiTrim(document.body.textContent)) - .toBe('ng2-a( 123 )ng2-b( 456 )ng2-c( 789 )'); - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { + expect(multiTrim(document.body.textContent)) + .toBe('ng2-a( 123 )ng2-b( 456 )ng2-c( 789 )'); + }); + })); it('should instantiate ng1 in ng2 template and project content', async(() => { @@ -145,39 +145,39 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should support multi-slot projection', async(() => { + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should support multi-slot projection', async(() => { - @Component({ - selector: 'ng2', - template: '2a()' + - '2b()' - }) - class Ng2Component { - constructor() {} - } + @Component({ + selector: 'ng2', + template: '2a()' + + '2b()' + }) + class Ng2Component { + constructor() {} + } - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const ng1Module = angular.module('ng1', []).directive( - 'ng2', downgradeComponent({component: Ng2Component})); + const ng1Module = angular.module('ng1', []).directive( + 'ng2', downgradeComponent({component: Ng2Component})); - // The ng-if on one of the projected children is here to make sure - // the correct slot is targeted even with structural directives in play. - const element = html( - '
1a
1b
'); + // The ng-if on one of the projected children is here to make sure + // the correct slot is targeted even with structural directives in play. + const element = html( + '
1a
1b
'); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { - expect(document.body.textContent).toEqual('2a(1a)2b(1b)'); - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { + expect(document.body.textContent).toEqual('2a(1a)2b(1b)'); + }); + })); }); }); diff --git a/packages/upgrade/test/static/integration/downgrade_component_spec.ts b/packages/upgrade/test/static/integration/downgrade_component_spec.ts index 9b23b32d33..be75502326 100644 --- a/packages/upgrade/test/static/integration/downgrade_component_spec.ts +++ b/packages/upgrade/test/static/integration/downgrade_component_spec.ts @@ -22,106 +22,106 @@ withEachNg1Version(() => { beforeEach(() => destroyPlatform()); afterEach(() => destroyPlatform()); - fixmeIvy('FW-716: Error: [$rootScope:inprog] $digest already in progress') && - it('should bind properties, events', async(() => { - const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { - $rootScope['name'] = 'world'; - $rootScope['dataA'] = 'A'; - $rootScope['dataB'] = 'B'; - $rootScope['modelA'] = 'initModelA'; - $rootScope['modelB'] = 'initModelB'; - $rootScope['eventA'] = '?'; - $rootScope['eventB'] = '?'; - }); + fixmeIvy('FW-716: Error: [$rootScope:inprog] $digest already in progress') + .it('should bind properties, events', async(() => { + const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { + $rootScope['name'] = 'world'; + $rootScope['dataA'] = 'A'; + $rootScope['dataB'] = 'B'; + $rootScope['modelA'] = 'initModelA'; + $rootScope['modelB'] = 'initModelB'; + $rootScope['eventA'] = '?'; + $rootScope['eventB'] = '?'; + }); - @Component({ - selector: 'ng2', - inputs: ['literal', 'interpolate', 'oneWayA', 'oneWayB', 'twoWayA', 'twoWayB'], - outputs: [ - 'eventA', 'eventB', 'twoWayAEmitter: twoWayAChange', - 'twoWayBEmitter: twoWayBChange' - ], - template: 'ignore: {{ignore}}; ' + - 'literal: {{literal}}; interpolate: {{interpolate}}; ' + - 'oneWayA: {{oneWayA}}; oneWayB: {{oneWayB}}; ' + - 'twoWayA: {{twoWayA}}; twoWayB: {{twoWayB}}; ({{ngOnChangesCount}})' - }) - class Ng2Component implements OnChanges { - ngOnChangesCount = 0; - ignore = '-'; - literal = '?'; - interpolate = '?'; - oneWayA = '?'; - oneWayB = '?'; - twoWayA = '?'; - twoWayB = '?'; - eventA = new EventEmitter(); - eventB = new EventEmitter(); - twoWayAEmitter = new EventEmitter(); - twoWayBEmitter = new EventEmitter(); + @Component({ + selector: 'ng2', + inputs: ['literal', 'interpolate', 'oneWayA', 'oneWayB', 'twoWayA', 'twoWayB'], + outputs: [ + 'eventA', 'eventB', 'twoWayAEmitter: twoWayAChange', + 'twoWayBEmitter: twoWayBChange' + ], + template: 'ignore: {{ignore}}; ' + + 'literal: {{literal}}; interpolate: {{interpolate}}; ' + + 'oneWayA: {{oneWayA}}; oneWayB: {{oneWayB}}; ' + + 'twoWayA: {{twoWayA}}; twoWayB: {{twoWayB}}; ({{ngOnChangesCount}})' + }) + class Ng2Component implements OnChanges { + ngOnChangesCount = 0; + ignore = '-'; + literal = '?'; + interpolate = '?'; + oneWayA = '?'; + oneWayB = '?'; + twoWayA = '?'; + twoWayB = '?'; + eventA = new EventEmitter(); + eventB = new EventEmitter(); + twoWayAEmitter = new EventEmitter(); + twoWayBEmitter = new EventEmitter(); - ngOnChanges(changes: SimpleChanges) { - const assert = (prop: string, value: any) => { - const propVal = (this as any)[prop]; - if (propVal != value) { - throw new Error(`Expected: '${prop}' to be '${value}' but was '${propVal}'`); - } - }; + ngOnChanges(changes: SimpleChanges) { + const assert = (prop: string, value: any) => { + const propVal = (this as any)[prop]; + if (propVal != value) { + throw new Error(`Expected: '${prop}' to be '${value}' but was '${propVal}'`); + } + }; - const assertChange = (prop: string, value: any) => { - assert(prop, value); - if (!changes[prop]) { - throw new Error(`Changes record for '${prop}' not found.`); - } - const actualValue = changes[prop].currentValue; - if (actualValue != value) { - throw new Error( - `Expected changes record for'${prop}' to be '${value}' but was '${actualValue}'`); - } - }; + const assertChange = (prop: string, value: any) => { + assert(prop, value); + if (!changes[prop]) { + throw new Error(`Changes record for '${prop}' not found.`); + } + const actualValue = changes[prop].currentValue; + if (actualValue != value) { + throw new Error( + `Expected changes record for'${prop}' to be '${value}' but was '${actualValue}'`); + } + }; - switch (this.ngOnChangesCount++) { - case 0: - assert('ignore', '-'); - assertChange('literal', 'Text'); - assertChange('interpolate', 'Hello world'); - assertChange('oneWayA', 'A'); - assertChange('oneWayB', 'B'); - assertChange('twoWayA', 'initModelA'); - assertChange('twoWayB', 'initModelB'); + switch (this.ngOnChangesCount++) { + case 0: + assert('ignore', '-'); + assertChange('literal', 'Text'); + assertChange('interpolate', 'Hello world'); + assertChange('oneWayA', 'A'); + assertChange('oneWayB', 'B'); + assertChange('twoWayA', 'initModelA'); + assertChange('twoWayB', 'initModelB'); - this.twoWayAEmitter.emit('newA'); - this.twoWayBEmitter.emit('newB'); - this.eventA.emit('aFired'); - this.eventB.emit('bFired'); - break; - case 1: - assertChange('twoWayA', 'newA'); - assertChange('twoWayB', 'newB'); - break; - case 2: - assertChange('interpolate', 'Hello everyone'); - break; - default: - throw new Error('Called too many times! ' + JSON.stringify(changes)); - } - } - } + this.twoWayAEmitter.emit('newA'); + this.twoWayBEmitter.emit('newB'); + this.eventA.emit('aFired'); + this.eventB.emit('bFired'); + break; + case 1: + assertChange('twoWayA', 'newA'); + assertChange('twoWayB', 'newB'); + break; + case 2: + assertChange('interpolate', 'Hello everyone'); + break; + default: + throw new Error('Called too many times! ' + JSON.stringify(changes)); + } + } + } - ng1Module.directive('ng2', downgradeComponent({ - component: Ng2Component, - })); + ng1Module.directive('ng2', downgradeComponent({ + component: Ng2Component, + })); - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const element = html(` + const element = html(`
{ | modelA: {{modelA}}; modelB: {{modelB}}; eventA: {{eventA}}; eventB: {{eventB}};
`); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { - expect(multiTrim(document.body.textContent)) - .toEqual( - 'ignore: -; ' + - 'literal: Text; interpolate: Hello world; ' + - 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (2) | ' + - 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { + expect(multiTrim(document.body.textContent)) + .toEqual( + 'ignore: -; ' + + 'literal: Text; interpolate: Hello world; ' + + 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (2) | ' + + 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); - $apply(upgrade, 'name = "everyone"'); - expect(multiTrim(document.body.textContent)) - .toEqual( - 'ignore: -; ' + - 'literal: Text; interpolate: Hello everyone; ' + - 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (3) | ' + - 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); - }); - })); + $apply(upgrade, 'name = "everyone"'); + expect(multiTrim(document.body.textContent)) + .toEqual( + 'ignore: -; ' + + 'literal: Text; interpolate: Hello everyone; ' + + 'oneWayA: A; oneWayB: B; twoWayA: newA; twoWayB: newB; (3) | ' + + 'modelA: newA; modelB: newB; eventA: aFired; eventB: bFired;'); + }); + })); it('should bind properties to onpush components', async(() => { const ng1Module = angular.module('ng1', []).run( @@ -189,58 +189,58 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should support two-way binding and event listener', async(() => { - const listenerSpy = jasmine.createSpy('$rootScope.listener'); - const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { - $rootScope['value'] = 'world'; - $rootScope['listener'] = listenerSpy; - }); + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should support two-way binding and event listener', async(() => { + const listenerSpy = jasmine.createSpy('$rootScope.listener'); + const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { + $rootScope['value'] = 'world'; + $rootScope['listener'] = listenerSpy; + }); - @Component({selector: 'ng2', template: `model: {{model}};`}) - class Ng2Component implements OnChanges { - ngOnChangesCount = 0; - @Input() model = '?'; - @Output() modelChange = new EventEmitter(); + @Component({selector: 'ng2', template: `model: {{model}};`}) + class Ng2Component implements OnChanges { + ngOnChangesCount = 0; + @Input() model = '?'; + @Output() modelChange = new EventEmitter(); - ngOnChanges(changes: SimpleChanges) { - switch (this.ngOnChangesCount++) { - case 0: - expect(changes.model.currentValue).toBe('world'); - this.modelChange.emit('newC'); - break; - case 1: - expect(changes.model.currentValue).toBe('newC'); - break; - default: - throw new Error('Called too many times! ' + JSON.stringify(changes)); - } - } - } + ngOnChanges(changes: SimpleChanges) { + switch (this.ngOnChangesCount++) { + case 0: + expect(changes.model.currentValue).toBe('world'); + this.modelChange.emit('newC'); + break; + case 1: + expect(changes.model.currentValue).toBe('newC'); + break; + default: + throw new Error('Called too many times! ' + JSON.stringify(changes)); + } + } + } - ng1Module.directive('ng2', downgradeComponent({component: Ng2Component})); + ng1Module.directive('ng2', downgradeComponent({component: Ng2Component})); - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const element = html(` + const element = html(`
| value: {{value}}
`); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { - expect(multiTrim(element.textContent)).toEqual('model: newC; | value: newC'); - expect(listenerSpy).toHaveBeenCalledWith('newC'); - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => { + expect(multiTrim(element.textContent)).toEqual('model: newC; | value: newC'); + expect(listenerSpy).toHaveBeenCalledWith('newC'); + }); + })); it('should run change-detection on every digest (by default)', async(() => { let ng2Component: Ng2Component; @@ -404,66 +404,66 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should initialize inputs in time for `ngOnChanges`', async(() => { - @Component({ - selector: 'ng2', - template: ` + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should initialize inputs in time for `ngOnChanges`', async(() => { + @Component({ + selector: 'ng2', + template: ` ngOnChangesCount: {{ ngOnChangesCount }} | firstChangesCount: {{ firstChangesCount }} | initialValue: {{ initialValue }}` - }) - class Ng2Component implements OnChanges { - ngOnChangesCount = 0; - firstChangesCount = 0; - // TODO(issue/24571): remove '!'. - initialValue !: string; - // TODO(issue/24571): remove '!'. - @Input() foo !: string; + }) + class Ng2Component implements OnChanges { + ngOnChangesCount = 0; + firstChangesCount = 0; + // TODO(issue/24571): remove '!'. + initialValue !: string; + // TODO(issue/24571): remove '!'. + @Input() foo !: string; - ngOnChanges(changes: SimpleChanges) { - this.ngOnChangesCount++; + ngOnChanges(changes: SimpleChanges) { + this.ngOnChangesCount++; - if (this.ngOnChangesCount === 1) { - this.initialValue = this.foo; - } + if (this.ngOnChangesCount === 1) { + this.initialValue = this.foo; + } - if (changes['foo'] && changes['foo'].isFirstChange()) { - this.firstChangesCount++; - } - } - } + if (changes['foo'] && changes['foo'].isFirstChange()) { + this.firstChangesCount++; + } + } + } - @NgModule({ - imports: [BrowserModule, UpgradeModule], - declarations: [Ng2Component], - entryComponents: [Ng2Component] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + imports: [BrowserModule, UpgradeModule], + declarations: [Ng2Component], + entryComponents: [Ng2Component] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const ng1Module = angular.module('ng1', []).directive( - 'ng2', downgradeComponent({component: Ng2Component})); + const ng1Module = angular.module('ng1', []).directive( + 'ng2', downgradeComponent({component: Ng2Component})); - const element = html(` + const element = html(` `); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { - const nodes = element.querySelectorAll('ng2'); - const expectedTextWith = (value: string) => - `ngOnChangesCount: 1 | firstChangesCount: 1 | initialValue: ${value}`; + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { + const nodes = element.querySelectorAll('ng2'); + const expectedTextWith = (value: string) => + `ngOnChangesCount: 1 | firstChangesCount: 1 | initialValue: ${value}`; - expect(multiTrim(nodes[0].textContent)).toBe(expectedTextWith('foo')); - expect(multiTrim(nodes[1].textContent)).toBe(expectedTextWith('bar')); - expect(multiTrim(nodes[2].textContent)).toBe(expectedTextWith('baz')); - expect(multiTrim(nodes[3].textContent)).toBe(expectedTextWith('qux')); - }); - })); + expect(multiTrim(nodes[0].textContent)).toBe(expectedTextWith('foo')); + expect(multiTrim(nodes[1].textContent)).toBe(expectedTextWith('bar')); + expect(multiTrim(nodes[2].textContent)).toBe(expectedTextWith('baz')); + expect(multiTrim(nodes[3].textContent)).toBe(expectedTextWith('qux')); + }); + })); it('should bind to ng-model', async(() => { const ng1Module = angular.module('ng1', []).run( @@ -709,88 +709,88 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should respect hierarchical dependency injection for ng2', async(() => { - @Component({selector: 'parent', template: 'parent()'}) - class ParentComponent { - } + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should respect hierarchical dependency injection for ng2', async(() => { + @Component({selector: 'parent', template: 'parent()'}) + class ParentComponent { + } - @Component({selector: 'child', template: 'child'}) - class ChildComponent { - constructor(parent: ParentComponent) {} - } + @Component({selector: 'child', template: 'child'}) + class ChildComponent { + constructor(parent: ParentComponent) {} + } - @NgModule({ - declarations: [ParentComponent, ChildComponent], - entryComponents: [ParentComponent, ChildComponent], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [ParentComponent, ChildComponent], + entryComponents: [ParentComponent, ChildComponent], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - const ng1Module = - angular.module('ng1', []) - .directive('parent', downgradeComponent({component: ParentComponent})) - .directive('child', downgradeComponent({component: ChildComponent})); + const ng1Module = + angular.module('ng1', []) + .directive('parent', downgradeComponent({component: ParentComponent})) + .directive('child', downgradeComponent({component: ChildComponent})); - const element = html(''); + const element = html(''); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { - expect(multiTrim(document.body.textContent)).toBe('parent(child)'); - }); - })); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { + expect(multiTrim(document.body.textContent)).toBe('parent(child)'); + }); + })); fixmeIvy( - 'FW-717: Injector on lazy loaded components are not the same as their NgModule\'s injector') && - it('should work with ng2 lazy loaded components', async(() => { - let componentInjector: Injector; + 'FW-717: Injector on lazy loaded components are not the same as their NgModule\'s injector') + .it('should work with ng2 lazy loaded components', async(() => { + let componentInjector: Injector; - @Component({selector: 'ng2', template: ''}) - class Ng2Component { - constructor(injector: Injector) { componentInjector = injector; } - } + @Component({selector: 'ng2', template: ''}) + class Ng2Component { + constructor(injector: Injector) { componentInjector = injector; } + } - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule], - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule], + }) + class Ng2Module { + ngDoBootstrap() {} + } - @Component({template: ''}) - class LazyLoadedComponent { - constructor(public module: NgModuleRef) {} - } + @Component({template: ''}) + class LazyLoadedComponent { + constructor(public module: NgModuleRef) {} + } - @NgModule({ - declarations: [LazyLoadedComponent], - entryComponents: [LazyLoadedComponent], - }) - class LazyLoadedModule { - } + @NgModule({ + declarations: [LazyLoadedComponent], + entryComponents: [LazyLoadedComponent], + }) + class LazyLoadedModule { + } - const ng1Module = angular.module('ng1', []).directive( - 'ng2', downgradeComponent({component: Ng2Component})); + const ng1Module = angular.module('ng1', []).directive( + 'ng2', downgradeComponent({component: Ng2Component})); - const element = html(''); + const element = html(''); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { - const modInjector = upgrade.injector; - // Emulate the router lazy loading a module and creating a component - const compiler = modInjector.get(Compiler); - const modFactory = compiler.compileModuleSync(LazyLoadedModule); - const childMod = modFactory.create(modInjector); - const cmpFactory = - childMod.componentFactoryResolver.resolveComponentFactory(LazyLoadedComponent) !; - const lazyCmp = cmpFactory.create(componentInjector); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { + const modInjector = upgrade.injector; + // Emulate the router lazy loading a module and creating a component + const compiler = modInjector.get(Compiler); + const modFactory = compiler.compileModuleSync(LazyLoadedModule); + const childMod = modFactory.create(modInjector); + const cmpFactory = childMod.componentFactoryResolver.resolveComponentFactory( + LazyLoadedComponent) !; + const lazyCmp = cmpFactory.create(componentInjector); - expect(lazyCmp.instance.module.injector === childMod.injector).toBe(true); - }); + expect(lazyCmp.instance.module.injector === childMod.injector).toBe(true); + }); - })); + })); it('should throw if `downgradedModule` is specified', async(() => { @Component({selector: 'ng2', template: ''}) diff --git a/packages/upgrade/test/static/integration/downgrade_module_spec.ts b/packages/upgrade/test/static/integration/downgrade_module_spec.ts index aec04938fd..a1b0455aaf 100644 --- a/packages/upgrade/test/static/integration/downgrade_module_spec.ts +++ b/packages/upgrade/test/static/integration/downgrade_module_spec.ts @@ -132,64 +132,64 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-718: upgraded service not being initialized correctly on the injector') && - it('should support using an upgraded service', async(() => { - class Ng2Service { - constructor(@Inject('ng1Value') private ng1Value: string) {} - getValue = () => `${this.ng1Value}-bar`; - } + fixmeIvy('FW-718: upgraded service not being initialized correctly on the injector') + .it('should support using an upgraded service', async(() => { + class Ng2Service { + constructor(@Inject('ng1Value') private ng1Value: string) {} + getValue = () => `${this.ng1Value}-bar`; + } - @Component({selector: 'ng2', template: '{{ value }}'}) - class Ng2Component { - value: string; - constructor(ng2Service: Ng2Service) { this.value = ng2Service.getValue(); } - } + @Component({selector: 'ng2', template: '{{ value }}'}) + class Ng2Component { + value: string; + constructor(ng2Service: Ng2Service) { this.value = ng2Service.getValue(); } + } - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule], - providers: [ - Ng2Service, - { - provide: 'ng1Value', - useFactory: (i: angular.IInjectorService) => i.get('ng1Value'), - deps: ['$injector'], - }, - ], - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule], + providers: [ + Ng2Service, + { + provide: 'ng1Value', + useFactory: (i: angular.IInjectorService) => i.get('ng1Value'), + deps: ['$injector'], + }, + ], + }) + class Ng2Module { + ngDoBootstrap() {} + } - const bootstrapFn = (extraProviders: StaticProvider[]) => - platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); - const lazyModuleName = downgradeModule(bootstrapFn); - const ng1Module = - angular.module('ng1', [lazyModuleName]) - .directive( - 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) - .value('ng1Value', 'foo'); + const bootstrapFn = (extraProviders: StaticProvider[]) => + platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); + const lazyModuleName = downgradeModule(bootstrapFn); + const ng1Module = + angular.module('ng1', [lazyModuleName]) + .directive( + 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) + .value('ng1Value', 'foo'); - const element = html('
'); - const $injector = angular.bootstrap(element, [ng1Module.name]); - const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService; + const element = html('
'); + const $injector = angular.bootstrap(element, [ng1Module.name]); + const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService; - expect(element.textContent).toBe(''); - expect(() => $injector.get(INJECTOR_KEY)).toThrowError(); + expect(element.textContent).toBe(''); + expect(() => $injector.get(INJECTOR_KEY)).toThrowError(); - $rootScope.$apply('loadNg2 = true'); - expect(element.textContent).toBe(''); - expect(() => $injector.get(INJECTOR_KEY)).toThrowError(); + $rootScope.$apply('loadNg2 = true'); + expect(element.textContent).toBe(''); + expect(() => $injector.get(INJECTOR_KEY)).toThrowError(); - // Wait for the module to be bootstrapped. - setTimeout(() => { - expect(() => $injector.get(INJECTOR_KEY)).not.toThrow(); + // Wait for the module to be bootstrapped. + setTimeout(() => { + expect(() => $injector.get(INJECTOR_KEY)).not.toThrow(); - // Wait for `$evalAsync()` to propagate inputs. - setTimeout(() => expect(element.textContent).toBe('foo-bar')); - }); - })); + // Wait for `$evalAsync()` to propagate inputs. + setTimeout(() => expect(element.textContent).toBe('foo-bar')); + }); + })); it('should create components inside the Angular zone', async(() => { @Component({selector: 'ng2', template: 'In the zone: {{ inTheZone }}'}) @@ -261,66 +261,66 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - it('should propagate input changes inside the Angular zone', async(() => { - let ng2Component: Ng2Component; + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .it('should propagate input changes inside the Angular zone', async(() => { + let ng2Component: Ng2Component; - @Component({selector: 'ng2', template: ''}) - class Ng2Component implements OnChanges { - @Input() attrInput = 'foo'; - @Input() propInput = 'foo'; + @Component({selector: 'ng2', template: ''}) + class Ng2Component implements OnChanges { + @Input() attrInput = 'foo'; + @Input() propInput = 'foo'; - constructor() { ng2Component = this; } - ngOnChanges() {} - } + constructor() { ng2Component = this; } + ngOnChanges() {} + } - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule], - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule], + }) + class Ng2Module { + ngDoBootstrap() {} + } - const bootstrapFn = (extraProviders: StaticProvider[]) => - platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); - const lazyModuleName = downgradeModule(bootstrapFn); - const ng1Module = - angular.module('ng1', [lazyModuleName]) - .directive( - 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) - .run(($rootScope: angular.IRootScopeService) => { - $rootScope.attrVal = 'bar'; - $rootScope.propVal = 'bar'; - }); + const bootstrapFn = (extraProviders: StaticProvider[]) => + platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); + const lazyModuleName = downgradeModule(bootstrapFn); + const ng1Module = + angular.module('ng1', [lazyModuleName]) + .directive( + 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) + .run(($rootScope: angular.IRootScopeService) => { + $rootScope.attrVal = 'bar'; + $rootScope.propVal = 'bar'; + }); - const element = - html(''); - const $injector = angular.bootstrap(element, [ng1Module.name]); - const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService; + const element = + html(''); + const $injector = angular.bootstrap(element, [ng1Module.name]); + const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService; - setTimeout(() => { // Wait for the module to be bootstrapped. - setTimeout(() => { // Wait for `$evalAsync()` to propagate inputs. - const expectToBeInNgZone = () => expect(NgZone.isInAngularZone()).toBe(true); - const changesSpy = - spyOn(ng2Component, 'ngOnChanges').and.callFake(expectToBeInNgZone); + setTimeout(() => { // Wait for the module to be bootstrapped. + setTimeout(() => { // Wait for `$evalAsync()` to propagate inputs. + const expectToBeInNgZone = () => expect(NgZone.isInAngularZone()).toBe(true); + const changesSpy = + spyOn(ng2Component, 'ngOnChanges').and.callFake(expectToBeInNgZone); - expect(ng2Component.attrInput).toBe('bar'); - expect(ng2Component.propInput).toBe('bar'); + expect(ng2Component.attrInput).toBe('bar'); + expect(ng2Component.propInput).toBe('bar'); - $rootScope.$apply('attrVal = "baz"'); - expect(ng2Component.attrInput).toBe('baz'); - expect(ng2Component.propInput).toBe('bar'); - expect(changesSpy).toHaveBeenCalledTimes(1); + $rootScope.$apply('attrVal = "baz"'); + expect(ng2Component.attrInput).toBe('baz'); + expect(ng2Component.propInput).toBe('bar'); + expect(changesSpy).toHaveBeenCalledTimes(1); - $rootScope.$apply('propVal = "qux"'); - expect(ng2Component.attrInput).toBe('baz'); - expect(ng2Component.propInput).toBe('qux'); - expect(changesSpy).toHaveBeenCalledTimes(2); - }); - }); - })); + $rootScope.$apply('propVal = "qux"'); + expect(ng2Component.attrInput).toBe('baz'); + expect(ng2Component.propInput).toBe('qux'); + expect(changesSpy).toHaveBeenCalledTimes(2); + }); + }); + })); it('should wire up the component for change detection', async(() => { @Component( @@ -364,166 +364,168 @@ withEachNg1Version(() => { }); })); - fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should run the lifecycle hooks in the correct order', async(() => { - const logs: string[] = []; - let rootScope: angular.IRootScopeService; + fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') + .fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should run the lifecycle hooks in the correct order', async(() => { + const logs: string[] = []; + let rootScope: angular.IRootScopeService; - @Component({ - selector: 'ng2', - template: ` + @Component({ + selector: 'ng2', + template: ` {{ value }} ` - }) - class Ng2Component implements AfterContentChecked, - AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, - OnInit { - @Input() value = 'foo'; + }) + class Ng2Component implements AfterContentChecked, + AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, + OnDestroy, OnInit { + @Input() value = 'foo'; - ngAfterContentChecked() { this.log('AfterContentChecked'); } - ngAfterContentInit() { this.log('AfterContentInit'); } - ngAfterViewChecked() { this.log('AfterViewChecked'); } - ngAfterViewInit() { this.log('AfterViewInit'); } - ngDoCheck() { this.log('DoCheck'); } - ngOnChanges() { this.log('OnChanges'); } - ngOnDestroy() { this.log('OnDestroy'); } - ngOnInit() { this.log('OnInit'); } + ngAfterContentChecked() { this.log('AfterContentChecked'); } + ngAfterContentInit() { this.log('AfterContentInit'); } + ngAfterViewChecked() { this.log('AfterViewChecked'); } + ngAfterViewInit() { this.log('AfterViewInit'); } + ngDoCheck() { this.log('DoCheck'); } + ngOnChanges() { this.log('OnChanges'); } + ngOnDestroy() { this.log('OnDestroy'); } + ngOnInit() { this.log('OnInit'); } - private log(hook: string) { logs.push(`${hook}(${this.value})`); } - } + private log(hook: string) { logs.push(`${hook}(${this.value})`); } + } - @NgModule({ - declarations: [Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule], - }) - class Ng2Module { - ngDoBootstrap() {} - } + @NgModule({ + declarations: [Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule], + }) + class Ng2Module { + ngDoBootstrap() {} + } - const bootstrapFn = (extraProviders: StaticProvider[]) => - platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); - const lazyModuleName = downgradeModule(bootstrapFn); - const ng1Module = - angular.module('ng1', [lazyModuleName]) - .directive( - 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) - .run(($rootScope: angular.IRootScopeService) => { - rootScope = $rootScope; - rootScope.value = 'bar'; - }); + const bootstrapFn = (extraProviders: StaticProvider[]) => + platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module); + const lazyModuleName = downgradeModule(bootstrapFn); + const ng1Module = + angular.module('ng1', [lazyModuleName]) + .directive( + 'ng2', downgradeComponent({component: Ng2Component, propagateDigest})) + .run(($rootScope: angular.IRootScopeService) => { + rootScope = $rootScope; + rootScope.value = 'bar'; + }); - const element = - html('
Content
'); - angular.bootstrap(element, [ng1Module.name]); + const element = + html('
Content
'); + angular.bootstrap(element, [ng1Module.name]); - setTimeout(() => { // Wait for the module to be bootstrapped. - setTimeout(() => { // Wait for `$evalAsync()` to propagate inputs. - const button = element.querySelector('button') !; + setTimeout(() => { // Wait for the module to be bootstrapped. + setTimeout(() => { // Wait for `$evalAsync()` to propagate inputs. + const button = element.querySelector('button') !; - // Once initialized. - expect(multiTrim(element.textContent)).toBe('bar Content'); - expect(logs).toEqual([ - // `ngOnChanges()` call triggered directly through the `inputChanges` $watcher. - 'OnChanges(bar)', - // Initial CD triggered directly through the `detectChanges()` or - // `inputChanges` - // $watcher (for `propagateDigest` true/false respectively). - 'OnInit(bar)', - 'DoCheck(bar)', - 'AfterContentInit(bar)', - 'AfterContentChecked(bar)', - 'AfterViewInit(bar)', - 'AfterViewChecked(bar)', - ...(propagateDigest ? - [ - // CD triggered directly through the `detectChanges()` $watcher (2nd - // $digest). - 'DoCheck(bar)', - 'AfterContentChecked(bar)', - 'AfterViewChecked(bar)', - ] : - []), - // CD triggered due to entering/leaving the NgZone (in `downgradeFn()`). - 'DoCheck(bar)', - 'AfterContentChecked(bar)', - 'AfterViewChecked(bar)', - ]); - logs.length = 0; + // Once initialized. + expect(multiTrim(element.textContent)).toBe('bar Content'); + expect(logs).toEqual([ + // `ngOnChanges()` call triggered directly through the `inputChanges` + // $watcher. + 'OnChanges(bar)', + // Initial CD triggered directly through the `detectChanges()` or + // `inputChanges` + // $watcher (for `propagateDigest` true/false respectively). + 'OnInit(bar)', + 'DoCheck(bar)', + 'AfterContentInit(bar)', + 'AfterContentChecked(bar)', + 'AfterViewInit(bar)', + 'AfterViewChecked(bar)', + ...(propagateDigest ? + [ + // CD triggered directly through the `detectChanges()` $watcher (2nd + // $digest). + 'DoCheck(bar)', + 'AfterContentChecked(bar)', + 'AfterViewChecked(bar)', + ] : + []), + // CD triggered due to entering/leaving the NgZone (in `downgradeFn()`). + 'DoCheck(bar)', + 'AfterContentChecked(bar)', + 'AfterViewChecked(bar)', + ]); + logs.length = 0; - // Change inputs and run `$digest`. - rootScope.$apply('value = "baz"'); - expect(multiTrim(element.textContent)).toBe('baz Content'); - expect(logs).toEqual([ - // `ngOnChanges()` call triggered directly through the `inputChanges` $watcher. - 'OnChanges(baz)', - // `propagateDigest: true` (3 CD runs): - // - CD triggered due to entering/leaving the NgZone (in `inputChanges` - // $watcher). - // - CD triggered directly through the `detectChanges()` $watcher. - // - CD triggered due to entering/leaving the NgZone (in `detectChanges` - // $watcher). - // `propagateDigest: false` (2 CD runs): - // - CD triggered directly through the `inputChanges` $watcher. - // - CD triggered due to entering/leaving the NgZone (in `inputChanges` - // $watcher). - 'DoCheck(baz)', - 'AfterContentChecked(baz)', - 'AfterViewChecked(baz)', - 'DoCheck(baz)', - 'AfterContentChecked(baz)', - 'AfterViewChecked(baz)', - ...(propagateDigest ? - [ - 'DoCheck(baz)', - 'AfterContentChecked(baz)', - 'AfterViewChecked(baz)', - ] : - []), - ]); - logs.length = 0; + // Change inputs and run `$digest`. + rootScope.$apply('value = "baz"'); + expect(multiTrim(element.textContent)).toBe('baz Content'); + expect(logs).toEqual([ + // `ngOnChanges()` call triggered directly through the `inputChanges` + // $watcher. + 'OnChanges(baz)', + // `propagateDigest: true` (3 CD runs): + // - CD triggered due to entering/leaving the NgZone (in `inputChanges` + // $watcher). + // - CD triggered directly through the `detectChanges()` $watcher. + // - CD triggered due to entering/leaving the NgZone (in `detectChanges` + // $watcher). + // `propagateDigest: false` (2 CD runs): + // - CD triggered directly through the `inputChanges` $watcher. + // - CD triggered due to entering/leaving the NgZone (in `inputChanges` + // $watcher). + 'DoCheck(baz)', + 'AfterContentChecked(baz)', + 'AfterViewChecked(baz)', + 'DoCheck(baz)', + 'AfterContentChecked(baz)', + 'AfterViewChecked(baz)', + ...(propagateDigest ? + [ + 'DoCheck(baz)', + 'AfterContentChecked(baz)', + 'AfterViewChecked(baz)', + ] : + []), + ]); + logs.length = 0; - // Run `$digest` (without changing inputs). - rootScope.$digest(); - expect(multiTrim(element.textContent)).toBe('baz Content'); - expect(logs).toEqual( - propagateDigest ? - [ - // CD triggered directly through the `detectChanges()` $watcher. - 'DoCheck(baz)', - 'AfterContentChecked(baz)', - 'AfterViewChecked(baz)', - // CD triggered due to entering/leaving the NgZone (in the above - // $watcher). - 'DoCheck(baz)', - 'AfterContentChecked(baz)', - 'AfterViewChecked(baz)', - ] : - []); - logs.length = 0; + // Run `$digest` (without changing inputs). + rootScope.$digest(); + expect(multiTrim(element.textContent)).toBe('baz Content'); + expect(logs).toEqual( + propagateDigest ? + [ + // CD triggered directly through the `detectChanges()` $watcher. + 'DoCheck(baz)', + 'AfterContentChecked(baz)', + 'AfterViewChecked(baz)', + // CD triggered due to entering/leaving the NgZone (in the above + // $watcher). + 'DoCheck(baz)', + 'AfterContentChecked(baz)', + 'AfterViewChecked(baz)', + ] : + []); + logs.length = 0; - // Trigger change detection (without changing inputs). - button.click(); - expect(multiTrim(element.textContent)).toBe('qux Content'); - expect(logs).toEqual([ - 'DoCheck(qux)', - 'AfterContentChecked(qux)', - 'AfterViewChecked(qux)', - ]); - logs.length = 0; + // Trigger change detection (without changing inputs). + button.click(); + expect(multiTrim(element.textContent)).toBe('qux Content'); + expect(logs).toEqual([ + 'DoCheck(qux)', + 'AfterContentChecked(qux)', + 'AfterViewChecked(qux)', + ]); + logs.length = 0; - // Destroy the component. - rootScope.$apply('hideNg2 = true'); - expect(logs).toEqual([ - 'OnDestroy(qux)', - ]); - logs.length = 0; - }); - }); - })); + // Destroy the component. + rootScope.$apply('hideNg2 = true'); + expect(logs).toEqual([ + 'OnDestroy(qux)', + ]); + logs.length = 0; + }); + }); + })); it('should detach hostViews from the ApplicationRef once destroyed', async(() => { let ng2Component: Ng2Component; diff --git a/packages/upgrade/test/static/integration/examples_spec.ts b/packages/upgrade/test/static/integration/examples_spec.ts index dc3244a228..90b66a88fa 100644 --- a/packages/upgrade/test/static/integration/examples_spec.ts +++ b/packages/upgrade/test/static/integration/examples_spec.ts @@ -24,70 +24,70 @@ withEachNg1Version(() => { it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1)); - fixmeIvy('FW-714: ng1 projected content is not being rendered') && - it('should verify UpgradeAdapter example', async(() => { + fixmeIvy('FW-714: ng1 projected content is not being rendered') + .it('should verify UpgradeAdapter example', async(() => { - // This is wrapping (upgrading) an AngularJS component to be used in an Angular - // component - @Directive({selector: 'ng1'}) - class Ng1Component extends UpgradeComponent { - // TODO(issue/24571): remove '!'. - @Input() title !: string; + // This is wrapping (upgrading) an AngularJS component to be used in an Angular + // component + @Directive({selector: 'ng1'}) + class Ng1Component extends UpgradeComponent { + // TODO(issue/24571): remove '!'. + @Input() title !: string; - constructor(elementRef: ElementRef, injector: Injector) { - super('ng1', elementRef, injector); - } - } + constructor(elementRef: ElementRef, injector: Injector) { + super('ng1', elementRef, injector); + } + } - // This is an Angular component that will be downgraded - @Component({ - selector: 'ng2', - template: 'ng2[transclude]()' - }) - class Ng2Component { - // TODO(issue/24571): remove '!'. - @Input('name') nameProp !: string; - } + // This is an Angular component that will be downgraded + @Component({ + selector: 'ng2', + template: 'ng2[transclude]()' + }) + class Ng2Component { + // TODO(issue/24571): remove '!'. + @Input('name') nameProp !: string; + } - // This module represents the Angular pieces of the application - @NgModule({ - declarations: [Ng1Component, Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() { /* this is a placeholder to stop the bootstrapper from - complaining */ - } - } + // This module represents the Angular pieces of the application + @NgModule({ + declarations: [Ng1Component, Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() { /* this is a placeholder to stop the bootstrapper from + complaining */ + } + } - // This module represents the AngularJS pieces of the application - const ng1Module = - angular - .module('myExample', []) - // This is an AngularJS component that will be upgraded - .directive( - 'ng1', - () => { - return { - scope: {title: '='}, - transclude: true, - template: 'ng1[Hello {{title}}!]()' - }; - }) - // This is wrapping (downgrading) an Angular component to be used in - // AngularJS - .directive('ng2', downgradeComponent({component: Ng2Component})); + // This module represents the AngularJS pieces of the application + const ng1Module = + angular + .module('myExample', []) + // This is an AngularJS component that will be upgraded + .directive( + 'ng1', + () => { + return { + scope: {title: '='}, + transclude: true, + template: 'ng1[Hello {{title}}!]()' + }; + }) + // This is wrapping (downgrading) an Angular component to be used in + // AngularJS + .directive('ng2', downgradeComponent({component: Ng2Component})); - // This is the (AngularJS) application bootstrap element - // Notice that it is actually a downgraded Angular component - const element = html('project'); + // This is the (AngularJS) application bootstrap element + // Notice that it is actually a downgraded Angular component + const element = html('project'); - // Let's use a helper function to make this simpler - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { - expect(multiTrim(element.textContent)) - .toBe('ng2[ng1[Hello World!](transclude)](project)'); - }); - })); + // Let's use a helper function to make this simpler + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => { + expect(multiTrim(element.textContent)) + .toBe('ng2[ng1[Hello World!](transclude)](project)'); + }); + })); }); }); diff --git a/packages/upgrade/test/static/integration/upgrade_component_spec.ts b/packages/upgrade/test/static/integration/upgrade_component_spec.ts index 63f050b8cb..cc6fa47ec7 100644 --- a/packages/upgrade/test/static/integration/upgrade_component_spec.ts +++ b/packages/upgrade/test/static/integration/upgrade_component_spec.ts @@ -2135,76 +2135,76 @@ withEachNg1Version(() => { describe('transclusion', () => { fixmeIvy( - `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) && - it('should support single-slot transclusion', async(() => { - let ng2ComponentAInstance: Ng2ComponentA; - let ng2ComponentBInstance: Ng2ComponentB; + `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) + .it('should support single-slot transclusion', async(() => { + let ng2ComponentAInstance: Ng2ComponentA; + let ng2ComponentBInstance: Ng2ComponentB; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: 'ng1(
)', - transclude: true - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: 'ng1(
)', + transclude: true + }; - // Define `Ng1ComponentFacade` - @Directive({selector: 'ng1'}) - class Ng1ComponentFacade extends UpgradeComponent { - constructor(elementRef: ElementRef, injector: Injector) { - super('ng1', elementRef, injector); - } - } + // Define `Ng1ComponentFacade` + @Directive({selector: 'ng1'}) + class Ng1ComponentFacade extends UpgradeComponent { + constructor(elementRef: ElementRef, injector: Injector) { + super('ng1', elementRef, injector); + } + } - // Define `Ng2Component` - @Component({ - selector: 'ng2A', - template: 'ng2A({{ value }} | )' - }) - class Ng2ComponentA { - value = 'foo'; - showB = false; - constructor() { ng2ComponentAInstance = this; } - } + // Define `Ng2Component` + @Component({ + selector: 'ng2A', + template: 'ng2A({{ value }} | )' + }) + class Ng2ComponentA { + value = 'foo'; + showB = false; + constructor() { ng2ComponentAInstance = this; } + } - @Component({selector: 'ng2B', template: 'ng2B({{ value }})'}) - class Ng2ComponentB { - value = 'bar'; - constructor() { ng2ComponentBInstance = this; } - } + @Component({selector: 'ng2B', template: 'ng2B({{ value }})'}) + class Ng2ComponentB { + value = 'bar'; + constructor() { ng2ComponentBInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2A', downgradeComponent({component: Ng2ComponentA})); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2A', downgradeComponent({component: Ng2ComponentA})); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule, UpgradeModule], - declarations: [Ng1ComponentFacade, Ng2ComponentA, Ng2ComponentB], - entryComponents: [Ng2ComponentA] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule, UpgradeModule], + declarations: [Ng1ComponentFacade, Ng2ComponentA, Ng2ComponentB], + entryComponents: [Ng2ComponentA] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(foo | ))'); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(foo | ))'); - ng2ComponentAInstance.value = 'baz'; - ng2ComponentAInstance.showB = true; - $digest(adapter); + ng2ComponentAInstance.value = 'baz'; + ng2ComponentAInstance.showB = true; + $digest(adapter); - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(bar)))'); + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(bar)))'); - ng2ComponentBInstance.value = 'qux'; - $digest(adapter); + ng2ComponentBInstance.value = 'qux'; + $digest(adapter); - expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(qux)))'); - }); - })); + expect(multiTrim(element.textContent)).toBe('ng2A(ng1(baz | ng2B(qux)))'); + }); + })); it('should support single-slot transclusion with fallback content', async(() => { let ng1ControllerInstances: any[] = []; @@ -2532,29 +2532,29 @@ withEachNg1Version(() => { })); fixmeIvy( - `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) && - it('should support structural directives in transcluded content', async(() => { - let ng2ComponentInstance: Ng2Component; + `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) + .it('should support structural directives in transcluded content', async(() => { + let ng2ComponentInstance: Ng2Component; - // Define `ng1Component` - const ng1Component: angular.IComponent = { - template: - 'ng1(x(
) | default(
))', - transclude: {slotX: 'contentX'} - }; + // Define `ng1Component` + const ng1Component: angular.IComponent = { + template: + 'ng1(x(
) | default(
))', + transclude: {slotX: 'contentX'} + }; - // Define `Ng1ComponentFacade` - @Directive({selector: 'ng1'}) - class Ng1ComponentFacade extends UpgradeComponent { - constructor(elementRef: ElementRef, injector: Injector) { - super('ng1', elementRef, injector); - } - } + // Define `Ng1ComponentFacade` + @Directive({selector: 'ng1'}) + class Ng1ComponentFacade extends UpgradeComponent { + constructor(elementRef: ElementRef, injector: Injector) { + super('ng1', elementRef, injector); + } + } - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: ` + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: ` ng2(
{{ x }}1
@@ -2563,53 +2563,53 @@ withEachNg1Version(() => {
{{ y }}2
)` - }) - class Ng2Component { - x = 'foo'; - y = 'bar'; - show = true; - constructor() { ng2ComponentInstance = this; } - } + }) + class Ng2Component { + x = 'foo'; + y = 'bar'; + show = true; + constructor() { ng2ComponentInstance = this; } + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .component('ng1', ng1Component) - .directive('ng2', downgradeComponent({component: Ng2Component})); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .component('ng1', ng1Component) + .directive('ng2', downgradeComponent({component: Ng2Component})); - // Define `Ng2Module` - @NgModule({ - imports: [BrowserModule, UpgradeModule], - declarations: [Ng1ComponentFacade, Ng2Component], - entryComponents: [Ng2Component], - schemas: [NO_ERRORS_SCHEMA] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // Define `Ng2Module` + @NgModule({ + imports: [BrowserModule, UpgradeModule], + declarations: [Ng1ComponentFacade, Ng2Component], + entryComponents: [Ng2Component], + schemas: [NO_ERRORS_SCHEMA] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // Bootstrap - const element = html(``); + // Bootstrap + const element = html(``); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(foo1)|default(bar2)))'); + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(foo1)|default(bar2)))'); - ng2ComponentInstance.x = 'baz'; - ng2ComponentInstance.y = 'qux'; - ng2ComponentInstance.show = false; - $digest(adapter); + ng2ComponentInstance.x = 'baz'; + ng2ComponentInstance.y = 'qux'; + ng2ComponentInstance.show = false; + $digest(adapter); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(baz2)|default(qux1)))'); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(baz2)|default(qux1)))'); - ng2ComponentInstance.show = true; - $digest(adapter); + ng2ComponentInstance.show = true; + $digest(adapter); - expect(multiTrim(element.textContent, true)) - .toBe('ng2(ng1(x(baz1)|default(qux2)))'); - }); - })); + expect(multiTrim(element.textContent, true)) + .toBe('ng2(ng1(x(baz1)|default(qux2)))'); + }); + })); }); describe('lifecycle hooks', () => { @@ -3336,103 +3336,105 @@ withEachNg1Version(() => { })); - fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && - it('should call `$onDestroy()` on controller', async(() => { - const controllerOnDestroyA = jasmine.createSpy('controllerOnDestroyA'); - const controllerOnDestroyB = jasmine.createSpy('controllerOnDestroyB'); + fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') + .it('should call `$onDestroy()` on controller', async(() => { + const controllerOnDestroyA = jasmine.createSpy('controllerOnDestroyA'); + const controllerOnDestroyB = jasmine.createSpy('controllerOnDestroyB'); - // Define `ng1Directive` - const ng1DirectiveA: angular.IDirective = { - template: 'ng1A', - scope: {}, - bindToController: false, - controllerAs: '$ctrl', - controller: class {$onDestroy() { controllerOnDestroyA(); }} - }; + // Define `ng1Directive` + const ng1DirectiveA: angular.IDirective = { + template: 'ng1A', + scope: {}, + bindToController: false, + controllerAs: '$ctrl', + controller: class {$onDestroy() { controllerOnDestroyA(); }} + }; - const ng1DirectiveB: angular.IDirective = { - template: 'ng1B', - scope: {}, - bindToController: true, - controllerAs: '$ctrl', - controller: - class {constructor() { (this as any)['$onDestroy'] = controllerOnDestroyB; }} - }; + const ng1DirectiveB: angular.IDirective = { + template: 'ng1B', + scope: {}, + bindToController: true, + controllerAs: '$ctrl', + controller: class { + constructor() { (this as any)['$onDestroy'] = controllerOnDestroyB; } + } + }; - // Define `Ng1ComponentFacade` - @Directive({selector: 'ng1A'}) - class Ng1ComponentAFacade extends UpgradeComponent { - constructor(elementRef: ElementRef, injector: Injector) { - super('ng1A', elementRef, injector); - } - } + // Define `Ng1ComponentFacade` + @Directive({selector: 'ng1A'}) + class Ng1ComponentAFacade extends UpgradeComponent { + constructor(elementRef: ElementRef, injector: Injector) { + super('ng1A', elementRef, injector); + } + } - @Directive({selector: 'ng1B'}) - class Ng1ComponentBFacade extends UpgradeComponent { - constructor(elementRef: ElementRef, injector: Injector) { - super('ng1B', elementRef, injector); - } - } + @Directive({selector: 'ng1B'}) + class Ng1ComponentBFacade extends UpgradeComponent { + constructor(elementRef: ElementRef, injector: Injector) { + super('ng1B', elementRef, injector); + } + } - // Define `Ng2Component` - @Component({ - selector: 'ng2', - template: '
|
' - }) - class Ng2Component { - // TODO(issue/24571): remove '!'. - @Input() show !: boolean; - } + // Define `Ng2Component` + @Component({ + selector: 'ng2', + template: '
|
' + }) + class Ng2Component { + // TODO(issue/24571): remove '!'. + @Input() show !: boolean; + } - // Define `ng1Module` - const ng1Module = - angular.module('ng1Module', []) - .directive('ng1A', () => ng1DirectiveA) - .directive('ng1B', () => ng1DirectiveB) - .directive('ng2', downgradeComponent({component: Ng2Component})); + // Define `ng1Module` + const ng1Module = + angular.module('ng1Module', []) + .directive('ng1A', () => ng1DirectiveA) + .directive('ng1B', () => ng1DirectiveB) + .directive('ng2', downgradeComponent({component: Ng2Component})); - // Define `Ng2Module` - @NgModule({ - declarations: [Ng1ComponentAFacade, Ng1ComponentBFacade, Ng2Component], - entryComponents: [Ng2Component], - imports: [BrowserModule, UpgradeModule] - }) - class Ng2Module { - ngDoBootstrap() {} - } + // Define `Ng2Module` + @NgModule({ + declarations: [Ng1ComponentAFacade, Ng1ComponentBFacade, Ng2Component], + entryComponents: [Ng2Component], + imports: [BrowserModule, UpgradeModule] + }) + class Ng2Module { + ngDoBootstrap() {} + } - // Bootstrap - const element = html(''); + // Bootstrap + const element = + html(''); - bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { - const $rootScope = - adapter.$injector.get('$rootScope') as angular.IRootScopeService; + bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { + const $rootScope = + adapter.$injector.get('$rootScope') as angular.IRootScopeService; - expect(multiTrim(document.body.textContent)).toBe('ng1A | ng1B'); - expect(controllerOnDestroyA).not.toHaveBeenCalled(); - expect(controllerOnDestroyB).not.toHaveBeenCalled(); + expect(multiTrim(document.body.textContent)).toBe('ng1A | ng1B'); + expect(controllerOnDestroyA).not.toHaveBeenCalled(); + expect(controllerOnDestroyB).not.toHaveBeenCalled(); - $rootScope.$apply('destroyFromNg1 = true'); + $rootScope.$apply('destroyFromNg1 = true'); - expect(multiTrim(document.body.textContent)).toBe(''); - expect(controllerOnDestroyA).toHaveBeenCalled(); - expect(controllerOnDestroyB).toHaveBeenCalled(); + expect(multiTrim(document.body.textContent)).toBe(''); + expect(controllerOnDestroyA).toHaveBeenCalled(); + expect(controllerOnDestroyB).toHaveBeenCalled(); - controllerOnDestroyA.calls.reset(); - controllerOnDestroyB.calls.reset(); - $rootScope.$apply('destroyFromNg1 = false'); + controllerOnDestroyA.calls.reset(); + controllerOnDestroyB.calls.reset(); + $rootScope.$apply('destroyFromNg1 = false'); - expect(multiTrim(document.body.textContent)).toBe('ng1A | ng1B'); - expect(controllerOnDestroyA).not.toHaveBeenCalled(); - expect(controllerOnDestroyB).not.toHaveBeenCalled(); + expect(multiTrim(document.body.textContent)).toBe('ng1A | ng1B'); + expect(controllerOnDestroyA).not.toHaveBeenCalled(); + expect(controllerOnDestroyB).not.toHaveBeenCalled(); - $rootScope.$apply('destroyFromNg2 = true'); + $rootScope.$apply('destroyFromNg2 = true'); - expect(multiTrim(document.body.textContent)).toBe(''); - expect(controllerOnDestroyA).toHaveBeenCalled(); - expect(controllerOnDestroyB).toHaveBeenCalled(); - }); - })); + expect(multiTrim(document.body.textContent)).toBe(''); + expect(controllerOnDestroyA).toHaveBeenCalled(); + expect(controllerOnDestroyB).toHaveBeenCalled(); + }); + })); it('should not call `$onDestroy()` on scope', async(() => { const scopeOnDestroy = jasmine.createSpy('scopeOnDestroy');