-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve AOT unit tests #19996
Improve AOT unit tests #19996
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ import {CompileMetadataResolver} from '@angular/compiler/src/metadata_resolver'; | |
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock'; | ||
import {Component, Directive, Injectable, NgModule, Pipe, Type} from '@angular/core'; | ||
import {TestBed, async, getTestBed} from '@angular/core/testing'; | ||
import {expect} from '@angular/platform-browser/testing/src/matchers'; | ||
|
||
export function main() { | ||
describe('Jit Summaries', () => { | ||
|
@@ -222,5 +223,29 @@ export function main() { | |
.createComponent(TestComp); | ||
expectInstanceCreated(SomeDirective); | ||
}); | ||
|
||
it('should allow to override a provider', () => { | ||
resetTestEnvironmentWithSummaries(summaries); | ||
|
||
const overwrittenValue = {}; | ||
|
||
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. chain call (or assert the type of the return value) ? |
||
|
||
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) | ||
.createComponent(SomePublicComponent); | ||
expect(fixture.componentInstance.dep).toBe(overwrittenValue); | ||
}); | ||
|
||
it('should allow to override a template', () => { | ||
resetTestEnvironmentWithSummaries(summaries); | ||
|
||
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wouldn't this test work the same with |
||
|
||
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) | ||
.createComponent(SomePublicComponent); | ||
expectInstanceCreated(SomePublicComponent); | ||
|
||
expect(fixture.nativeElement).toHaveText('overwritten'); | ||
}); | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectionToken, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, Type, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearProviderOverrides as clearProviderOverrides, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core'; | ||
import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectionToken, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, Type, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core'; | ||
|
||
import {AsyncTestCompleter} from './async_test_completer'; | ||
import {ComponentFixture} from './component_fixture'; | ||
|
@@ -142,9 +142,23 @@ export class TestBed implements Injector { | |
return TestBed; | ||
} | ||
|
||
/** | ||
* Overrides the template of the given component, compiling the template | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add docs to |
||
* in the context of the TestingModule. | ||
* | ||
* Note: This works for JIT and AOTed components as well. | ||
*/ | ||
static overrideTemplateUsingTestingModule(component: Type<any>, template: string): | ||
typeof TestBed { | ||
getTestBed().overrideTemplateUsingTestingModule(component, template); | ||
return TestBed; | ||
} | ||
|
||
|
||
/** | ||
* Overwrites all providers for the given token with the given provider definition. | ||
* | ||
* Note: This works for JIT and AOTed components as well. | ||
*/ | ||
static overrideProvider(token: any, provider: { | ||
useFactory: Function, | ||
|
@@ -208,6 +222,7 @@ export class TestBed implements Injector { | |
|
||
private _testEnvAotSummaries: () => any[] = () => []; | ||
private _aotSummaries: Array<() => any[]> = []; | ||
private _templateOverrides: Array<{component: Type<any>, templateOf: Type<any>}> = []; | ||
|
||
platform: PlatformRef = null !; | ||
|
||
|
@@ -251,8 +266,9 @@ export class TestBed implements Injector { | |
} | ||
|
||
resetTestingModule() { | ||
clearProviderOverrides(); | ||
clearOverrides(); | ||
this._aotSummaries = []; | ||
this._templateOverrides = []; | ||
this._compiler = null !; | ||
this._moduleOverrides = []; | ||
this._componentOverrides = []; | ||
|
@@ -333,6 +349,11 @@ export class TestBed implements Injector { | |
} | ||
} | ||
} | ||
for (const {component, templateOf} of this._templateOverrides) { | ||
const compFactory = this._compiler.getComponentFactory(templateOf); | ||
overrideComponentView(component, compFactory); | ||
} | ||
|
||
const ngZone = new NgZone({enableLongStackTrace: true}); | ||
const ngZoneInjector = | ||
Injector.create([{provide: NgZone, useValue: ngZone}], this.platform.injector); | ||
|
@@ -345,7 +366,8 @@ export class TestBed implements Injector { | |
|
||
private _createCompilerAndModule(): Type<any> { | ||
const providers = this._providers.concat([{provide: TestBed, useValue: this}]); | ||
const declarations = this._declarations; | ||
const declarations = | ||
[...this._declarations, ...this._templateOverrides.map(entry => entry.templateOf)]; | ||
const imports = [this.ngModule, this._imports]; | ||
const schemas = this._schemas; | ||
|
||
|
@@ -478,6 +500,16 @@ export class TestBed implements Injector { | |
overrideProvider({token, flags, deps, value, deprecatedBehavior: deprecated}); | ||
} | ||
|
||
overrideTemplateUsingTestingModule(component: Type<any>, template: string) { | ||
this._assertNotInstantiated('overrideTemplateUsingTestingModule', 'override template'); | ||
|
||
@Component({selector: 'empty', template: template}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit |
||
class OverrideComponent { | ||
} | ||
|
||
this._templateOverrides.push({component, templateOf: OverrideComponent}); | ||
} | ||
|
||
createComponent<T>(component: Type<T>): ComponentFixture<T> { | ||
this._initIfNeeded(); | ||
const componentFactory = this._compiler.getComponentFactory(component); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -712,6 +712,60 @@ export function main() { | |
}); | ||
}); | ||
|
||
describe('overrideTemplateUsingTestingModule', () => { | ||
it('should compile the template in the context of the testing module', () => { | ||
@Component({selector: 'comp', template: 'a'}) | ||
class MyComponent { | ||
prop = 'some prop'; | ||
} | ||
|
||
let testDir: TestDir|undefined; | ||
|
||
@Directive({selector: '[test]'}) | ||
class TestDir { | ||
constructor() { testDir = this; } | ||
|
||
@Input('test') | ||
test: string; | ||
} | ||
|
||
TestBed.overrideTemplateUsingTestingModule( | ||
MyComponent, '<div [test]="prop">Hello world!</div>'); | ||
|
||
const fixture = TestBed.configureTestingModule({declarations: [MyComponent, TestDir]}) | ||
.createComponent(MyComponent); | ||
fixture.detectChanges(); | ||
expect(fixture.nativeElement).toHaveText('Hello world!'); | ||
expect(testDir).toBeAnInstanceOf(TestDir); | ||
expect(testDir !.test).toBe('some prop'); | ||
}); | ||
|
||
it('should throw if the TestBed is already created', () => { | ||
@Component({selector: 'comp', template: 'a'}) | ||
class MyComponent { | ||
} | ||
|
||
TestBed.get(Injector); | ||
|
||
expect(() => TestBed.overrideTemplateUsingTestingModule(MyComponent, 'b')) | ||
.toThrowError( | ||
/Cannot override template when the test module has already been instantiated/); | ||
}); | ||
|
||
it('should reset overrides when the testing modules is resetted', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. testing module-s- |
||
@Component({selector: 'comp', template: 'a'}) | ||
class MyComponent { | ||
} | ||
|
||
TestBed.overrideTemplateUsingTestingModule(MyComponent, 'b'); | ||
TestBed.resetTestingModule(); | ||
|
||
const fixture = TestBed.configureTestingModule({declarations: [MyComponent]}) | ||
.createComponent(MyComponent); | ||
expect(fixture.nativeElement).toHaveText('a'); | ||
}); | ||
}); | ||
|
||
describe('setting up the compiler', () => { | ||
|
||
describe('providers', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
override+n+CV ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have
OverrideProvider
, keeping for consistency