From 11325bad4ab786a07e52ff380c00622fda11c0b7 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Wed, 9 Jan 2019 13:33:11 -0800 Subject: [PATCH] test(ivy): mark jit_summaries_integration_spec as obsolete in Ivy (#28027) These tests validate the ability of the View Engine TestBed to consume summary metadata, a mechanism which allows the TestBed to use AOT-compiled components & directives in tests. It achieves this through two operations which are independently obsolete in Ivy: 1. It injects CompileMetadataResolver, a View Engine specific compiler internal class which extracts global analysis metadata from classes, and uses it to construct summary metadata. This happens in a beforeEach() block which calls createSummaries(). 2. It uses TestBed.initTestEnvironment to pass summary metadata to the TestBed itself. Any such metadata is ignored in Ivy. Operation #1 makes it impossible to run these tests under Ivy, as the CompileMetadataResolver is not available with an Ivy compiler. Ivy itself does not rely on summary data, and the R3TestBed can depend directly on AOT compiled components without it. Thus, the spirit of thes tests is obsolete in an Ivy world. FW-838 #resolve PR Close #28027 --- .../linker/jit_summaries_integration_spec.ts | 259 +++++++++--------- 1 file changed, 127 insertions(+), 132 deletions(-) diff --git a/packages/core/test/linker/jit_summaries_integration_spec.ts b/packages/core/test/linker/jit_summaries_integration_spec.ts index c1cb61ada6..170bd288f0 100644 --- a/packages/core/test/linker/jit_summaries_integration_spec.ts +++ b/packages/core/test/linker/jit_summaries_integration_spec.ts @@ -12,133 +12,136 @@ import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_ import {Component, Directive, Injectable, NgModule, OnDestroy, Pipe} from '@angular/core'; import {TestBed, async, getTestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/src/matchers'; -import {fixmeIvy} from '@angular/private/testing'; +import {obsoleteInIvy} from '@angular/private/testing'; { - describe('Jit Summaries', () => { - let instances: Map; - let summaries: () => any[]; + obsoleteInIvy('Summaries are not used/supported/able to be produced in Ivy. See FW-838.') + .describe('Jit Summaries', () => { + let instances: Map; + let summaries: () => any[]; - class SomeDep {} + class SomeDep {} - class Base { - static annotations: any[]; - static parameters: any[][]; + class Base { + static annotations: any[]; + static parameters: any[][]; - constructor(public dep: SomeDep) { - instances.set(Object.getPrototypeOf(this).constructor, this); - } - } + constructor(public dep: SomeDep) { + instances.set(Object.getPrototypeOf(this).constructor, this); + } + } - function expectInstanceCreated(type: any) { - const instance = instances.get(type) !; - expect(instance).toBeDefined(); - expect(instance.dep instanceof SomeDep).toBe(true); - } + function expectInstanceCreated(type: any) { + const instance = instances.get(type) !; + expect(instance).toBeDefined(); + expect(instance.dep instanceof SomeDep).toBe(true); + } - class SomeModule extends Base {} + class SomeModule extends Base {} - class SomePrivateComponent extends Base {} + class SomePrivateComponent extends Base {} - class SomePublicComponent extends Base {} + class SomePublicComponent extends Base {} - class SomeDirective extends Base {} + class SomeDirective extends Base {} - class SomePipe extends Base { - transform(value: any) { return value; } - } + class SomePipe extends Base { + transform(value: any) { return value; } + } - class SomeService extends Base {} + class SomeService extends Base {} - // Move back into the it which needs it after https://github.com/angular/tsickle/issues/547 is - // fixed. - @Component({template: '
{{1 | somePipe}}
'}) - class TestComp3 { - constructor(service: SomeService) {} - } + // Move back into the it which needs it after https://github.com/angular/tsickle/issues/547 + // is + // fixed. + @Component({template: '
{{1 | somePipe}}
'}) + class TestComp3 { + constructor(service: SomeService) {} + } - @Component({template: ''}) - class TestCompErrorOnDestroy implements OnDestroy { - ngOnDestroy() {} - } + @Component({template: ''}) + class TestCompErrorOnDestroy implements OnDestroy { + ngOnDestroy() {} + } - function resetTestEnvironmentWithSummaries(summaries?: () => any[]) { - const {platform, ngModule} = getTestBed(); - TestBed.resetTestEnvironment(); - TestBed.initTestEnvironment(ngModule, platform, summaries); - } + function resetTestEnvironmentWithSummaries(summaries?: () => any[]) { + const {platform, ngModule} = getTestBed(); + TestBed.resetTestEnvironment(); + TestBed.initTestEnvironment(ngModule, platform, summaries); + } - function createSummaries() { - const resourceLoader = new MockResourceLoader(); + function createSummaries() { + const resourceLoader = new MockResourceLoader(); - setMetadata(resourceLoader); + setMetadata(resourceLoader); - TestBed.configureCompiler({providers: [{provide: ResourceLoader, useValue: resourceLoader}]}); - TestBed.configureTestingModule({imports: [SomeModule], providers: [SomeDep]}); + TestBed.configureCompiler( + {providers: [{provide: ResourceLoader, useValue: resourceLoader}]}); + TestBed.configureTestingModule({imports: [SomeModule], providers: [SomeDep]}); - let summariesPromise = TestBed.compileComponents().then(() => { - const metadataResolver = TestBed.get(CompileMetadataResolver) as CompileMetadataResolver; - const summaries = [ - metadataResolver.getNgModuleSummary(SomeModule), - // test nesting via closures, as we use this in the generated code too. - () => - [metadataResolver.getDirectiveSummary(SomePublicComponent), - metadataResolver.getDirectiveSummary(SomePrivateComponent), - ], - metadataResolver.getDirectiveSummary(SomeDirective), - metadataResolver.getPipeSummary(SomePipe), - metadataResolver.getInjectableSummary(SomeService) - ]; - clearMetadata(); - TestBed.resetTestingModule(); - return () => summaries; - }); + let summariesPromise = TestBed.compileComponents().then(() => { + const metadataResolver = + TestBed.get(CompileMetadataResolver) as CompileMetadataResolver; + const summaries = [ + metadataResolver.getNgModuleSummary(SomeModule), + // test nesting via closures, as we use this in the generated code too. + () => + [metadataResolver.getDirectiveSummary(SomePublicComponent), + metadataResolver.getDirectiveSummary(SomePrivateComponent), + ], + metadataResolver.getDirectiveSummary(SomeDirective), + metadataResolver.getPipeSummary(SomePipe), + metadataResolver.getInjectableSummary(SomeService) + ]; + clearMetadata(); + TestBed.resetTestingModule(); + return () => summaries; + }); - resourceLoader.flush(); - return summariesPromise; - } + resourceLoader.flush(); + return summariesPromise; + } - function setMetadata(resourceLoader: MockResourceLoader) { - Base.parameters = [[SomeDep]]; + function setMetadata(resourceLoader: MockResourceLoader) { + Base.parameters = [[SomeDep]]; - SomeModule.annotations = [new NgModule({ - declarations: [SomePublicComponent, SomePrivateComponent, SomeDirective, SomePipe], - exports: [SomeDirective, SomePipe, SomePublicComponent], - providers: [SomeService] - })]; + SomeModule.annotations = [new NgModule({ + declarations: [SomePublicComponent, SomePrivateComponent, SomeDirective, SomePipe], + exports: [SomeDirective, SomePipe, SomePublicComponent], + providers: [SomeService] + })]; - SomePublicComponent.annotations = [new Component({templateUrl: 'somePublicUrl.html'})]; - resourceLoader.expect('somePublicUrl.html', `Hello public world!`); + SomePublicComponent.annotations = [new Component({templateUrl: 'somePublicUrl.html'})]; + resourceLoader.expect('somePublicUrl.html', `Hello public world!`); - SomePrivateComponent.annotations = [new Component({templateUrl: 'somePrivateUrl.html'})]; - resourceLoader.expect('somePrivateUrl.html', `Hello private world!`); + SomePrivateComponent.annotations = [new Component({templateUrl: 'somePrivateUrl.html'})]; + resourceLoader.expect('somePrivateUrl.html', `Hello private world!`); - SomeDirective.annotations = [new Directive({selector: '[someDir]'})]; + SomeDirective.annotations = [new Directive({selector: '[someDir]'})]; - SomePipe.annotations = [new Pipe({name: 'somePipe'})]; + SomePipe.annotations = [new Pipe({name: 'somePipe'})]; - SomeService.annotations = [new Injectable()]; - } + SomeService.annotations = [new Injectable()]; + } - function clearMetadata() { - Base.parameters = []; - SomeModule.annotations = []; - SomePublicComponent.annotations = []; - SomePrivateComponent.annotations = []; - SomeDirective.annotations = []; - SomePipe.annotations = []; - SomeService.annotations = []; - } + function clearMetadata() { + Base.parameters = []; + SomeModule.annotations = []; + SomePublicComponent.annotations = []; + SomePrivateComponent.annotations = []; + SomeDirective.annotations = []; + SomePipe.annotations = []; + SomeService.annotations = []; + } - beforeEach(async(() => { - instances = new Map(); - createSummaries().then(s => summaries = s); - })); + beforeEach(async(() => { + instances = new Map(); + createSummaries().then(s => summaries = s); + })); - afterEach(() => { resetTestEnvironmentWithSummaries(); }); + afterEach(() => { resetTestEnvironmentWithSummaries(); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should use directive metadata from summaries', () => { + it('should use directive metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); @Component({template: '
'}) @@ -152,8 +155,8 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeDirective); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should use pipe metadata from summaries', () => { + + it('should use pipe metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); @Component({template: '{{1 | somePipe}}'}) @@ -165,8 +168,7 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomePipe); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should use Service metadata from summaries', () => { + it('should use Service metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.configureTestingModule({ @@ -176,8 +178,7 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeService); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should use NgModule metadata from summaries', () => { + it('should use NgModule metadata from summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed @@ -191,8 +192,7 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeService); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should allow to create private components from imported NgModule summaries', () => { + it('should allow to create private components from imported NgModule summaries', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) @@ -200,8 +200,7 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomePrivateComponent); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should throw when trying to mock a type with a summary', () => { + it('should throw when trying to mock a type with a summary', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.resetTestingModule(); @@ -220,35 +219,33 @@ import {fixmeIvy} from '@angular/private/testing'; .toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.'); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should return stack trace and component data on resetTestingModule when error is thrown', - () => { - resetTestEnvironmentWithSummaries(); + 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-838: ivy testbed doesn\'t support jit summaries') - .it('should allow to add summaries via configureTestingModule', () => { + it('should allow to add summaries via configureTestingModule', () => { resetTestEnvironmentWithSummaries(); @Component({template: '
'}) @@ -265,8 +262,7 @@ import {fixmeIvy} from '@angular/private/testing'; expectInstanceCreated(SomeDirective); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should allow to override a provider', () => { + it('should allow to override a provider', () => { resetTestEnvironmentWithSummaries(summaries); const overwrittenValue = {}; @@ -279,8 +275,7 @@ import {fixmeIvy} from '@angular/private/testing'; expect(fixture.componentInstance.dep).toBe(overwrittenValue); }); - fixmeIvy('FW-838: ivy testbed doesn\'t support jit summaries') - .it('should allow to override a template', () => { + it('should allow to override a template', () => { resetTestEnvironmentWithSummaries(summaries); TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten'); @@ -292,5 +287,5 @@ import {fixmeIvy} from '@angular/private/testing'; expect(fixture.nativeElement).toHaveText('overwritten'); }); - }); + }); }