@angular/core
Version:
Angular - the core framework
723 lines • 106 kB
JavaScript
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as tslib_1 from "tslib";
import { ResourceLoader } from '@angular/compiler';
import { ApplicationInitStatus, COMPILER_OPTIONS, Compiler, LOCALE_ID, ModuleWithComponentFactories, NgZone, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID, ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF, ɵNG_DIRECTIVE_DEF as NG_DIRECTIVE_DEF, ɵNG_INJECTOR_DEF as NG_INJECTOR_DEF, ɵNG_MODULE_DEF as NG_MODULE_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵNgModuleFactory as R3NgModuleFactory, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵsetLocaleId as setLocaleId, ɵtransitiveScopesFor as transitiveScopesFor } from '@angular/core';
import { clearResolutionOfComponentResourcesQueue, isComponentDefPendingResolution, resolveComponentResources, restoreComponentResolutionQueue } from '../../src/metadata/resource_loading';
import { ComponentResolver, DirectiveResolver, NgModuleResolver, PipeResolver } from './resolvers';
var TestingModuleOverride;
(function (TestingModuleOverride) {
TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
})(TestingModuleOverride || (TestingModuleOverride = {}));
function isTestingModuleOverride(value) {
return value === TestingModuleOverride.DECLARATION ||
value === TestingModuleOverride.OVERRIDE_TEMPLATE;
}
var R3TestBedCompiler = /** @class */ (function () {
function R3TestBedCompiler(platform, additionalModuleTypes) {
this.platform = platform;
this.additionalModuleTypes = additionalModuleTypes;
this.originalComponentResolutionQueue = null;
// Testing module configuration
this.declarations = [];
this.imports = [];
this.providers = [];
this.schemas = [];
// Queues of components/directives/pipes that should be recompiled.
this.pendingComponents = new Set();
this.pendingDirectives = new Set();
this.pendingPipes = new Set();
// Keep track of all components and directives, so we can patch Providers onto defs later.
this.seenComponents = new Set();
this.seenDirectives = new Set();
// Store resolved styles for Components that have template overrides present and `styleUrls`
// defined at the same time.
this.existingComponentStyles = new Map();
this.resolvers = initResolvers();
this.componentToModuleScope = new Map();
// Map that keeps initial version of component/directive/pipe defs in case
// we compile a Type again, thus overriding respective static fields. This is
// required to make sure we restore defs to their initial states between test runs
// TODO: we should support the case with multiple defs on a type
this.initialNgDefs = new Map();
// Array that keeps cleanup operations for initial versions of component/directive/pipe/module
// defs in case TestBed makes changes to the originals.
this.defCleanupOps = [];
this._injector = null;
this.compilerProviders = null;
this.providerOverrides = [];
this.rootProviderOverrides = [];
this.providerOverridesByToken = new Map();
this.moduleProvidersOverridden = new Set();
this.testModuleRef = null;
var DynamicTestModule = /** @class */ (function () {
function DynamicTestModule() {
}
return DynamicTestModule;
}());
this.testModuleType = DynamicTestModule;
}
R3TestBedCompiler.prototype.setCompilerProviders = function (providers) {
this.compilerProviders = providers;
this._injector = null;
};
R3TestBedCompiler.prototype.configureTestingModule = function (moduleDef) {
var _a, _b, _c, _d;
// Enqueue any compilation tasks for the directly declared component.
if (moduleDef.declarations !== undefined) {
this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
(_a = this.declarations).push.apply(_a, tslib_1.__spread(moduleDef.declarations));
}
// Enqueue any compilation tasks for imported modules.
if (moduleDef.imports !== undefined) {
this.queueTypesFromModulesArray(moduleDef.imports);
(_b = this.imports).push.apply(_b, tslib_1.__spread(moduleDef.imports));
}
if (moduleDef.providers !== undefined) {
(_c = this.providers).push.apply(_c, tslib_1.__spread(moduleDef.providers));
}
if (moduleDef.schemas !== undefined) {
(_d = this.schemas).push.apply(_d, tslib_1.__spread(moduleDef.schemas));
}
};
R3TestBedCompiler.prototype.overrideModule = function (ngModule, override) {
// Compile the module right away.
this.resolvers.module.addOverride(ngModule, override);
var metadata = this.resolvers.module.resolve(ngModule);
if (metadata === null) {
throw new Error(ngModule.name + " is not an @NgModule or is missing metadata");
}
this.recompileNgModule(ngModule);
// At this point, the module has a valid .ngModuleDef, but the override may have introduced
// new declarations or imported modules. Ingest any possible new types and add them to the
// current queue.
this.queueTypesFromModulesArray([ngModule]);
};
R3TestBedCompiler.prototype.overrideComponent = function (component, override) {
this.resolvers.component.addOverride(component, override);
this.pendingComponents.add(component);
};
R3TestBedCompiler.prototype.overrideDirective = function (directive, override) {
this.resolvers.directive.addOverride(directive, override);
this.pendingDirectives.add(directive);
};
R3TestBedCompiler.prototype.overridePipe = function (pipe, override) {
this.resolvers.pipe.addOverride(pipe, override);
this.pendingPipes.add(pipe);
};
R3TestBedCompiler.prototype.overrideProvider = function (token, provider) {
var providerDef = provider.useFactory ?
{
provide: token,
useFactory: provider.useFactory,
deps: provider.deps || [],
multi: provider.multi,
} :
{ provide: token, useValue: provider.useValue, multi: provider.multi };
var injectableDef;
var isRoot = (typeof token !== 'string' && (injectableDef = getInjectableDef(token)) &&
injectableDef.providedIn === 'root');
var overridesBucket = isRoot ? this.rootProviderOverrides : this.providerOverrides;
overridesBucket.push(providerDef);
// Keep overrides grouped by token as well for fast lookups using token
this.providerOverridesByToken.set(token, providerDef);
};
R3TestBedCompiler.prototype.overrideTemplateUsingTestingModule = function (type, template) {
var _this = this;
var def = type[NG_COMPONENT_DEF];
var hasStyleUrls = function () {
var metadata = _this.resolvers.component.resolve(type);
return !!metadata.styleUrls && metadata.styleUrls.length > 0;
};
var overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
// In Ivy, compiling a component does not require knowing the module providing the
// component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
// overrideComponent. Important: overriding template requires full Component re-compilation,
// which may fail in case styleUrls are also present (thus Component is considered as required
// resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
// preserve current styles available on Component def and restore styles back once compilation
// is complete.
var override = overrideStyleUrls ? { template: template, styles: [], styleUrls: [] } : { template: template };
this.overrideComponent(type, { set: override });
if (overrideStyleUrls && def.styles && def.styles.length > 0) {
this.existingComponentStyles.set(type, def.styles);
}
// Set the component's scope to be the testing module.
this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
};
R3TestBedCompiler.prototype.compileComponents = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var needsAsyncResources, resourceLoader_1, resolver;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.clearComponentResolutionQueue();
needsAsyncResources = this.compileTypesSync();
if (!needsAsyncResources) return [3 /*break*/, 2];
resolver = function (url) {
if (!resourceLoader_1) {
resourceLoader_1 = _this.injector.get(ResourceLoader);
}
return Promise.resolve(resourceLoader_1.get(url));
};
return [4 /*yield*/, resolveComponentResources(resolver)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
R3TestBedCompiler.prototype.finalize = function () {
// One last compile
this.compileTypesSync();
// Create the testing module itself.
this.compileTestModule();
this.applyTransitiveScopes();
this.applyProviderOverrides();
// Patch previously stored `styles` Component values (taken from ngComponentDef), in case these
// Components have `styleUrls` fields defined and template override was requested.
this.patchComponentsWithExistingStyles();
// Clear the componentToModuleScope map, so that future compilations don't reset the scope of
// every component.
this.componentToModuleScope.clear();
var parentInjector = this.platform.injector;
this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector);
// Set the locale ID, it can be overridden for the tests
var localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
setLocaleId(localeId);
// ApplicationInitStatus.runInitializers() is marked @internal to core.
// Cast it to any before accessing it.
this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
return this.testModuleRef;
};
/**
* @internal
*/
R3TestBedCompiler.prototype._compileNgModuleSync = function (moduleType) {
this.queueTypesFromModulesArray([moduleType]);
this.compileTypesSync();
this.applyProviderOverrides();
this.applyProviderOverridesToModule(moduleType);
this.applyTransitiveScopes();
};
/**
* @internal
*/
R3TestBedCompiler.prototype._compileNgModuleAsync = function (moduleType) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.queueTypesFromModulesArray([moduleType]);
return [4 /*yield*/, this.compileComponents()];
case 1:
_a.sent();
this.applyProviderOverrides();
this.applyProviderOverridesToModule(moduleType);
this.applyTransitiveScopes();
return [2 /*return*/];
}
});
});
};
/**
* @internal
*/
R3TestBedCompiler.prototype._getModuleResolver = function () { return this.resolvers.module; };
/**
* @internal
*/
R3TestBedCompiler.prototype._getComponentFactories = function (moduleType) {
var _this = this;
return maybeUnwrapFn(moduleType.ngModuleDef.declarations).reduce(function (factories, declaration) {
var componentDef = declaration.ngComponentDef;
componentDef && factories.push(new ComponentFactory(componentDef, _this.testModuleRef));
return factories;
}, []);
};
R3TestBedCompiler.prototype.compileTypesSync = function () {
var _this = this;
// Compile all queued components, directives, pipes.
var needsAsyncResources = false;
this.pendingComponents.forEach(function (declaration) {
needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
var metadata = _this.resolvers.component.resolve(declaration);
_this.maybeStoreNgDef(NG_COMPONENT_DEF, declaration);
compileComponent(declaration, metadata);
});
this.pendingComponents.clear();
this.pendingDirectives.forEach(function (declaration) {
var metadata = _this.resolvers.directive.resolve(declaration);
_this.maybeStoreNgDef(NG_DIRECTIVE_DEF, declaration);
compileDirective(declaration, metadata);
});
this.pendingDirectives.clear();
this.pendingPipes.forEach(function (declaration) {
var metadata = _this.resolvers.pipe.resolve(declaration);
_this.maybeStoreNgDef(NG_PIPE_DEF, declaration);
compilePipe(declaration, metadata);
});
this.pendingPipes.clear();
return needsAsyncResources;
};
R3TestBedCompiler.prototype.applyTransitiveScopes = function () {
var _this = this;
var moduleToScope = new Map();
var getScopeOfModule = function (moduleType) {
if (!moduleToScope.has(moduleType)) {
var realType = isTestingModuleOverride(moduleType) ? _this.testModuleType : moduleType;
moduleToScope.set(moduleType, transitiveScopesFor(realType));
}
return moduleToScope.get(moduleType);
};
this.componentToModuleScope.forEach(function (moduleType, componentType) {
var moduleScope = getScopeOfModule(moduleType);
_this.storeFieldOfDefOnType(componentType, NG_COMPONENT_DEF, 'directiveDefs');
_this.storeFieldOfDefOnType(componentType, NG_COMPONENT_DEF, 'pipeDefs');
patchComponentDefWithScope(componentType.ngComponentDef, moduleScope);
});
this.componentToModuleScope.clear();
};
R3TestBedCompiler.prototype.applyProviderOverrides = function () {
var _this = this;
var maybeApplyOverrides = function (field) { return function (type) {
var resolver = field === NG_COMPONENT_DEF ? _this.resolvers.component : _this.resolvers.directive;
var metadata = resolver.resolve(type);
if (_this.hasProviderOverrides(metadata.providers)) {
_this.patchDefWithProviderOverrides(type, field);
}
}; };
this.seenComponents.forEach(maybeApplyOverrides(NG_COMPONENT_DEF));
this.seenDirectives.forEach(maybeApplyOverrides(NG_DIRECTIVE_DEF));
this.seenComponents.clear();
this.seenDirectives.clear();
};
R3TestBedCompiler.prototype.applyProviderOverridesToModule = function (moduleType) {
var e_1, _a;
if (this.moduleProvidersOverridden.has(moduleType)) {
return;
}
this.moduleProvidersOverridden.add(moduleType);
var injectorDef = moduleType[NG_INJECTOR_DEF];
if (this.providerOverridesByToken.size > 0) {
if (this.hasProviderOverrides(injectorDef.providers)) {
this.maybeStoreNgDef(NG_INJECTOR_DEF, moduleType);
this.storeFieldOfDefOnType(moduleType, NG_INJECTOR_DEF, 'providers');
injectorDef.providers = this.getOverriddenProviders(injectorDef.providers);
}
// Apply provider overrides to imported modules recursively
var moduleDef = moduleType[NG_MODULE_DEF];
try {
for (var _b = tslib_1.__values(moduleDef.imports), _c = _b.next(); !_c.done; _c = _b.next()) {
var importType = _c.value;
this.applyProviderOverridesToModule(importType);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
}
};
R3TestBedCompiler.prototype.patchComponentsWithExistingStyles = function () {
this.existingComponentStyles.forEach(function (styles, type) { return type[NG_COMPONENT_DEF].styles = styles; });
this.existingComponentStyles.clear();
};
R3TestBedCompiler.prototype.queueTypeArray = function (arr, moduleType) {
var e_2, _a;
try {
for (var arr_1 = tslib_1.__values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
var value = arr_1_1.value;
if (Array.isArray(value)) {
this.queueTypeArray(value, moduleType);
}
else {
this.queueType(value, moduleType);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
}
finally { if (e_2) throw e_2.error; }
}
};
R3TestBedCompiler.prototype.recompileNgModule = function (ngModule) {
var metadata = this.resolvers.module.resolve(ngModule);
if (metadata === null) {
throw new Error("Unable to resolve metadata for NgModule: " + ngModule.name);
}
// Cache the initial ngModuleDef as it will be overwritten.
this.maybeStoreNgDef(NG_MODULE_DEF, ngModule);
this.maybeStoreNgDef(NG_INJECTOR_DEF, ngModule);
compileNgModuleDefs(ngModule, metadata);
};
R3TestBedCompiler.prototype.queueType = function (type, moduleType) {
var component = this.resolvers.component.resolve(type);
if (component) {
// Check whether a give Type has respective NG def (ngComponentDef) and compile if def is
// missing. That might happen in case a class without any Angular decorators extends another
// class where Component/Directive/Pipe decorator is defined.
if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(NG_COMPONENT_DEF)) {
this.pendingComponents.add(type);
}
this.seenComponents.add(type);
// Keep track of the module which declares this component, so later the component's scope
// can be set correctly. If the component has already been recorded here, then one of several
// cases is true:
// * the module containing the component was imported multiple times (common).
// * the component is declared in multiple modules (which is an error).
// * the component was in 'declarations' of the testing module, and also in an imported module
// in which case the module scope will be TestingModuleOverride.DECLARATION.
// * overrideTemplateUsingTestingModule was called for the component in which case the module
// scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
//
// If the component was previously in the testing module's 'declarations' (meaning the
// current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
// real module, which was imported. This pattern is understood to mean that the component
// should use its original scope, but that the testing module should also contain the
// component in its scope.
if (!this.componentToModuleScope.has(type) ||
this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION) {
this.componentToModuleScope.set(type, moduleType);
}
return;
}
var directive = this.resolvers.directive.resolve(type);
if (directive) {
if (!type.hasOwnProperty(NG_DIRECTIVE_DEF)) {
this.pendingDirectives.add(type);
}
this.seenDirectives.add(type);
return;
}
var pipe = this.resolvers.pipe.resolve(type);
if (pipe && !type.hasOwnProperty(NG_PIPE_DEF)) {
this.pendingPipes.add(type);
return;
}
};
R3TestBedCompiler.prototype.queueTypesFromModulesArray = function (arr) {
var e_3, _a;
try {
for (var arr_2 = tslib_1.__values(arr), arr_2_1 = arr_2.next(); !arr_2_1.done; arr_2_1 = arr_2.next()) {
var value = arr_2_1.value;
if (Array.isArray(value)) {
this.queueTypesFromModulesArray(value);
}
else if (hasNgModuleDef(value)) {
var def = value.ngModuleDef;
// Look through declarations, imports, and exports, and queue everything found there.
this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
this.queueTypesFromModulesArray(maybeUnwrapFn(def.imports));
this.queueTypesFromModulesArray(maybeUnwrapFn(def.exports));
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (arr_2_1 && !arr_2_1.done && (_a = arr_2.return)) _a.call(arr_2);
}
finally { if (e_3) throw e_3.error; }
}
};
R3TestBedCompiler.prototype.maybeStoreNgDef = function (prop, type) {
if (!this.initialNgDefs.has(type)) {
var currentDef = Object.getOwnPropertyDescriptor(type, prop);
this.initialNgDefs.set(type, [prop, currentDef]);
}
};
R3TestBedCompiler.prototype.storeFieldOfDefOnType = function (type, defField, field) {
var def = type[defField];
var original = def[field];
this.defCleanupOps.push({ field: field, def: def, original: original });
};
/**
* Clears current components resolution queue, but stores the state of the queue, so we can
* restore it later. Clearing the queue is required before we try to compile components (via
* `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
*/
R3TestBedCompiler.prototype.clearComponentResolutionQueue = function () {
var _this = this;
if (this.originalComponentResolutionQueue === null) {
this.originalComponentResolutionQueue = new Map();
}
clearResolutionOfComponentResourcesQueue().forEach(function (value, key) { return _this.originalComponentResolutionQueue.set(key, value); });
};
/*
* Restores component resolution queue to the previously saved state. This operation is performed
* as a part of restoring the state after completion of the current set of tests (that might
* potentially mutate the state).
*/
R3TestBedCompiler.prototype.restoreComponentResolutionQueue = function () {
if (this.originalComponentResolutionQueue !== null) {
restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
this.originalComponentResolutionQueue = null;
}
};
R3TestBedCompiler.prototype.restoreOriginalState = function () {
var e_4, _a;
try {
for (var _b = tslib_1.__values(this.defCleanupOps), _c = _b.next(); !_c.done; _c = _b.next()) {
var op = _c.value;
op.def[op.field] = op.original;
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_4) throw e_4.error; }
}
// Restore initial component/directive/pipe defs
this.initialNgDefs.forEach(function (value, type) {
var _a = tslib_1.__read(value, 2), prop = _a[0], descriptor = _a[1];
if (!descriptor) {
// Delete operations are generally undesirable since they have performance implications
// on objects they were applied to. In this particular case, situations where this code is
// invoked should be quite rare to cause any noticable impact, since it's applied only to
// some test cases (for example when class with no annotations extends some @Component)
// when we need to clear 'ngComponentDef' field on a given class to restore its original
// state (before applying overrides and running tests).
delete type[prop];
}
else {
Object.defineProperty(type, prop, descriptor);
}
});
this.initialNgDefs.clear();
this.moduleProvidersOverridden.clear();
this.restoreComponentResolutionQueue();
// Restore the locale ID to the default value, this shouldn't be necessary but we never know
setLocaleId(DEFAULT_LOCALE_ID);
};
R3TestBedCompiler.prototype.compileTestModule = function () {
var _this = this;
var RootScopeModule = /** @class */ (function () {
function RootScopeModule() {
}
return RootScopeModule;
}());
compileNgModuleDefs(RootScopeModule, {
providers: tslib_1.__spread(this.rootProviderOverrides),
});
var ngZone = new NgZone({ enableLongStackTrace: true });
var providers = tslib_1.__spread([
{ provide: NgZone, useValue: ngZone },
{ provide: Compiler, useFactory: function () { return new R3TestCompiler(_this); } }
], this.providers, this.providerOverrides);
var imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
// clang-format off
compileNgModuleDefs(this.testModuleType, {
declarations: this.declarations,
imports: imports,
schemas: this.schemas,
providers: providers,
}, /* allowDuplicateDeclarationsInRoot */ true);
// clang-format on
this.applyProviderOverridesToModule(this.testModuleType);
};
Object.defineProperty(R3TestBedCompiler.prototype, "injector", {
get: function () {
if (this._injector !== null) {
return this._injector;
}
var providers = [];
var compilerOptions = this.platform.injector.get(COMPILER_OPTIONS);
compilerOptions.forEach(function (opts) {
if (opts.providers) {
providers.push(opts.providers);
}
});
if (this.compilerProviders !== null) {
providers.push.apply(providers, tslib_1.__spread(this.compilerProviders));
}
// TODO(ocombe): make this work with an Injector directly instead of creating a module for it
var CompilerModule = /** @class */ (function () {
function CompilerModule() {
}
return CompilerModule;
}());
compileNgModuleDefs(CompilerModule, { providers: providers });
var CompilerModuleFactory = new R3NgModuleFactory(CompilerModule);
this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
return this._injector;
},
enumerable: true,
configurable: true
});
// get overrides for a specific provider (if any)
R3TestBedCompiler.prototype.getSingleProviderOverrides = function (provider) {
var token = getProviderToken(provider);
return this.providerOverridesByToken.get(token) || null;
};
R3TestBedCompiler.prototype.getProviderOverrides = function (providers) {
var _this = this;
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
return [];
// There are two flattening operations here. The inner flatten() operates on the metadata's
// providers and applies a mapping function which retrieves overrides for each incoming
// provider. The outer flatten() then flattens the produced overrides array. If this is not
// done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
// providers array and contaminate any error messages that might be generated.
return flatten(flatten(providers, function (provider) { return _this.getSingleProviderOverrides(provider) || []; }));
};
R3TestBedCompiler.prototype.getOverriddenProviders = function (providers) {
var _this = this;
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
return [];
var overrides = this.getProviderOverrides(providers);
var hasMultiProviderOverrides = overrides.some(isMultiProvider);
var overriddenProviders = tslib_1.__spread(providers, overrides);
// No additional processing is required in case we have no multi providers to override
if (!hasMultiProviderOverrides) {
return overriddenProviders;
}
var final = [];
var seenMultiProviders = new Set();
// We iterate through the list of providers in reverse order to make sure multi provider
// overrides take precedence over the values defined in provider list. We also fiter out all
// multi providers that have overrides, keeping overridden values only.
forEachRight(overriddenProviders, function (provider) {
var token = getProviderToken(provider);
if (isMultiProvider(provider) && _this.providerOverridesByToken.has(token)) {
if (!seenMultiProviders.has(token)) {
seenMultiProviders.add(token);
if (provider && provider.useValue && Array.isArray(provider.useValue)) {
forEachRight(provider.useValue, function (value) {
// Unwrap provider override array into individual providers in final set.
final.unshift({ provide: token, useValue: value, multi: true });
});
}
else {
final.unshift(provider);
}
}
}
else {
final.unshift(provider);
}
});
return final;
};
R3TestBedCompiler.prototype.hasProviderOverrides = function (providers) {
return this.getProviderOverrides(providers).length > 0;
};
R3TestBedCompiler.prototype.patchDefWithProviderOverrides = function (declaration, field) {
var _this = this;
var def = declaration[field];
if (def && def.providersResolver) {
this.maybeStoreNgDef(field, declaration);
var resolver_1 = def.providersResolver;
var processProvidersFn_1 = function (providers) { return _this.getOverriddenProviders(providers); };
this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
def.providersResolver = function (ngDef) { return resolver_1(ngDef, processProvidersFn_1); };
}
};
return R3TestBedCompiler;
}());
export { R3TestBedCompiler };
function initResolvers() {
return {
module: new NgModuleResolver(),
component: new ComponentResolver(),
directive: new DirectiveResolver(),
pipe: new PipeResolver()
};
}
function hasNgModuleDef(value) {
return value.hasOwnProperty('ngModuleDef');
}
function maybeUnwrapFn(maybeFn) {
return maybeFn instanceof Function ? maybeFn() : maybeFn;
}
function flatten(values, mapFn) {
var out = [];
values.forEach(function (value) {
if (Array.isArray(value)) {
out.push.apply(out, tslib_1.__spread(flatten(value, mapFn)));
}
else {
out.push(mapFn ? mapFn(value) : value);
}
});
return out;
}
function getProviderField(provider, field) {
return provider && typeof provider === 'object' && provider[field];
}
function getProviderToken(provider) {
return getProviderField(provider, 'provide') || provider;
}
function isMultiProvider(provider) {
return !!getProviderField(provider, 'multi');
}
function forEachRight(values, fn) {
for (var idx = values.length - 1; idx >= 0; idx--) {
fn(values[idx], idx);
}
}
var R3TestCompiler = /** @class */ (function () {
function R3TestCompiler(testBed) {
this.testBed = testBed;
}
R3TestCompiler.prototype.compileModuleSync = function (moduleType) {
this.testBed._compileNgModuleSync(moduleType);
return new R3NgModuleFactory(moduleType);
};
R3TestCompiler.prototype.compileModuleAsync = function (moduleType) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.testBed._compileNgModuleAsync(moduleType)];
case 1:
_a.sent();
return [2 /*return*/, new R3NgModuleFactory(moduleType)];
}
});
});
};
R3TestCompiler.prototype.compileModuleAndAllComponentsSync = function (moduleType) {
var ngModuleFactory = this.compileModuleSync(moduleType);
var componentFactories = this.testBed._getComponentFactories(moduleType);
return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
};
R3TestCompiler.prototype.compileModuleAndAllComponentsAsync = function (moduleType) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var ngModuleFactory, componentFactories;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.compileModuleAsync(moduleType)];
case 1:
ngModuleFactory = _a.sent();
componentFactories = this.testBed._getComponentFactories(moduleType);
return [2 /*return*/, new ModuleWithComponentFactories(ngModuleFactory, componentFactories)];
}
});
});
};
R3TestCompiler.prototype.clearCache = function () { };
R3TestCompiler.prototype.clearCacheFor = function (type) { };
R3TestCompiler.prototype.getModuleId = function (moduleType) {
var meta = this.testBed._getModuleResolver().resolve(moduleType);
return meta && meta.id || undefined;
};
return R3TestCompiler;
}());
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfdGVzdF9iZWRfY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3Rlc3Rpbmcvc3JjL3IzX3Rlc3RfYmVkX2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7QUFFSCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBa0MsU0FBUyxFQUFFLDRCQUE0QixFQUE2QixNQUFNLEVBQXFDLGtCQUFrQixJQUFJLGlCQUFpQixFQUFpQyxpQkFBaUIsSUFBSSxnQkFBZ0IsRUFBRSxpQkFBaUIsSUFBSSxnQkFBZ0IsRUFBRSxnQkFBZ0IsSUFBSSxlQUFlLEVBQUUsY0FBYyxJQUFJLGFBQWEsRUFBRSxZQUFZLElBQUksV0FBVyxFQUFFLGdCQUFnQixJQUFJLGlCQUFpQixFQUF3Rix3QkFBd0IsSUFBSSxnQkFBZ0IsRUFBRSxtQkFBbUIsSUFBSSxXQUFXLEVBQUUsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsb0JBQW9CLElBQUksbUJBQW1CLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxpQkFBaUIsSUFBSSxnQkFBZ0IsRUFBRSwyQkFBMkIsSUFBSSwwQkFBMEIsRUFBRSxZQUFZLElBQUksV0FBVyxFQUFFLG9CQUFvQixJQUFJLG1CQUFtQixFQUFtQyxNQUFNLGVBQWUsQ0FBQztBQUU3Z0MsT0FBTyxFQUFDLHdDQUF3QyxFQUFFLCtCQUErQixFQUFFLHlCQUF5QixFQUFFLCtCQUErQixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFFMUwsT0FBTyxFQUFDLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBVyxNQUFNLGFBQWEsQ0FBQztBQUczRyxJQUFL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