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
This commit is contained in:
Alex Rickabaugh 2019-01-09 13:33:11 -08:00 committed by Andrew Kushnir
parent d0c3e252a3
commit 11325bad4a
1 changed files with 127 additions and 132 deletions

View File

@ -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<any, Base>;
let summaries: () => any[];
obsoleteInIvy('Summaries are not used/supported/able to be produced in Ivy. See FW-838.')
.describe('Jit Summaries', () => {
let instances: Map<any, Base>;
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: '<div someDir>{{1 | somePipe}}</div>'})
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: '<div someDir>{{1 | somePipe}}</div>'})
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<any, any>();
createSummaries().then(s => summaries = s);
}));
beforeEach(async(() => {
instances = new Map<any, any>();
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: '<div someDir></div>'})
@ -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>(TestCompErrorOnDestroy);
const fixture =
TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]})
.createComponent<TestCompErrorOnDestroy>(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: '<div someDir></div>'})
@ -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');
});
});
});
}