feat(compiler): introduce `TestBed.overrideTemplateUsingTestingModule`
This allows to overwrite templates for JIT and AOT components alike. In contrast to `TestBed.overrideTemplate`, the template is compiled in the context of the testing module, allowing to use other testing directives. Closes #19815
This commit is contained in:
parent
05d96dc507
commit
a460066972
|
@ -20,5 +20,5 @@ export {DirectRenderer as ɵDirectRenderer, RenderDebugInfo as ɵRenderDebugInfo
|
||||||
export {global as ɵglobal, looseIdentical as ɵlooseIdentical, stringify as ɵstringify} from './util';
|
export {global as ɵglobal, looseIdentical as ɵlooseIdentical, stringify as ɵstringify} from './util';
|
||||||
export {makeDecorator as ɵmakeDecorator} from './util/decorators';
|
export {makeDecorator as ɵmakeDecorator} from './util/decorators';
|
||||||
export {isObservable as ɵisObservable, isPromise as ɵisPromise} from './util/lang';
|
export {isObservable as ɵisObservable, isPromise as ɵisPromise} from './util/lang';
|
||||||
export {clearProviderOverrides as ɵclearProviderOverrides, overrideProvider as ɵoverrideProvider} from './view/index';
|
export {clearOverrides as ɵclearOverrides, overrideComponentView as ɵoverrideComponentView, overrideProvider as ɵoverrideProvider} from './view/index';
|
||||||
export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider';
|
export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider';
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector} from '../di/injector';
|
import {Injector} from '../di/injector';
|
||||||
|
import {ComponentFactory} from '../linker/component_factory';
|
||||||
import {NgModuleFactory, NgModuleRef} from '../linker/ng_module_factory';
|
import {NgModuleFactory, NgModuleRef} from '../linker/ng_module_factory';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {initServicesIfNeeded} from './services';
|
import {initServicesIfNeeded} from './services';
|
||||||
import {NgModuleDefinitionFactory, ProviderOverride, Services} from './types';
|
import {NgModuleDefinitionFactory, ProviderOverride, Services, ViewDefinition} from './types';
|
||||||
import {resolveDefinition} from './util';
|
import {resolveDefinition} from './util';
|
||||||
|
|
||||||
export function overrideProvider(override: ProviderOverride) {
|
export function overrideProvider(override: ProviderOverride) {
|
||||||
|
@ -19,9 +20,14 @@ export function overrideProvider(override: ProviderOverride) {
|
||||||
return Services.overrideProvider(override);
|
return Services.overrideProvider(override);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearProviderOverrides() {
|
export function overrideComponentView(comp: Type<any>, componentFactory: ComponentFactory<any>) {
|
||||||
initServicesIfNeeded();
|
initServicesIfNeeded();
|
||||||
return Services.clearProviderOverrides();
|
return Services.overrideComponentView(comp, componentFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearOverrides() {
|
||||||
|
initServicesIfNeeded();
|
||||||
|
return Services.clearOverrides();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attention: this function is called as top level function.
|
// Attention: this function is called as top level function.
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {anchorDef, elementDef} from './element';
|
export {anchorDef, elementDef} from './element';
|
||||||
export {clearProviderOverrides, createNgModuleFactory, overrideProvider} from './entrypoint';
|
export {clearOverrides, createNgModuleFactory, overrideComponentView, overrideProvider} from './entrypoint';
|
||||||
export {ngContentDef} from './ng_content';
|
export {ngContentDef} from './ng_content';
|
||||||
export {moduleDef, moduleProvideDef} from './ng_module';
|
export {moduleDef, moduleProvideDef} from './ng_module';
|
||||||
export {directiveDef, pipeDef, providerDef} from './provider';
|
export {directiveDef, pipeDef, providerDef} from './provider';
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {isDevMode} from '../application_ref';
|
||||||
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
|
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
|
||||||
import {Injector} from '../di';
|
import {Injector} from '../di';
|
||||||
import {ErrorHandler} from '../error_handler';
|
import {ErrorHandler} from '../error_handler';
|
||||||
|
import {ComponentFactory} from '../linker/component_factory';
|
||||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||||
import {Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2} from '../render/api';
|
import {Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2} from '../render/api';
|
||||||
import {Sanitizer} from '../security';
|
import {Sanitizer} from '../security';
|
||||||
|
@ -18,9 +19,9 @@ import {Type} from '../type';
|
||||||
import {isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './errors';
|
import {isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './errors';
|
||||||
import {resolveDep} from './provider';
|
import {resolveDep} from './provider';
|
||||||
import {dirtyParentQueries, getQueryValue} from './query';
|
import {dirtyParentQueries, getQueryValue} from './query';
|
||||||
import {createInjector, createNgModuleRef} from './refs';
|
import {createInjector, createNgModuleRef, getComponentViewDefinitionFactory} from './refs';
|
||||||
import {ArgumentType, BindingFlags, CheckType, DebugContext, DepDef, ElementData, NgModuleDefinition, NgModuleProviderDef, NodeDef, NodeFlags, NodeLogger, ProviderOverride, RootData, Services, ViewData, ViewDefinition, ViewState, asElementData, asPureExpressionData} from './types';
|
import {ArgumentType, BindingFlags, CheckType, DebugContext, DepDef, ElementData, NgModuleDefinition, NgModuleProviderDef, NodeDef, NodeFlags, NodeLogger, ProviderOverride, RootData, Services, ViewData, ViewDefinition, ViewState, asElementData, asPureExpressionData} from './types';
|
||||||
import {NOOP, isComponentView, renderNode, splitDepsDsl, viewParentEl} from './util';
|
import {NOOP, isComponentView, renderNode, resolveDefinition, splitDepsDsl, viewParentEl} from './util';
|
||||||
import {checkAndUpdateNode, checkAndUpdateView, checkNoChangesNode, checkNoChangesView, createComponentView, createEmbeddedView, createRootView, destroyView} from './view';
|
import {checkAndUpdateNode, checkAndUpdateView, checkNoChangesNode, checkNoChangesView, createComponentView, createEmbeddedView, createRootView, destroyView} from './view';
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +39,8 @@ export function initServicesIfNeeded() {
|
||||||
Services.createComponentView = services.createComponentView;
|
Services.createComponentView = services.createComponentView;
|
||||||
Services.createNgModuleRef = services.createNgModuleRef;
|
Services.createNgModuleRef = services.createNgModuleRef;
|
||||||
Services.overrideProvider = services.overrideProvider;
|
Services.overrideProvider = services.overrideProvider;
|
||||||
Services.clearProviderOverrides = services.clearProviderOverrides;
|
Services.overrideComponentView = services.overrideComponentView;
|
||||||
|
Services.clearOverrides = services.clearOverrides;
|
||||||
Services.checkAndUpdateView = services.checkAndUpdateView;
|
Services.checkAndUpdateView = services.checkAndUpdateView;
|
||||||
Services.checkNoChangesView = services.checkNoChangesView;
|
Services.checkNoChangesView = services.checkNoChangesView;
|
||||||
Services.destroyView = services.destroyView;
|
Services.destroyView = services.destroyView;
|
||||||
|
@ -58,7 +60,8 @@ function createProdServices() {
|
||||||
createComponentView: createComponentView,
|
createComponentView: createComponentView,
|
||||||
createNgModuleRef: createNgModuleRef,
|
createNgModuleRef: createNgModuleRef,
|
||||||
overrideProvider: NOOP,
|
overrideProvider: NOOP,
|
||||||
clearProviderOverrides: NOOP,
|
overrideComponentView: NOOP,
|
||||||
|
clearOverrides: NOOP,
|
||||||
checkAndUpdateView: checkAndUpdateView,
|
checkAndUpdateView: checkAndUpdateView,
|
||||||
checkNoChangesView: checkNoChangesView,
|
checkNoChangesView: checkNoChangesView,
|
||||||
destroyView: destroyView,
|
destroyView: destroyView,
|
||||||
|
@ -84,7 +87,8 @@ function createDebugServices() {
|
||||||
createComponentView: debugCreateComponentView,
|
createComponentView: debugCreateComponentView,
|
||||||
createNgModuleRef: debugCreateNgModuleRef,
|
createNgModuleRef: debugCreateNgModuleRef,
|
||||||
overrideProvider: debugOverrideProvider,
|
overrideProvider: debugOverrideProvider,
|
||||||
clearProviderOverrides: debugClearProviderOverrides,
|
overrideComponentView: debugOverrideComponentView,
|
||||||
|
clearOverrides: debugClearOverrides,
|
||||||
checkAndUpdateView: debugCheckAndUpdateView,
|
checkAndUpdateView: debugCheckAndUpdateView,
|
||||||
checkNoChangesView: debugCheckNoChangesView,
|
checkNoChangesView: debugCheckNoChangesView,
|
||||||
destroyView: debugDestroyView,
|
destroyView: debugDestroyView,
|
||||||
|
@ -139,10 +143,15 @@ function debugCreateEmbeddedView(
|
||||||
|
|
||||||
function debugCreateComponentView(
|
function debugCreateComponentView(
|
||||||
parentView: ViewData, nodeDef: NodeDef, viewDef: ViewDefinition, hostElement: any): ViewData {
|
parentView: ViewData, nodeDef: NodeDef, viewDef: ViewDefinition, hostElement: any): ViewData {
|
||||||
const defWithOverride = applyProviderOverridesToView(viewDef);
|
const overrideComponentView =
|
||||||
|
viewDefOverrides.get(nodeDef.element !.componentProvider !.provider !.token);
|
||||||
|
if (overrideComponentView) {
|
||||||
|
viewDef = overrideComponentView;
|
||||||
|
} else {
|
||||||
|
viewDef = applyProviderOverridesToView(viewDef);
|
||||||
|
}
|
||||||
return callWithDebugContext(
|
return callWithDebugContext(
|
||||||
DebugAction.create, createComponentView, null,
|
DebugAction.create, createComponentView, null, [parentView, nodeDef, viewDef, hostElement]);
|
||||||
[parentView, nodeDef, defWithOverride, hostElement]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function debugCreateNgModuleRef(
|
function debugCreateNgModuleRef(
|
||||||
|
@ -153,13 +162,21 @@ function debugCreateNgModuleRef(
|
||||||
}
|
}
|
||||||
|
|
||||||
const providerOverrides = new Map<any, ProviderOverride>();
|
const providerOverrides = new Map<any, ProviderOverride>();
|
||||||
|
const viewDefOverrides = new Map<any, ViewDefinition>();
|
||||||
|
|
||||||
function debugOverrideProvider(override: ProviderOverride) {
|
function debugOverrideProvider(override: ProviderOverride) {
|
||||||
providerOverrides.set(override.token, override);
|
providerOverrides.set(override.token, override);
|
||||||
}
|
}
|
||||||
|
|
||||||
function debugClearProviderOverrides() {
|
function debugOverrideComponentView(comp: any, compFactory: ComponentFactory<any>) {
|
||||||
|
const hostViewDef = resolveDefinition(getComponentViewDefinitionFactory(compFactory));
|
||||||
|
const compViewDef = resolveDefinition(hostViewDef.nodes[0].element !.componentView !);
|
||||||
|
viewDefOverrides.set(comp, compViewDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugClearOverrides() {
|
||||||
providerOverrides.clear();
|
providerOverrides.clear();
|
||||||
|
viewDefOverrides.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notes about the algorithm:
|
// Notes about the algorithm:
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
import {Injector} from '../di';
|
import {Injector} from '../di';
|
||||||
import {ErrorHandler} from '../error_handler';
|
import {ErrorHandler} from '../error_handler';
|
||||||
|
import {ComponentFactory} from '../linker/component_factory';
|
||||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||||
import {QueryList} from '../linker/query_list';
|
import {QueryList} from '../linker/query_list';
|
||||||
import {TemplateRef} from '../linker/template_ref';
|
import {TemplateRef} from '../linker/template_ref';
|
||||||
|
@ -16,6 +17,7 @@ import {Renderer2, RendererFactory2, RendererType2} from '../render/api';
|
||||||
import {Sanitizer, SecurityContext} from '../security';
|
import {Sanitizer, SecurityContext} from '../security';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// Defs
|
// Defs
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
@ -522,7 +524,8 @@ export interface Services {
|
||||||
moduleType: Type<any>, parent: Injector, bootstrapComponents: Type<any>[],
|
moduleType: Type<any>, parent: Injector, bootstrapComponents: Type<any>[],
|
||||||
def: NgModuleDefinition): NgModuleRef<any>;
|
def: NgModuleDefinition): NgModuleRef<any>;
|
||||||
overrideProvider(override: ProviderOverride): void;
|
overrideProvider(override: ProviderOverride): void;
|
||||||
clearProviderOverrides(): void;
|
overrideComponentView(compType: Type<any>, compFactory: ComponentFactory<any>): void;
|
||||||
|
clearOverrides(): void;
|
||||||
checkAndUpdateView(view: ViewData): void;
|
checkAndUpdateView(view: ViewData): void;
|
||||||
checkNoChangesView(view: ViewData): void;
|
checkNoChangesView(view: ViewData): void;
|
||||||
destroyView(view: ViewData): void;
|
destroyView(view: ViewData): void;
|
||||||
|
@ -547,7 +550,8 @@ export const Services: Services = {
|
||||||
createComponentView: undefined !,
|
createComponentView: undefined !,
|
||||||
createNgModuleRef: undefined !,
|
createNgModuleRef: undefined !,
|
||||||
overrideProvider: undefined !,
|
overrideProvider: undefined !,
|
||||||
clearProviderOverrides: undefined !,
|
overrideComponentView: undefined !,
|
||||||
|
clearOverrides: undefined !,
|
||||||
checkAndUpdateView: undefined !,
|
checkAndUpdateView: undefined !,
|
||||||
checkNoChangesView: undefined !,
|
checkNoChangesView: undefined !,
|
||||||
destroyView: undefined !,
|
destroyView: undefined !,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {CompileMetadataResolver} from '@angular/compiler/src/metadata_resolver';
|
||||||
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
|
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
|
||||||
import {Component, Directive, Injectable, NgModule, Pipe, Type} from '@angular/core';
|
import {Component, Directive, Injectable, NgModule, Pipe, Type} from '@angular/core';
|
||||||
import {TestBed, async, getTestBed} from '@angular/core/testing';
|
import {TestBed, async, getTestBed} from '@angular/core/testing';
|
||||||
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('Jit Summaries', () => {
|
describe('Jit Summaries', () => {
|
||||||
|
@ -222,5 +223,29 @@ export function main() {
|
||||||
.createComponent(TestComp);
|
.createComponent(TestComp);
|
||||||
expectInstanceCreated(SomeDirective);
|
expectInstanceCreated(SomeDirective);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow to override a provider', () => {
|
||||||
|
resetTestEnvironmentWithSummaries(summaries);
|
||||||
|
|
||||||
|
const overwrittenValue = {};
|
||||||
|
|
||||||
|
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []});
|
||||||
|
|
||||||
|
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');
|
||||||
|
|
||||||
|
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
|
||||||
|
.createComponent(SomePublicComponent);
|
||||||
|
expectInstanceCreated(SomePublicComponent);
|
||||||
|
|
||||||
|
expect(fixture.nativeElement).toHaveText('overwritten');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* 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, StaticProvider, 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 {AsyncTestCompleter} from './async_test_completer';
|
||||||
import {ComponentFixture} from './component_fixture';
|
import {ComponentFixture} from './component_fixture';
|
||||||
|
@ -142,9 +142,23 @@ export class TestBed implements Injector {
|
||||||
return TestBed;
|
return TestBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the template of the given component, compiling the template
|
||||||
|
* 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.
|
* 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: {
|
static overrideProvider(token: any, provider: {
|
||||||
useFactory: Function,
|
useFactory: Function,
|
||||||
|
@ -208,6 +222,7 @@ export class TestBed implements Injector {
|
||||||
|
|
||||||
private _testEnvAotSummaries: () => any[] = () => [];
|
private _testEnvAotSummaries: () => any[] = () => [];
|
||||||
private _aotSummaries: Array<() => any[]> = [];
|
private _aotSummaries: Array<() => any[]> = [];
|
||||||
|
private _templateOverrides: Array<{component: Type<any>, templateOf: Type<any>}> = [];
|
||||||
|
|
||||||
platform: PlatformRef = null !;
|
platform: PlatformRef = null !;
|
||||||
|
|
||||||
|
@ -251,8 +266,9 @@ export class TestBed implements Injector {
|
||||||
}
|
}
|
||||||
|
|
||||||
resetTestingModule() {
|
resetTestingModule() {
|
||||||
clearProviderOverrides();
|
clearOverrides();
|
||||||
this._aotSummaries = [];
|
this._aotSummaries = [];
|
||||||
|
this._templateOverrides = [];
|
||||||
this._compiler = null !;
|
this._compiler = null !;
|
||||||
this._moduleOverrides = [];
|
this._moduleOverrides = [];
|
||||||
this._componentOverrides = [];
|
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 ngZone = new NgZone({enableLongStackTrace: true});
|
||||||
const ngZoneInjector =
|
const ngZoneInjector =
|
||||||
Injector.create([{provide: NgZone, useValue: ngZone}], this.platform.injector);
|
Injector.create([{provide: NgZone, useValue: ngZone}], this.platform.injector);
|
||||||
|
@ -345,7 +366,8 @@ export class TestBed implements Injector {
|
||||||
|
|
||||||
private _createCompilerAndModule(): Type<any> {
|
private _createCompilerAndModule(): Type<any> {
|
||||||
const providers = this._providers.concat([{provide: TestBed, useValue: this}]);
|
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 imports = [this.ngModule, this._imports];
|
||||||
const schemas = this._schemas;
|
const schemas = this._schemas;
|
||||||
|
|
||||||
|
@ -478,6 +500,16 @@ export class TestBed implements Injector {
|
||||||
overrideProvider({token, flags, deps, value, deprecatedBehavior: deprecated});
|
overrideProvider({token, flags, deps, value, deprecatedBehavior: deprecated});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overrideTemplateUsingTestingModule(component: Type<any>, template: string) {
|
||||||
|
this._assertNotInstantiated('overrideTemplateUsingTestingModule', 'override template');
|
||||||
|
|
||||||
|
@Component({selector: 'empty', template: template})
|
||||||
|
class OverrideComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
this._templateOverrides.push({component, templateOf: OverrideComponent});
|
||||||
|
}
|
||||||
|
|
||||||
createComponent<T>(component: Type<T>): ComponentFixture<T> {
|
createComponent<T>(component: Type<T>): ComponentFixture<T> {
|
||||||
this._initIfNeeded();
|
this._initIfNeeded();
|
||||||
const componentFactory = this._compiler.getComponentFactory(component);
|
const componentFactory = this._compiler.getComponentFactory(component);
|
||||||
|
|
|
@ -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', () => {
|
||||||
|
@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('setting up the compiler', () => {
|
||||||
|
|
||||||
describe('providers', () => {
|
describe('providers', () => {
|
||||||
|
|
|
@ -71,13 +71,13 @@ export declare class TestBed implements Injector {
|
||||||
}): void;
|
}): void;
|
||||||
configureTestingModule(moduleDef: TestModuleMetadata): void;
|
configureTestingModule(moduleDef: TestModuleMetadata): void;
|
||||||
createComponent<T>(component: Type<T>): ComponentFixture<T>;
|
createComponent<T>(component: Type<T>): ComponentFixture<T>;
|
||||||
|
deprecatedOverrideProvider(token: any, provider: {
|
||||||
|
useValue: any;
|
||||||
|
}): void;
|
||||||
/** @deprecated */ deprecatedOverrideProvider(token: any, provider: {
|
/** @deprecated */ deprecatedOverrideProvider(token: any, provider: {
|
||||||
useFactory: Function;
|
useFactory: Function;
|
||||||
deps: any[];
|
deps: any[];
|
||||||
}): void;
|
}): void;
|
||||||
deprecatedOverrideProvider(token: any, provider: {
|
|
||||||
useValue: any;
|
|
||||||
}): void;
|
|
||||||
execute(tokens: any[], fn: Function, context?: any): any;
|
execute(tokens: any[], fn: Function, context?: any): any;
|
||||||
get(token: any, notFoundValue?: any): any;
|
get(token: any, notFoundValue?: any): any;
|
||||||
/** @experimental */ initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): void;
|
/** @experimental */ initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): void;
|
||||||
|
@ -92,6 +92,7 @@ export declare class TestBed implements Injector {
|
||||||
overrideProvider(token: any, provider: {
|
overrideProvider(token: any, provider: {
|
||||||
useValue: any;
|
useValue: any;
|
||||||
}): void;
|
}): void;
|
||||||
|
overrideTemplateUsingTestingModule(component: Type<any>, template: string): void;
|
||||||
/** @experimental */ resetTestEnvironment(): void;
|
/** @experimental */ resetTestEnvironment(): void;
|
||||||
resetTestingModule(): void;
|
resetTestingModule(): void;
|
||||||
static compileComponents(): Promise<any>;
|
static compileComponents(): Promise<any>;
|
||||||
|
@ -101,13 +102,13 @@ export declare class TestBed implements Injector {
|
||||||
}): typeof TestBed;
|
}): typeof TestBed;
|
||||||
static configureTestingModule(moduleDef: TestModuleMetadata): typeof TestBed;
|
static configureTestingModule(moduleDef: TestModuleMetadata): typeof TestBed;
|
||||||
static createComponent<T>(component: Type<T>): ComponentFixture<T>;
|
static createComponent<T>(component: Type<T>): ComponentFixture<T>;
|
||||||
|
static deprecatedOverrideProvider(token: any, provider: {
|
||||||
|
useValue: any;
|
||||||
|
}): void;
|
||||||
/** @deprecated */ static deprecatedOverrideProvider(token: any, provider: {
|
/** @deprecated */ static deprecatedOverrideProvider(token: any, provider: {
|
||||||
useFactory: Function;
|
useFactory: Function;
|
||||||
deps: any[];
|
deps: any[];
|
||||||
}): void;
|
}): void;
|
||||||
static deprecatedOverrideProvider(token: any, provider: {
|
|
||||||
useValue: any;
|
|
||||||
}): void;
|
|
||||||
static get(token: any, notFoundValue?: any): any;
|
static get(token: any, notFoundValue?: any): any;
|
||||||
/** @experimental */ static initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed;
|
/** @experimental */ static initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed;
|
||||||
static overrideComponent(component: Type<any>, override: MetadataOverride<Component>): typeof TestBed;
|
static overrideComponent(component: Type<any>, override: MetadataOverride<Component>): typeof TestBed;
|
||||||
|
@ -122,6 +123,7 @@ export declare class TestBed implements Injector {
|
||||||
useValue: any;
|
useValue: any;
|
||||||
}): void;
|
}): void;
|
||||||
static overrideTemplate(component: Type<any>, template: string): typeof TestBed;
|
static overrideTemplate(component: Type<any>, template: string): typeof TestBed;
|
||||||
|
static overrideTemplateUsingTestingModule(component: Type<any>, template: string): typeof TestBed;
|
||||||
/** @experimental */ static resetTestEnvironment(): void;
|
/** @experimental */ static resetTestEnvironment(): void;
|
||||||
static resetTestingModule(): typeof TestBed;
|
static resetTestingModule(): typeof TestBed;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +139,7 @@ export declare type TestModuleMetadata = {
|
||||||
declarations?: any[];
|
declarations?: any[];
|
||||||
imports?: any[];
|
imports?: any[];
|
||||||
schemas?: Array<SchemaMetadata | any[]>;
|
schemas?: Array<SchemaMetadata | any[]>;
|
||||||
|
aotSummaries?: () => any[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @experimental */
|
/** @experimental */
|
||||||
|
|
Loading…
Reference in New Issue