source: trip-planner-front/node_modules/@angular/core/fesm2015/testing.js@ 8d391a1

Last change on this file since 8d391a1 was e29cc2e, checked in by Ema <ema_spirova@…>, 3 years ago

primeNG components

  • Property mode set to 100644
File size: 105.7 KB
Line 
1/**
2 * @license Angular v12.2.13
3 * (c) 2010-2021 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { getDebugNode, RendererFactory2, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, NgZone, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ModuleWithComponentFactories, InjectionToken, Injector, InjectFlags, ɵresetCompiledComponents, ɵflushModuleScopingQueueAsMuchAsPossible, Injectable, ɵclearOverrides, ɵoverrideComponentView, ɵINJECTOR_SCOPE, Optional, SkipSelf, ɵoverrideProvider, ɵivyEnabled } from '@angular/core';
8import { __awaiter } from 'tslib';
9import { ResourceLoader } from '@angular/compiler';
10
11/**
12 * @license
13 * Copyright Google LLC All Rights Reserved.
14 *
15 * Use of this source code is governed by an MIT-style license that can be
16 * found in the LICENSE file at https://angular.io/license
17 */
18/**
19 * Wraps a test function in an asynchronous test zone. The test will automatically
20 * complete when all asynchronous calls within this zone are done. Can be used
21 * to wrap an {@link inject} call.
22 *
23 * Example:
24 *
25 * ```
26 * it('...', waitForAsync(inject([AClass], (object) => {
27 * object.doSomething.then(() => {
28 * expect(...);
29 * })
30 * });
31 * ```
32 *
33 * @publicApi
34 */
35function waitForAsync(fn) {
36 const _Zone = typeof Zone !== 'undefined' ? Zone : null;
37 if (!_Zone) {
38 return function () {
39 return Promise.reject('Zone is needed for the waitForAsync() test helper but could not be found. ' +
40 'Please make sure that your environment includes zone.js');
41 };
42 }
43 const asyncTest = _Zone && _Zone[_Zone.__symbol__('asyncTest')];
44 if (typeof asyncTest === 'function') {
45 return asyncTest(fn);
46 }
47 return function () {
48 return Promise.reject('zone-testing.js is needed for the async() test helper but could not be found. ' +
49 'Please make sure that your environment includes zone.js/testing');
50 };
51}
52/**
53 * @deprecated use `waitForAsync()`, (expected removal in v12)
54 * @see {@link waitForAsync}
55 * @publicApi
56 * */
57function async(fn) {
58 return waitForAsync(fn);
59}
60
61/**
62 * @license
63 * Copyright Google LLC All Rights Reserved.
64 *
65 * Use of this source code is governed by an MIT-style license that can be
66 * found in the LICENSE file at https://angular.io/license
67 */
68/**
69 * Fixture for debugging and testing a component.
70 *
71 * @publicApi
72 */
73class ComponentFixture {
74 constructor(componentRef, ngZone, _autoDetect) {
75 this.componentRef = componentRef;
76 this.ngZone = ngZone;
77 this._autoDetect = _autoDetect;
78 this._isStable = true;
79 this._isDestroyed = false;
80 this._resolve = null;
81 this._promise = null;
82 this._onUnstableSubscription = null;
83 this._onStableSubscription = null;
84 this._onMicrotaskEmptySubscription = null;
85 this._onErrorSubscription = null;
86 this.changeDetectorRef = componentRef.changeDetectorRef;
87 this.elementRef = componentRef.location;
88 this.debugElement = getDebugNode(this.elementRef.nativeElement);
89 this.componentInstance = componentRef.instance;
90 this.nativeElement = this.elementRef.nativeElement;
91 this.componentRef = componentRef;
92 this.ngZone = ngZone;
93 if (ngZone) {
94 // Create subscriptions outside the NgZone so that the callbacks run oustide
95 // of NgZone.
96 ngZone.runOutsideAngular(() => {
97 this._onUnstableSubscription = ngZone.onUnstable.subscribe({
98 next: () => {
99 this._isStable = false;
100 }
101 });
102 this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({
103 next: () => {
104 if (this._autoDetect) {
105 // Do a change detection run with checkNoChanges set to true to check
106 // there are no changes on the second run.
107 this.detectChanges(true);
108 }
109 }
110 });
111 this._onStableSubscription = ngZone.onStable.subscribe({
112 next: () => {
113 this._isStable = true;
114 // Check whether there is a pending whenStable() completer to resolve.
115 if (this._promise !== null) {
116 // If so check whether there are no pending macrotasks before resolving.
117 // Do this check in the next tick so that ngZone gets a chance to update the state of
118 // pending macrotasks.
119 scheduleMicroTask(() => {
120 if (!ngZone.hasPendingMacrotasks) {
121 if (this._promise !== null) {
122 this._resolve(true);
123 this._resolve = null;
124 this._promise = null;
125 }
126 }
127 });
128 }
129 }
130 });
131 this._onErrorSubscription = ngZone.onError.subscribe({
132 next: (error) => {
133 throw error;
134 }
135 });
136 });
137 }
138 }
139 _tick(checkNoChanges) {
140 this.changeDetectorRef.detectChanges();
141 if (checkNoChanges) {
142 this.checkNoChanges();
143 }
144 }
145 /**
146 * Trigger a change detection cycle for the component.
147 */
148 detectChanges(checkNoChanges = true) {
149 if (this.ngZone != null) {
150 // Run the change detection inside the NgZone so that any async tasks as part of the change
151 // detection are captured by the zone and can be waited for in isStable.
152 this.ngZone.run(() => {
153 this._tick(checkNoChanges);
154 });
155 }
156 else {
157 // Running without zone. Just do the change detection.
158 this._tick(checkNoChanges);
159 }
160 }
161 /**
162 * Do a change detection run to make sure there were no changes.
163 */
164 checkNoChanges() {
165 this.changeDetectorRef.checkNoChanges();
166 }
167 /**
168 * Set whether the fixture should autodetect changes.
169 *
170 * Also runs detectChanges once so that any existing change is detected.
171 */
172 autoDetectChanges(autoDetect = true) {
173 if (this.ngZone == null) {
174 throw new Error('Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set');
175 }
176 this._autoDetect = autoDetect;
177 this.detectChanges();
178 }
179 /**
180 * Return whether the fixture is currently stable or has async tasks that have not been completed
181 * yet.
182 */
183 isStable() {
184 return this._isStable && !this.ngZone.hasPendingMacrotasks;
185 }
186 /**
187 * Get a promise that resolves when the fixture is stable.
188 *
189 * This can be used to resume testing after events have triggered asynchronous activity or
190 * asynchronous change detection.
191 */
192 whenStable() {
193 if (this.isStable()) {
194 return Promise.resolve(false);
195 }
196 else if (this._promise !== null) {
197 return this._promise;
198 }
199 else {
200 this._promise = new Promise(res => {
201 this._resolve = res;
202 });
203 return this._promise;
204 }
205 }
206 _getRenderer() {
207 if (this._renderer === undefined) {
208 this._renderer = this.componentRef.injector.get(RendererFactory2, null);
209 }
210 return this._renderer;
211 }
212 /**
213 * Get a promise that resolves when the ui state is stable following animations.
214 */
215 whenRenderingDone() {
216 const renderer = this._getRenderer();
217 if (renderer && renderer.whenRenderingDone) {
218 return renderer.whenRenderingDone();
219 }
220 return this.whenStable();
221 }
222 /**
223 * Trigger component destruction.
224 */
225 destroy() {
226 if (!this._isDestroyed) {
227 this.componentRef.destroy();
228 if (this._onUnstableSubscription != null) {
229 this._onUnstableSubscription.unsubscribe();
230 this._onUnstableSubscription = null;
231 }
232 if (this._onStableSubscription != null) {
233 this._onStableSubscription.unsubscribe();
234 this._onStableSubscription = null;
235 }
236 if (this._onMicrotaskEmptySubscription != null) {
237 this._onMicrotaskEmptySubscription.unsubscribe();
238 this._onMicrotaskEmptySubscription = null;
239 }
240 if (this._onErrorSubscription != null) {
241 this._onErrorSubscription.unsubscribe();
242 this._onErrorSubscription = null;
243 }
244 this._isDestroyed = true;
245 }
246 }
247}
248function scheduleMicroTask(fn) {
249 Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
250}
251
252/**
253 * @license
254 * Copyright Google LLC All Rights Reserved.
255 *
256 * Use of this source code is governed by an MIT-style license that can be
257 * found in the LICENSE file at https://angular.io/license
258 */
259const _Zone = typeof Zone !== 'undefined' ? Zone : null;
260const fakeAsyncTestModule = _Zone && _Zone[_Zone.__symbol__('fakeAsyncTest')];
261const fakeAsyncTestModuleNotLoadedErrorMessage = `zone-testing.js is needed for the fakeAsync() test helper but could not be found.
262 Please make sure that your environment includes zone.js/testing`;
263/**
264 * Clears out the shared fake async zone for a test.
265 * To be called in a global `beforeEach`.
266 *
267 * @publicApi
268 */
269function resetFakeAsyncZone() {
270 if (fakeAsyncTestModule) {
271 return fakeAsyncTestModule.resetFakeAsyncZone();
272 }
273 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
274}
275/**
276 * Wraps a function to be executed in the `fakeAsync` zone:
277 * - Microtasks are manually executed by calling `flushMicrotasks()`.
278 * - Timers are synchronous; `tick()` simulates the asynchronous passage of time.
279 *
280 * If there are any pending timers at the end of the function, an exception is thrown.
281 *
282 * Can be used to wrap `inject()` calls.
283 *
284 * @param fn The function that you want to wrap in the `fakeAysnc` zone.
285 *
286 * @usageNotes
287 * ### Example
288 *
289 * {@example core/testing/ts/fake_async.ts region='basic'}
290 *
291 *
292 * @returns The function wrapped to be executed in the `fakeAsync` zone.
293 * Any arguments passed when calling this returned function will be passed through to the `fn`
294 * function in the parameters when it is called.
295 *
296 * @publicApi
297 */
298function fakeAsync(fn) {
299 if (fakeAsyncTestModule) {
300 return fakeAsyncTestModule.fakeAsync(fn);
301 }
302 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
303}
304/**
305 * Simulates the asynchronous passage of time for the timers in the `fakeAsync` zone.
306 *
307 * The microtasks queue is drained at the very start of this function and after any timer callback
308 * has been executed.
309 *
310 * @param millis The number of milliseconds to advance the virtual timer.
311 * @param tickOptions The options to pass to the `tick()` function.
312 *
313 * @usageNotes
314 *
315 * The `tick()` option is a flag called `processNewMacroTasksSynchronously`,
316 * which determines whether or not to invoke new macroTasks.
317 *
318 * If you provide a `tickOptions` object, but do not specify a
319 * `processNewMacroTasksSynchronously` property (`tick(100, {})`),
320 * then `processNewMacroTasksSynchronously` defaults to true.
321 *
322 * If you omit the `tickOptions` parameter (`tick(100))`), then
323 * `tickOptions` defaults to `{processNewMacroTasksSynchronously: true}`.
324 *
325 * ### Example
326 *
327 * {@example core/testing/ts/fake_async.ts region='basic'}
328 *
329 * The following example includes a nested timeout (new macroTask), and
330 * the `tickOptions` parameter is allowed to default. In this case,
331 * `processNewMacroTasksSynchronously` defaults to true, and the nested
332 * function is executed on each tick.
333 *
334 * ```
335 * it ('test with nested setTimeout', fakeAsync(() => {
336 * let nestedTimeoutInvoked = false;
337 * function funcWithNestedTimeout() {
338 * setTimeout(() => {
339 * nestedTimeoutInvoked = true;
340 * });
341 * };
342 * setTimeout(funcWithNestedTimeout);
343 * tick();
344 * expect(nestedTimeoutInvoked).toBe(true);
345 * }));
346 * ```
347 *
348 * In the following case, `processNewMacroTasksSynchronously` is explicitly
349 * set to false, so the nested timeout function is not invoked.
350 *
351 * ```
352 * it ('test with nested setTimeout', fakeAsync(() => {
353 * let nestedTimeoutInvoked = false;
354 * function funcWithNestedTimeout() {
355 * setTimeout(() => {
356 * nestedTimeoutInvoked = true;
357 * });
358 * };
359 * setTimeout(funcWithNestedTimeout);
360 * tick(0, {processNewMacroTasksSynchronously: false});
361 * expect(nestedTimeoutInvoked).toBe(false);
362 * }));
363 * ```
364 *
365 *
366 * @publicApi
367 */
368function tick(millis = 0, tickOptions = {
369 processNewMacroTasksSynchronously: true
370}) {
371 if (fakeAsyncTestModule) {
372 return fakeAsyncTestModule.tick(millis, tickOptions);
373 }
374 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
375}
376/**
377 * Simulates the asynchronous passage of time for the timers in the `fakeAsync` zone by
378 * draining the macrotask queue until it is empty.
379 *
380 * @param maxTurns The maximum number of times the scheduler attempts to clear its queue before
381 * throwing an error.
382 * @returns The simulated time elapsed, in milliseconds.
383 *
384 * @publicApi
385 */
386function flush(maxTurns) {
387 if (fakeAsyncTestModule) {
388 return fakeAsyncTestModule.flush(maxTurns);
389 }
390 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
391}
392/**
393 * Discard all remaining periodic tasks.
394 *
395 * @publicApi
396 */
397function discardPeriodicTasks() {
398 if (fakeAsyncTestModule) {
399 return fakeAsyncTestModule.discardPeriodicTasks();
400 }
401 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
402}
403/**
404 * Flush any pending microtasks.
405 *
406 * @publicApi
407 */
408function flushMicrotasks() {
409 if (fakeAsyncTestModule) {
410 return fakeAsyncTestModule.flushMicrotasks();
411 }
412 throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
413}
414
415/**
416 * @license
417 * Copyright Google LLC All Rights Reserved.
418 *
419 * Use of this source code is governed by an MIT-style license that can be
420 * found in the LICENSE file at https://angular.io/license
421 */
422/**
423 * Used to resolve resource URLs on `@Component` when used with JIT compilation.
424 *
425 * Example:
426 * ```
427 * @Component({
428 * selector: 'my-comp',
429 * templateUrl: 'my-comp.html', // This requires asynchronous resolution
430 * })
431 * class MyComponent{
432 * }
433 *
434 * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
435 * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
436 *
437 * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
438 * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
439 *
440 * // Use browser's `fetch()` function as the default resource resolution strategy.
441 * resolveComponentResources(fetch).then(() => {
442 * // After resolution all URLs have been converted into `template` strings.
443 * renderComponent(MyComponent);
444 * });
445 *
446 * ```
447 *
448 * NOTE: In AOT the resolution happens during compilation, and so there should be no need
449 * to call this method outside JIT mode.
450 *
451 * @param resourceResolver a function which is responsible for returning a `Promise` to the
452 * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
453 */
454function resolveComponentResources(resourceResolver) {
455 // Store all promises which are fetching the resources.
456 const componentResolved = [];
457 // Cache so that we don't fetch the same resource more than once.
458 const urlMap = new Map();
459 function cachedResourceResolve(url) {
460 let promise = urlMap.get(url);
461 if (!promise) {
462 const resp = resourceResolver(url);
463 urlMap.set(url, promise = resp.then(unwrapResponse));
464 }
465 return promise;
466 }
467 componentResourceResolutionQueue.forEach((component, type) => {
468 const promises = [];
469 if (component.templateUrl) {
470 promises.push(cachedResourceResolve(component.templateUrl).then((template) => {
471 component.template = template;
472 }));
473 }
474 const styleUrls = component.styleUrls;
475 const styles = component.styles || (component.styles = []);
476 const styleOffset = component.styles.length;
477 styleUrls && styleUrls.forEach((styleUrl, index) => {
478 styles.push(''); // pre-allocate array.
479 promises.push(cachedResourceResolve(styleUrl).then((style) => {
480 styles[styleOffset + index] = style;
481 styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
482 if (styleUrls.length == 0) {
483 component.styleUrls = undefined;
484 }
485 }));
486 });
487 const fullyResolved = Promise.all(promises).then(() => componentDefResolved(type));
488 componentResolved.push(fullyResolved);
489 });
490 clearResolutionOfComponentResourcesQueue();
491 return Promise.all(componentResolved).then(() => undefined);
492}
493let componentResourceResolutionQueue = new Map();
494// Track when existing ɵcmp for a Type is waiting on resources.
495const componentDefPendingResolution = new Set();
496function maybeQueueResolutionOfComponentResources(type, metadata) {
497 if (componentNeedsResolution(metadata)) {
498 componentResourceResolutionQueue.set(type, metadata);
499 componentDefPendingResolution.add(type);
500 }
501}
502function isComponentDefPendingResolution(type) {
503 return componentDefPendingResolution.has(type);
504}
505function componentNeedsResolution(component) {
506 return !!((component.templateUrl && !component.hasOwnProperty('template')) ||
507 component.styleUrls && component.styleUrls.length);
508}
509function clearResolutionOfComponentResourcesQueue() {
510 const old = componentResourceResolutionQueue;
511 componentResourceResolutionQueue = new Map();
512 return old;
513}
514function restoreComponentResolutionQueue(queue) {
515 componentDefPendingResolution.clear();
516 queue.forEach((_, type) => componentDefPendingResolution.add(type));
517 componentResourceResolutionQueue = queue;
518}
519function isComponentResourceResolutionQueueEmpty() {
520 return componentResourceResolutionQueue.size === 0;
521}
522function unwrapResponse(response) {
523 return typeof response == 'string' ? response : response.text();
524}
525function componentDefResolved(type) {
526 componentDefPendingResolution.delete(type);
527}
528
529/**
530 * @license
531 * Copyright Google LLC All Rights Reserved.
532 *
533 * Use of this source code is governed by an MIT-style license that can be
534 * found in the LICENSE file at https://angular.io/license
535 */
536let _nextReferenceId = 0;
537class MetadataOverrider {
538 constructor() {
539 this._references = new Map();
540 }
541 /**
542 * Creates a new instance for the given metadata class
543 * based on an old instance and overrides.
544 */
545 overrideMetadata(metadataClass, oldMetadata, override) {
546 const props = {};
547 if (oldMetadata) {
548 _valueProps(oldMetadata).forEach((prop) => props[prop] = oldMetadata[prop]);
549 }
550 if (override.set) {
551 if (override.remove || override.add) {
552 throw new Error(`Cannot set and add/remove ${ɵstringify(metadataClass)} at the same time!`);
553 }
554 setMetadata(props, override.set);
555 }
556 if (override.remove) {
557 removeMetadata(props, override.remove, this._references);
558 }
559 if (override.add) {
560 addMetadata(props, override.add);
561 }
562 return new metadataClass(props);
563 }
564}
565function removeMetadata(metadata, remove, references) {
566 const removeObjects = new Set();
567 for (const prop in remove) {
568 const removeValue = remove[prop];
569 if (Array.isArray(removeValue)) {
570 removeValue.forEach((value) => {
571 removeObjects.add(_propHashKey(prop, value, references));
572 });
573 }
574 else {
575 removeObjects.add(_propHashKey(prop, removeValue, references));
576 }
577 }
578 for (const prop in metadata) {
579 const propValue = metadata[prop];
580 if (Array.isArray(propValue)) {
581 metadata[prop] = propValue.filter((value) => !removeObjects.has(_propHashKey(prop, value, references)));
582 }
583 else {
584 if (removeObjects.has(_propHashKey(prop, propValue, references))) {
585 metadata[prop] = undefined;
586 }
587 }
588 }
589}
590function addMetadata(metadata, add) {
591 for (const prop in add) {
592 const addValue = add[prop];
593 const propValue = metadata[prop];
594 if (propValue != null && Array.isArray(propValue)) {
595 metadata[prop] = propValue.concat(addValue);
596 }
597 else {
598 metadata[prop] = addValue;
599 }
600 }
601}
602function setMetadata(metadata, set) {
603 for (const prop in set) {
604 metadata[prop] = set[prop];
605 }
606}
607function _propHashKey(propName, propValue, references) {
608 const replacer = (key, value) => {
609 if (typeof value === 'function') {
610 value = _serializeReference(value, references);
611 }
612 return value;
613 };
614 return `${propName}:${JSON.stringify(propValue, replacer)}`;
615}
616function _serializeReference(ref, references) {
617 let id = references.get(ref);
618 if (!id) {
619 id = `${ɵstringify(ref)}${_nextReferenceId++}`;
620 references.set(ref, id);
621 }
622 return id;
623}
624function _valueProps(obj) {
625 const props = [];
626 // regular public props
627 Object.keys(obj).forEach((prop) => {
628 if (!prop.startsWith('_')) {
629 props.push(prop);
630 }
631 });
632 // getters
633 let proto = obj;
634 while (proto = Object.getPrototypeOf(proto)) {
635 Object.keys(proto).forEach((protoProp) => {
636 const desc = Object.getOwnPropertyDescriptor(proto, protoProp);
637 if (!protoProp.startsWith('_') && desc && 'get' in desc) {
638 props.push(protoProp);
639 }
640 });
641 }
642 return props;
643}
644
645/**
646 * @license
647 * Copyright Google LLC All Rights Reserved.
648 *
649 * Use of this source code is governed by an MIT-style license that can be
650 * found in the LICENSE file at https://angular.io/license
651 */
652const reflection = new ɵReflectionCapabilities();
653/**
654 * Allows to override ivy metadata for tests (via the `TestBed`).
655 */
656class OverrideResolver {
657 constructor() {
658 this.overrides = new Map();
659 this.resolved = new Map();
660 }
661 addOverride(type, override) {
662 const overrides = this.overrides.get(type) || [];
663 overrides.push(override);
664 this.overrides.set(type, overrides);
665 this.resolved.delete(type);
666 }
667 setOverrides(overrides) {
668 this.overrides.clear();
669 overrides.forEach(([type, override]) => {
670 this.addOverride(type, override);
671 });
672 }
673 getAnnotation(type) {
674 const annotations = reflection.annotations(type);
675 // Try to find the nearest known Type annotation and make sure that this annotation is an
676 // instance of the type we are looking for, so we can use it for resolution. Note: there might
677 // be multiple known annotations found due to the fact that Components can extend Directives (so
678 // both Directive and Component annotations would be present), so we always check if the known
679 // annotation has the right type.
680 for (let i = annotations.length - 1; i >= 0; i--) {
681 const annotation = annotations[i];
682 const isKnownType = annotation instanceof Directive || annotation instanceof Component ||
683 annotation instanceof Pipe || annotation instanceof NgModule;
684 if (isKnownType) {
685 return annotation instanceof this.type ? annotation : null;
686 }
687 }
688 return null;
689 }
690 resolve(type) {
691 let resolved = this.resolved.get(type) || null;
692 if (!resolved) {
693 resolved = this.getAnnotation(type);
694 if (resolved) {
695 const overrides = this.overrides.get(type);
696 if (overrides) {
697 const overrider = new MetadataOverrider();
698 overrides.forEach(override => {
699 resolved = overrider.overrideMetadata(this.type, resolved, override);
700 });
701 }
702 }
703 this.resolved.set(type, resolved);
704 }
705 return resolved;
706 }
707}
708class DirectiveResolver extends OverrideResolver {
709 get type() {
710 return Directive;
711 }
712}
713class ComponentResolver extends OverrideResolver {
714 get type() {
715 return Component;
716 }
717}
718class PipeResolver extends OverrideResolver {
719 get type() {
720 return Pipe;
721 }
722}
723class NgModuleResolver extends OverrideResolver {
724 get type() {
725 return NgModule;
726 }
727}
728
729/**
730 * @license
731 * Copyright Google LLC All Rights Reserved.
732 *
733 * Use of this source code is governed by an MIT-style license that can be
734 * found in the LICENSE file at https://angular.io/license
735 */
736var TestingModuleOverride;
737(function (TestingModuleOverride) {
738 TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
739 TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
740})(TestingModuleOverride || (TestingModuleOverride = {}));
741function isTestingModuleOverride(value) {
742 return value === TestingModuleOverride.DECLARATION ||
743 value === TestingModuleOverride.OVERRIDE_TEMPLATE;
744}
745class R3TestBedCompiler {
746 constructor(platform, additionalModuleTypes) {
747 this.platform = platform;
748 this.additionalModuleTypes = additionalModuleTypes;
749 this.originalComponentResolutionQueue = null;
750 // Testing module configuration
751 this.declarations = [];
752 this.imports = [];
753 this.providers = [];
754 this.schemas = [];
755 // Queues of components/directives/pipes that should be recompiled.
756 this.pendingComponents = new Set();
757 this.pendingDirectives = new Set();
758 this.pendingPipes = new Set();
759 // Keep track of all components and directives, so we can patch Providers onto defs later.
760 this.seenComponents = new Set();
761 this.seenDirectives = new Set();
762 // Keep track of overridden modules, so that we can collect all affected ones in the module tree.
763 this.overriddenModules = new Set();
764 // Store resolved styles for Components that have template overrides present and `styleUrls`
765 // defined at the same time.
766 this.existingComponentStyles = new Map();
767 this.resolvers = initResolvers();
768 this.componentToModuleScope = new Map();
769 // Map that keeps initial version of component/directive/pipe defs in case
770 // we compile a Type again, thus overriding respective static fields. This is
771 // required to make sure we restore defs to their initial states between test runs
772 // TODO: we should support the case with multiple defs on a type
773 this.initialNgDefs = new Map();
774 // Array that keeps cleanup operations for initial versions of component/directive/pipe/module
775 // defs in case TestBed makes changes to the originals.
776 this.defCleanupOps = [];
777 this._injector = null;
778 this.compilerProviders = null;
779 this.providerOverrides = [];
780 this.rootProviderOverrides = [];
781 // Overrides for injectables with `{providedIn: SomeModule}` need to be tracked and added to that
782 // module's provider list.
783 this.providerOverridesByModule = new Map();
784 this.providerOverridesByToken = new Map();
785 this.moduleProvidersOverridden = new Set();
786 this.testModuleRef = null;
787 class DynamicTestModule {
788 }
789 this.testModuleType = DynamicTestModule;
790 }
791 setCompilerProviders(providers) {
792 this.compilerProviders = providers;
793 this._injector = null;
794 }
795 configureTestingModule(moduleDef) {
796 // Enqueue any compilation tasks for the directly declared component.
797 if (moduleDef.declarations !== undefined) {
798 this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
799 this.declarations.push(...moduleDef.declarations);
800 }
801 // Enqueue any compilation tasks for imported modules.
802 if (moduleDef.imports !== undefined) {
803 this.queueTypesFromModulesArray(moduleDef.imports);
804 this.imports.push(...moduleDef.imports);
805 }
806 if (moduleDef.providers !== undefined) {
807 this.providers.push(...moduleDef.providers);
808 }
809 if (moduleDef.schemas !== undefined) {
810 this.schemas.push(...moduleDef.schemas);
811 }
812 }
813 overrideModule(ngModule, override) {
814 this.overriddenModules.add(ngModule);
815 // Compile the module right away.
816 this.resolvers.module.addOverride(ngModule, override);
817 const metadata = this.resolvers.module.resolve(ngModule);
818 if (metadata === null) {
819 throw invalidTypeError(ngModule.name, 'NgModule');
820 }
821 this.recompileNgModule(ngModule, metadata);
822 // At this point, the module has a valid module def (ɵmod), but the override may have introduced
823 // new declarations or imported modules. Ingest any possible new types and add them to the
824 // current queue.
825 this.queueTypesFromModulesArray([ngModule]);
826 }
827 overrideComponent(component, override) {
828 this.resolvers.component.addOverride(component, override);
829 this.pendingComponents.add(component);
830 }
831 overrideDirective(directive, override) {
832 this.resolvers.directive.addOverride(directive, override);
833 this.pendingDirectives.add(directive);
834 }
835 overridePipe(pipe, override) {
836 this.resolvers.pipe.addOverride(pipe, override);
837 this.pendingPipes.add(pipe);
838 }
839 overrideProvider(token, provider) {
840 let providerDef;
841 if (provider.useFactory !== undefined) {
842 providerDef = {
843 provide: token,
844 useFactory: provider.useFactory,
845 deps: provider.deps || [],
846 multi: provider.multi
847 };
848 }
849 else if (provider.useValue !== undefined) {
850 providerDef = { provide: token, useValue: provider.useValue, multi: provider.multi };
851 }
852 else {
853 providerDef = { provide: token };
854 }
855 const injectableDef = typeof token !== 'string' ? ɵgetInjectableDef(token) : null;
856 const providedIn = injectableDef === null ? null : resolveForwardRef(injectableDef.providedIn);
857 const overridesBucket = providedIn === 'root' ? this.rootProviderOverrides : this.providerOverrides;
858 overridesBucket.push(providerDef);
859 // Keep overrides grouped by token as well for fast lookups using token
860 this.providerOverridesByToken.set(token, providerDef);
861 if (injectableDef !== null && providedIn !== null && typeof providedIn !== 'string') {
862 const existingOverrides = this.providerOverridesByModule.get(providedIn);
863 if (existingOverrides !== undefined) {
864 existingOverrides.push(providerDef);
865 }
866 else {
867 this.providerOverridesByModule.set(providedIn, [providerDef]);
868 }
869 }
870 }
871 overrideTemplateUsingTestingModule(type, template) {
872 const def = type[ɵNG_COMP_DEF];
873 const hasStyleUrls = () => {
874 const metadata = this.resolvers.component.resolve(type);
875 return !!metadata.styleUrls && metadata.styleUrls.length > 0;
876 };
877 const overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
878 // In Ivy, compiling a component does not require knowing the module providing the
879 // component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
880 // overrideComponent. Important: overriding template requires full Component re-compilation,
881 // which may fail in case styleUrls are also present (thus Component is considered as required
882 // resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
883 // preserve current styles available on Component def and restore styles back once compilation
884 // is complete.
885 const override = overrideStyleUrls ? { template, styles: [], styleUrls: [] } : { template };
886 this.overrideComponent(type, { set: override });
887 if (overrideStyleUrls && def.styles && def.styles.length > 0) {
888 this.existingComponentStyles.set(type, def.styles);
889 }
890 // Set the component's scope to be the testing module.
891 this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
892 }
893 compileComponents() {
894 return __awaiter(this, void 0, void 0, function* () {
895 this.clearComponentResolutionQueue();
896 // Run compilers for all queued types.
897 let needsAsyncResources = this.compileTypesSync();
898 // compileComponents() should not be async unless it needs to be.
899 if (needsAsyncResources) {
900 let resourceLoader;
901 let resolver = (url) => {
902 if (!resourceLoader) {
903 resourceLoader = this.injector.get(ResourceLoader);
904 }
905 return Promise.resolve(resourceLoader.get(url));
906 };
907 yield resolveComponentResources(resolver);
908 }
909 });
910 }
911 finalize() {
912 // One last compile
913 this.compileTypesSync();
914 // Create the testing module itself.
915 this.compileTestModule();
916 this.applyTransitiveScopes();
917 this.applyProviderOverrides();
918 // Patch previously stored `styles` Component values (taken from ɵcmp), in case these
919 // Components have `styleUrls` fields defined and template override was requested.
920 this.patchComponentsWithExistingStyles();
921 // Clear the componentToModuleScope map, so that future compilations don't reset the scope of
922 // every component.
923 this.componentToModuleScope.clear();
924 const parentInjector = this.platform.injector;
925 this.testModuleRef = new ɵRender3NgModuleRef(this.testModuleType, parentInjector);
926 // ApplicationInitStatus.runInitializers() is marked @internal to core.
927 // Cast it to any before accessing it.
928 this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
929 // Set locale ID after running app initializers, since locale information might be updated while
930 // running initializers. This is also consistent with the execution order while bootstrapping an
931 // app (see `packages/core/src/application_ref.ts` file).
932 const localeId = this.testModuleRef.injector.get(LOCALE_ID, ɵDEFAULT_LOCALE_ID);
933 ɵsetLocaleId(localeId);
934 return this.testModuleRef;
935 }
936 /**
937 * @internal
938 */
939 _compileNgModuleSync(moduleType) {
940 this.queueTypesFromModulesArray([moduleType]);
941 this.compileTypesSync();
942 this.applyProviderOverrides();
943 this.applyProviderOverridesToModule(moduleType);
944 this.applyTransitiveScopes();
945 }
946 /**
947 * @internal
948 */
949 _compileNgModuleAsync(moduleType) {
950 return __awaiter(this, void 0, void 0, function* () {
951 this.queueTypesFromModulesArray([moduleType]);
952 yield this.compileComponents();
953 this.applyProviderOverrides();
954 this.applyProviderOverridesToModule(moduleType);
955 this.applyTransitiveScopes();
956 });
957 }
958 /**
959 * @internal
960 */
961 _getModuleResolver() {
962 return this.resolvers.module;
963 }
964 /**
965 * @internal
966 */
967 _getComponentFactories(moduleType) {
968 return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce((factories, declaration) => {
969 const componentDef = declaration.ɵcmp;
970 componentDef && factories.push(new ɵRender3ComponentFactory(componentDef, this.testModuleRef));
971 return factories;
972 }, []);
973 }
974 compileTypesSync() {
975 // Compile all queued components, directives, pipes.
976 let needsAsyncResources = false;
977 this.pendingComponents.forEach(declaration => {
978 needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
979 const metadata = this.resolvers.component.resolve(declaration);
980 if (metadata === null) {
981 throw invalidTypeError(declaration.name, 'Component');
982 }
983 this.maybeStoreNgDef(ɵNG_COMP_DEF, declaration);
984 ɵcompileComponent(declaration, metadata);
985 });
986 this.pendingComponents.clear();
987 this.pendingDirectives.forEach(declaration => {
988 const metadata = this.resolvers.directive.resolve(declaration);
989 if (metadata === null) {
990 throw invalidTypeError(declaration.name, 'Directive');
991 }
992 this.maybeStoreNgDef(ɵNG_DIR_DEF, declaration);
993 ɵcompileDirective(declaration, metadata);
994 });
995 this.pendingDirectives.clear();
996 this.pendingPipes.forEach(declaration => {
997 const metadata = this.resolvers.pipe.resolve(declaration);
998 if (metadata === null) {
999 throw invalidTypeError(declaration.name, 'Pipe');
1000 }
1001 this.maybeStoreNgDef(ɵNG_PIPE_DEF, declaration);
1002 ɵcompilePipe(declaration, metadata);
1003 });
1004 this.pendingPipes.clear();
1005 return needsAsyncResources;
1006 }
1007 applyTransitiveScopes() {
1008 if (this.overriddenModules.size > 0) {
1009 // Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
1010 // calculated and stored in `transitiveCompileScopes`. If module overrides are present,
1011 // collect all affected modules and reset scopes to force their re-calculation.
1012 const testingModuleDef = this.testModuleType[ɵNG_MOD_DEF];
1013 const affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
1014 if (affectedModules.size > 0) {
1015 affectedModules.forEach(moduleType => {
1016 this.storeFieldOfDefOnType(moduleType, ɵNG_MOD_DEF, 'transitiveCompileScopes');
1017 moduleType[ɵNG_MOD_DEF].transitiveCompileScopes = null;
1018 });
1019 }
1020 }
1021 const moduleToScope = new Map();
1022 const getScopeOfModule = (moduleType) => {
1023 if (!moduleToScope.has(moduleType)) {
1024 const isTestingModule = isTestingModuleOverride(moduleType);
1025 const realType = isTestingModule ? this.testModuleType : moduleType;
1026 moduleToScope.set(moduleType, ɵtransitiveScopesFor(realType));
1027 }
1028 return moduleToScope.get(moduleType);
1029 };
1030 this.componentToModuleScope.forEach((moduleType, componentType) => {
1031 const moduleScope = getScopeOfModule(moduleType);
1032 this.storeFieldOfDefOnType(componentType, ɵNG_COMP_DEF, 'directiveDefs');
1033 this.storeFieldOfDefOnType(componentType, ɵNG_COMP_DEF, 'pipeDefs');
1034 // `tView` that is stored on component def contains information about directives and pipes
1035 // that are in the scope of this component. Patching component scope will cause `tView` to be
1036 // changed. Store original `tView` before patching scope, so the `tView` (including scope
1037 // information) is restored back to its previous/original state before running next test.
1038 this.storeFieldOfDefOnType(componentType, ɵNG_COMP_DEF, 'tView');
1039 ɵpatchComponentDefWithScope(componentType.ɵcmp, moduleScope);
1040 });
1041 this.componentToModuleScope.clear();
1042 }
1043 applyProviderOverrides() {
1044 const maybeApplyOverrides = (field) => (type) => {
1045 const resolver = field === ɵNG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
1046 const metadata = resolver.resolve(type);
1047 if (this.hasProviderOverrides(metadata.providers)) {
1048 this.patchDefWithProviderOverrides(type, field);
1049 }
1050 };
1051 this.seenComponents.forEach(maybeApplyOverrides(ɵNG_COMP_DEF));
1052 this.seenDirectives.forEach(maybeApplyOverrides(ɵNG_DIR_DEF));
1053 this.seenComponents.clear();
1054 this.seenDirectives.clear();
1055 }
1056 applyProviderOverridesToModule(moduleType) {
1057 if (this.moduleProvidersOverridden.has(moduleType)) {
1058 return;
1059 }
1060 this.moduleProvidersOverridden.add(moduleType);
1061 const injectorDef = moduleType[ɵNG_INJ_DEF];
1062 if (this.providerOverridesByToken.size > 0) {
1063 const providers = [
1064 ...injectorDef.providers,
1065 ...(this.providerOverridesByModule.get(moduleType) || [])
1066 ];
1067 if (this.hasProviderOverrides(providers)) {
1068 this.maybeStoreNgDef(ɵNG_INJ_DEF, moduleType);
1069 this.storeFieldOfDefOnType(moduleType, ɵNG_INJ_DEF, 'providers');
1070 injectorDef.providers = this.getOverriddenProviders(providers);
1071 }
1072 // Apply provider overrides to imported modules recursively
1073 const moduleDef = moduleType[ɵNG_MOD_DEF];
1074 const imports = maybeUnwrapFn(moduleDef.imports);
1075 for (const importedModule of imports) {
1076 this.applyProviderOverridesToModule(importedModule);
1077 }
1078 // Also override the providers on any ModuleWithProviders imports since those don't appear in
1079 // the moduleDef.
1080 for (const importedModule of flatten(injectorDef.imports)) {
1081 if (isModuleWithProviders(importedModule)) {
1082 this.defCleanupOps.push({
1083 object: importedModule,
1084 fieldName: 'providers',
1085 originalValue: importedModule.providers
1086 });
1087 importedModule.providers = this.getOverriddenProviders(importedModule.providers);
1088 }
1089 }
1090 }
1091 }
1092 patchComponentsWithExistingStyles() {
1093 this.existingComponentStyles.forEach((styles, type) => type[ɵNG_COMP_DEF].styles = styles);
1094 this.existingComponentStyles.clear();
1095 }
1096 queueTypeArray(arr, moduleType) {
1097 for (const value of arr) {
1098 if (Array.isArray(value)) {
1099 this.queueTypeArray(value, moduleType);
1100 }
1101 else {
1102 this.queueType(value, moduleType);
1103 }
1104 }
1105 }
1106 recompileNgModule(ngModule, metadata) {
1107 // Cache the initial ngModuleDef as it will be overwritten.
1108 this.maybeStoreNgDef(ɵNG_MOD_DEF, ngModule);
1109 this.maybeStoreNgDef(ɵNG_INJ_DEF, ngModule);
1110 ɵcompileNgModuleDefs(ngModule, metadata);
1111 }
1112 queueType(type, moduleType) {
1113 const component = this.resolvers.component.resolve(type);
1114 if (component) {
1115 // Check whether a give Type has respective NG def (ɵcmp) and compile if def is
1116 // missing. That might happen in case a class without any Angular decorators extends another
1117 // class where Component/Directive/Pipe decorator is defined.
1118 if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(ɵNG_COMP_DEF)) {
1119 this.pendingComponents.add(type);
1120 }
1121 this.seenComponents.add(type);
1122 // Keep track of the module which declares this component, so later the component's scope
1123 // can be set correctly. If the component has already been recorded here, then one of several
1124 // cases is true:
1125 // * the module containing the component was imported multiple times (common).
1126 // * the component is declared in multiple modules (which is an error).
1127 // * the component was in 'declarations' of the testing module, and also in an imported module
1128 // in which case the module scope will be TestingModuleOverride.DECLARATION.
1129 // * overrideTemplateUsingTestingModule was called for the component in which case the module
1130 // scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
1131 //
1132 // If the component was previously in the testing module's 'declarations' (meaning the
1133 // current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
1134 // real module, which was imported. This pattern is understood to mean that the component
1135 // should use its original scope, but that the testing module should also contain the
1136 // component in its scope.
1137 if (!this.componentToModuleScope.has(type) ||
1138 this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION) {
1139 this.componentToModuleScope.set(type, moduleType);
1140 }
1141 return;
1142 }
1143 const directive = this.resolvers.directive.resolve(type);
1144 if (directive) {
1145 if (!type.hasOwnProperty(ɵNG_DIR_DEF)) {
1146 this.pendingDirectives.add(type);
1147 }
1148 this.seenDirectives.add(type);
1149 return;
1150 }
1151 const pipe = this.resolvers.pipe.resolve(type);
1152 if (pipe && !type.hasOwnProperty(ɵNG_PIPE_DEF)) {
1153 this.pendingPipes.add(type);
1154 return;
1155 }
1156 }
1157 queueTypesFromModulesArray(arr) {
1158 // Because we may encounter the same NgModule while processing the imports and exports of an
1159 // NgModule tree, we cache them in this set so we can skip ones that have already been seen
1160 // encountered. In some test setups, this caching resulted in 10X runtime improvement.
1161 const processedNgModuleDefs = new Set();
1162 const queueTypesFromModulesArrayRecur = (arr) => {
1163 for (const value of arr) {
1164 if (Array.isArray(value)) {
1165 queueTypesFromModulesArrayRecur(value);
1166 }
1167 else if (hasNgModuleDef(value)) {
1168 const def = value.ɵmod;
1169 if (processedNgModuleDefs.has(def)) {
1170 continue;
1171 }
1172 processedNgModuleDefs.add(def);
1173 // Look through declarations, imports, and exports, and queue
1174 // everything found there.
1175 this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
1176 queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports));
1177 queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports));
1178 }
1179 else if (isModuleWithProviders(value)) {
1180 queueTypesFromModulesArrayRecur([value.ngModule]);
1181 }
1182 }
1183 };
1184 queueTypesFromModulesArrayRecur(arr);
1185 }
1186 // When module overrides (via `TestBed.overrideModule`) are present, it might affect all modules
1187 // that import (even transitively) an overridden one. For all affected modules we need to
1188 // recalculate their scopes for a given test run and restore original scopes at the end. The goal
1189 // of this function is to collect all affected modules in a set for further processing. Example:
1190 // if we have the following module hierarchy: A -> B -> C (where `->` means `imports`) and module
1191 // `C` is overridden, we consider `A` and `B` as affected, since their scopes might become
1192 // invalidated with the override.
1193 collectModulesAffectedByOverrides(arr) {
1194 const seenModules = new Set();
1195 const affectedModules = new Set();
1196 const calcAffectedModulesRecur = (arr, path) => {
1197 for (const value of arr) {
1198 if (Array.isArray(value)) {
1199 // If the value is an array, just flatten it (by invoking this function recursively),
1200 // keeping "path" the same.
1201 calcAffectedModulesRecur(value, path);
1202 }
1203 else if (hasNgModuleDef(value)) {
1204 if (seenModules.has(value)) {
1205 // If we've seen this module before and it's included into "affected modules" list, mark
1206 // the whole path that leads to that module as affected, but do not descend into its
1207 // imports, since we already examined them before.
1208 if (affectedModules.has(value)) {
1209 path.forEach(item => affectedModules.add(item));
1210 }
1211 continue;
1212 }
1213 seenModules.add(value);
1214 if (this.overriddenModules.has(value)) {
1215 path.forEach(item => affectedModules.add(item));
1216 }
1217 // Examine module imports recursively to look for overridden modules.
1218 const moduleDef = value[ɵNG_MOD_DEF];
1219 calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
1220 }
1221 }
1222 };
1223 calcAffectedModulesRecur(arr, []);
1224 return affectedModules;
1225 }
1226 maybeStoreNgDef(prop, type) {
1227 if (!this.initialNgDefs.has(type)) {
1228 const currentDef = Object.getOwnPropertyDescriptor(type, prop);
1229 this.initialNgDefs.set(type, [prop, currentDef]);
1230 }
1231 }
1232 storeFieldOfDefOnType(type, defField, fieldName) {
1233 const def = type[defField];
1234 const originalValue = def[fieldName];
1235 this.defCleanupOps.push({ object: def, fieldName, originalValue });
1236 }
1237 /**
1238 * Clears current components resolution queue, but stores the state of the queue, so we can
1239 * restore it later. Clearing the queue is required before we try to compile components (via
1240 * `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
1241 */
1242 clearComponentResolutionQueue() {
1243 if (this.originalComponentResolutionQueue === null) {
1244 this.originalComponentResolutionQueue = new Map();
1245 }
1246 clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
1247 }
1248 /*
1249 * Restores component resolution queue to the previously saved state. This operation is performed
1250 * as a part of restoring the state after completion of the current set of tests (that might
1251 * potentially mutate the state).
1252 */
1253 restoreComponentResolutionQueue() {
1254 if (this.originalComponentResolutionQueue !== null) {
1255 restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
1256 this.originalComponentResolutionQueue = null;
1257 }
1258 }
1259 restoreOriginalState() {
1260 // Process cleanup ops in reverse order so the field's original value is restored correctly (in
1261 // case there were multiple overrides for the same field).
1262 forEachRight(this.defCleanupOps, (op) => {
1263 op.object[op.fieldName] = op.originalValue;
1264 });
1265 // Restore initial component/directive/pipe defs
1266 this.initialNgDefs.forEach((value, type) => {
1267 const [prop, descriptor] = value;
1268 if (!descriptor) {
1269 // Delete operations are generally undesirable since they have performance implications
1270 // on objects they were applied to. In this particular case, situations where this code
1271 // is invoked should be quite rare to cause any noticeable impact, since it's applied
1272 // only to some test cases (for example when class with no annotations extends some
1273 // @Component) when we need to clear 'ɵcmp' field on a given class to restore
1274 // its original state (before applying overrides and running tests).
1275 delete type[prop];
1276 }
1277 else {
1278 Object.defineProperty(type, prop, descriptor);
1279 }
1280 });
1281 this.initialNgDefs.clear();
1282 this.moduleProvidersOverridden.clear();
1283 this.restoreComponentResolutionQueue();
1284 // Restore the locale ID to the default value, this shouldn't be necessary but we never know
1285 ɵsetLocaleId(ɵDEFAULT_LOCALE_ID);
1286 }
1287 compileTestModule() {
1288 class RootScopeModule {
1289 }
1290 ɵcompileNgModuleDefs(RootScopeModule, {
1291 providers: [...this.rootProviderOverrides],
1292 });
1293 const ngZone = new NgZone({ enableLongStackTrace: true });
1294 const providers = [
1295 { provide: NgZone, useValue: ngZone },
1296 { provide: Compiler, useFactory: () => new R3TestCompiler(this) },
1297 ...this.providers,
1298 ...this.providerOverrides,
1299 ];
1300 const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
1301 // clang-format off
1302 ɵcompileNgModuleDefs(this.testModuleType, {
1303 declarations: this.declarations,
1304 imports,
1305 schemas: this.schemas,
1306 providers,
1307 }, /* allowDuplicateDeclarationsInRoot */ true);
1308 // clang-format on
1309 this.applyProviderOverridesToModule(this.testModuleType);
1310 }
1311 get injector() {
1312 if (this._injector !== null) {
1313 return this._injector;
1314 }
1315 const providers = [];
1316 const compilerOptions = this.platform.injector.get(COMPILER_OPTIONS);
1317 compilerOptions.forEach(opts => {
1318 if (opts.providers) {
1319 providers.push(opts.providers);
1320 }
1321 });
1322 if (this.compilerProviders !== null) {
1323 providers.push(...this.compilerProviders);
1324 }
1325 // TODO(ocombe): make this work with an Injector directly instead of creating a module for it
1326 class CompilerModule {
1327 }
1328 ɵcompileNgModuleDefs(CompilerModule, { providers });
1329 const CompilerModuleFactory = new ɵNgModuleFactory(CompilerModule);
1330 this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
1331 return this._injector;
1332 }
1333 // get overrides for a specific provider (if any)
1334 getSingleProviderOverrides(provider) {
1335 const token = getProviderToken(provider);
1336 return this.providerOverridesByToken.get(token) || null;
1337 }
1338 getProviderOverrides(providers) {
1339 if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
1340 return [];
1341 // There are two flattening operations here. The inner flatten() operates on the metadata's
1342 // providers and applies a mapping function which retrieves overrides for each incoming
1343 // provider. The outer flatten() then flattens the produced overrides array. If this is not
1344 // done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
1345 // providers array and contaminate any error messages that might be generated.
1346 return flatten(flatten(providers, (provider) => this.getSingleProviderOverrides(provider) || []));
1347 }
1348 getOverriddenProviders(providers) {
1349 if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
1350 return [];
1351 const flattenedProviders = flatten(providers);
1352 const overrides = this.getProviderOverrides(flattenedProviders);
1353 const overriddenProviders = [...flattenedProviders, ...overrides];
1354 const final = [];
1355 const seenOverriddenProviders = new Set();
1356 // We iterate through the list of providers in reverse order to make sure provider overrides
1357 // take precedence over the values defined in provider list. We also filter out all providers
1358 // that have overrides, keeping overridden values only. This is needed, since presence of a
1359 // provider with `ngOnDestroy` hook will cause this hook to be registered and invoked later.
1360 forEachRight(overriddenProviders, (provider) => {
1361 const token = getProviderToken(provider);
1362 if (this.providerOverridesByToken.has(token)) {
1363 if (!seenOverriddenProviders.has(token)) {
1364 seenOverriddenProviders.add(token);
1365 // Treat all overridden providers as `{multi: false}` (even if it's a multi-provider) to
1366 // make sure that provided override takes highest precedence and is not combined with
1367 // other instances of the same multi provider.
1368 final.unshift(Object.assign(Object.assign({}, provider), { multi: false }));
1369 }
1370 }
1371 else {
1372 final.unshift(provider);
1373 }
1374 });
1375 return final;
1376 }
1377 hasProviderOverrides(providers) {
1378 return this.getProviderOverrides(providers).length > 0;
1379 }
1380 patchDefWithProviderOverrides(declaration, field) {
1381 const def = declaration[field];
1382 if (def && def.providersResolver) {
1383 this.maybeStoreNgDef(field, declaration);
1384 const resolver = def.providersResolver;
1385 const processProvidersFn = (providers) => this.getOverriddenProviders(providers);
1386 this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
1387 def.providersResolver = (ngDef) => resolver(ngDef, processProvidersFn);
1388 }
1389 }
1390}
1391function initResolvers() {
1392 return {
1393 module: new NgModuleResolver(),
1394 component: new ComponentResolver(),
1395 directive: new DirectiveResolver(),
1396 pipe: new PipeResolver()
1397 };
1398}
1399function hasNgModuleDef(value) {
1400 return value.hasOwnProperty('ɵmod');
1401}
1402function maybeUnwrapFn(maybeFn) {
1403 return maybeFn instanceof Function ? maybeFn() : maybeFn;
1404}
1405function flatten(values, mapFn) {
1406 const out = [];
1407 values.forEach(value => {
1408 if (Array.isArray(value)) {
1409 out.push(...flatten(value, mapFn));
1410 }
1411 else {
1412 out.push(mapFn ? mapFn(value) : value);
1413 }
1414 });
1415 return out;
1416}
1417function getProviderField(provider, field) {
1418 return provider && typeof provider === 'object' && provider[field];
1419}
1420function getProviderToken(provider) {
1421 return getProviderField(provider, 'provide') || provider;
1422}
1423function isModuleWithProviders(value) {
1424 return value.hasOwnProperty('ngModule');
1425}
1426function forEachRight(values, fn) {
1427 for (let idx = values.length - 1; idx >= 0; idx--) {
1428 fn(values[idx], idx);
1429 }
1430}
1431function invalidTypeError(name, expectedType) {
1432 return new Error(`${name} class doesn't have @${expectedType} decorator or is missing metadata.`);
1433}
1434class R3TestCompiler {
1435 constructor(testBed) {
1436 this.testBed = testBed;
1437 }
1438 compileModuleSync(moduleType) {
1439 this.testBed._compileNgModuleSync(moduleType);
1440 return new ɵNgModuleFactory(moduleType);
1441 }
1442 compileModuleAsync(moduleType) {
1443 return __awaiter(this, void 0, void 0, function* () {
1444 yield this.testBed._compileNgModuleAsync(moduleType);
1445 return new ɵNgModuleFactory(moduleType);
1446 });
1447 }
1448 compileModuleAndAllComponentsSync(moduleType) {
1449 const ngModuleFactory = this.compileModuleSync(moduleType);
1450 const componentFactories = this.testBed._getComponentFactories(moduleType);
1451 return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
1452 }
1453 compileModuleAndAllComponentsAsync(moduleType) {
1454 return __awaiter(this, void 0, void 0, function* () {
1455 const ngModuleFactory = yield this.compileModuleAsync(moduleType);
1456 const componentFactories = this.testBed._getComponentFactories(moduleType);
1457 return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
1458 });
1459 }
1460 clearCache() { }
1461 clearCacheFor(type) { }
1462 getModuleId(moduleType) {
1463 const meta = this.testBed._getModuleResolver().resolve(moduleType);
1464 return meta && meta.id || undefined;
1465 }
1466}
1467
1468/**
1469 * @license
1470 * Copyright Google LLC All Rights Reserved.
1471 *
1472 * Use of this source code is governed by an MIT-style license that can be
1473 * found in the LICENSE file at https://angular.io/license
1474 */
1475/**
1476 * Whether test modules should be torn down by default.
1477 * Currently disabled for backwards-compatibility reasons.
1478 */
1479const TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT = false;
1480/**
1481 * An abstract class for inserting the root test component element in a platform independent way.
1482 *
1483 * @publicApi
1484 */
1485class TestComponentRenderer {
1486 insertRootElement(rootElementId) { }
1487 removeAllRootElements() { }
1488}
1489/**
1490 * @publicApi
1491 */
1492const ComponentFixtureAutoDetect = new InjectionToken('ComponentFixtureAutoDetect');
1493/**
1494 * @publicApi
1495 */
1496const ComponentFixtureNoNgZone = new InjectionToken('ComponentFixtureNoNgZone');
1497
1498/**
1499 * @license
1500 * Copyright Google LLC All Rights Reserved.
1501 *
1502 * Use of this source code is governed by an MIT-style license that can be
1503 * found in the LICENSE file at https://angular.io/license
1504 */
1505let _nextRootElementId = 0;
1506/**
1507 * @description
1508 * Configures and initializes environment for unit testing and provides methods for
1509 * creating components and services in unit tests.
1510 *
1511 * TestBed is the primary api for writing unit tests for Angular applications and libraries.
1512 *
1513 * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
1514 * according to the compiler used.
1515 */
1516class TestBedRender3 {
1517 constructor() {
1518 // Properties
1519 this.platform = null;
1520 this.ngModule = null;
1521 this._compiler = null;
1522 this._testModuleRef = null;
1523 this._activeFixtures = [];
1524 this._globalCompilationChecked = false;
1525 }
1526 /**
1527 * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
1528 * angular module. These are common to every test in the suite.
1529 *
1530 * This may only be called once, to set up the common providers for the current test
1531 * suite on the current platform. If you absolutely need to change the providers,
1532 * first use `resetTestEnvironment`.
1533 *
1534 * Test modules and platforms for individual platforms are available from
1535 * '@angular/<platform_name>/testing'.
1536 *
1537 * @publicApi
1538 */
1539 static initTestEnvironment(ngModule, platform, summariesOrOptions) {
1540 const testBed = _getTestBedRender3();
1541 testBed.initTestEnvironment(ngModule, platform, summariesOrOptions);
1542 return testBed;
1543 }
1544 /**
1545 * Reset the providers for the test injector.
1546 *
1547 * @publicApi
1548 */
1549 static resetTestEnvironment() {
1550 _getTestBedRender3().resetTestEnvironment();
1551 }
1552 static configureCompiler(config) {
1553 _getTestBedRender3().configureCompiler(config);
1554 return TestBedRender3;
1555 }
1556 /**
1557 * Allows overriding default providers, directives, pipes, modules of the test injector,
1558 * which are defined in test_injector.js
1559 */
1560 static configureTestingModule(moduleDef) {
1561 _getTestBedRender3().configureTestingModule(moduleDef);
1562 return TestBedRender3;
1563 }
1564 /**
1565 * Compile components with a `templateUrl` for the test's NgModule.
1566 * It is necessary to call this function
1567 * as fetching urls is asynchronous.
1568 */
1569 static compileComponents() {
1570 return _getTestBedRender3().compileComponents();
1571 }
1572 static overrideModule(ngModule, override) {
1573 _getTestBedRender3().overrideModule(ngModule, override);
1574 return TestBedRender3;
1575 }
1576 static overrideComponent(component, override) {
1577 _getTestBedRender3().overrideComponent(component, override);
1578 return TestBedRender3;
1579 }
1580 static overrideDirective(directive, override) {
1581 _getTestBedRender3().overrideDirective(directive, override);
1582 return TestBedRender3;
1583 }
1584 static overridePipe(pipe, override) {
1585 _getTestBedRender3().overridePipe(pipe, override);
1586 return TestBedRender3;
1587 }
1588 static overrideTemplate(component, template) {
1589 _getTestBedRender3().overrideComponent(component, { set: { template, templateUrl: null } });
1590 return TestBedRender3;
1591 }
1592 /**
1593 * Overrides the template of the given component, compiling the template
1594 * in the context of the TestingModule.
1595 *
1596 * Note: This works for JIT and AOTed components as well.
1597 */
1598 static overrideTemplateUsingTestingModule(component, template) {
1599 _getTestBedRender3().overrideTemplateUsingTestingModule(component, template);
1600 return TestBedRender3;
1601 }
1602 static overrideProvider(token, provider) {
1603 _getTestBedRender3().overrideProvider(token, provider);
1604 return TestBedRender3;
1605 }
1606 static inject(token, notFoundValue, flags) {
1607 return _getTestBedRender3().inject(token, notFoundValue, flags);
1608 }
1609 /** @deprecated from v9.0.0 use TestBed.inject */
1610 static get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
1611 return _getTestBedRender3().inject(token, notFoundValue, flags);
1612 }
1613 static createComponent(component) {
1614 return _getTestBedRender3().createComponent(component);
1615 }
1616 static resetTestingModule() {
1617 _getTestBedRender3().resetTestingModule();
1618 return TestBedRender3;
1619 }
1620 static shouldTearDownTestingModule() {
1621 return _getTestBedRender3().shouldTearDownTestingModule();
1622 }
1623 static tearDownTestingModule() {
1624 _getTestBedRender3().tearDownTestingModule();
1625 }
1626 /**
1627 * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
1628 * angular module. These are common to every test in the suite.
1629 *
1630 * This may only be called once, to set up the common providers for the current test
1631 * suite on the current platform. If you absolutely need to change the providers,
1632 * first use `resetTestEnvironment`.
1633 *
1634 * Test modules and platforms for individual platforms are available from
1635 * '@angular/<platform_name>/testing'.
1636 *
1637 * @publicApi
1638 */
1639 initTestEnvironment(ngModule, platform, summariesOrOptions) {
1640 if (this.platform || this.ngModule) {
1641 throw new Error('Cannot set base providers because it has already been called');
1642 }
1643 // If `summariesOrOptions` is a function, it means that it's
1644 // an AOT summaries factory which Ivy doesn't support.
1645 TestBedRender3._environmentTeardownOptions =
1646 typeof summariesOrOptions === 'function' ? undefined : summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.teardown;
1647 this.platform = platform;
1648 this.ngModule = ngModule;
1649 this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
1650 }
1651 /**
1652 * Reset the providers for the test injector.
1653 *
1654 * @publicApi
1655 */
1656 resetTestEnvironment() {
1657 this.resetTestingModule();
1658 this._compiler = null;
1659 this.platform = null;
1660 this.ngModule = null;
1661 TestBedRender3._environmentTeardownOptions = undefined;
1662 }
1663 resetTestingModule() {
1664 this.checkGlobalCompilationFinished();
1665 ɵresetCompiledComponents();
1666 if (this._compiler !== null) {
1667 this.compiler.restoreOriginalState();
1668 }
1669 this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
1670 // We have to chain a couple of try/finally blocks, because each step can
1671 // throw errors and we don't want it to interrupt the next step and we also
1672 // want an error to be thrown at the end.
1673 try {
1674 this.destroyActiveFixtures();
1675 }
1676 finally {
1677 try {
1678 if (this.shouldTearDownTestingModule()) {
1679 this.tearDownTestingModule();
1680 }
1681 }
1682 finally {
1683 this._testModuleRef = null;
1684 this._instanceTeardownOptions = undefined;
1685 }
1686 }
1687 }
1688 configureCompiler(config) {
1689 if (config.useJit != null) {
1690 throw new Error('the Render3 compiler JiT mode is not configurable !');
1691 }
1692 if (config.providers !== undefined) {
1693 this.compiler.setCompilerProviders(config.providers);
1694 }
1695 }
1696 configureTestingModule(moduleDef) {
1697 this.assertNotInstantiated('R3TestBed.configureTestingModule', 'configure the test module');
1698 // Always re-assign the teardown options, even if they're undefined.
1699 // This ensures that we don't carry the options between tests.
1700 this._instanceTeardownOptions = moduleDef.teardown;
1701 this.compiler.configureTestingModule(moduleDef);
1702 }
1703 compileComponents() {
1704 return this.compiler.compileComponents();
1705 }
1706 inject(token, notFoundValue, flags) {
1707 if (token === TestBedRender3) {
1708 return this;
1709 }
1710 const UNDEFINED = {};
1711 const result = this.testModuleRef.injector.get(token, UNDEFINED, flags);
1712 return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue, flags) :
1713 result;
1714 }
1715 /** @deprecated from v9.0.0 use TestBed.inject */
1716 get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
1717 return this.inject(token, notFoundValue, flags);
1718 }
1719 execute(tokens, fn, context) {
1720 const params = tokens.map(t => this.inject(t));
1721 return fn.apply(context, params);
1722 }
1723 overrideModule(ngModule, override) {
1724 this.assertNotInstantiated('overrideModule', 'override module metadata');
1725 this.compiler.overrideModule(ngModule, override);
1726 }
1727 overrideComponent(component, override) {
1728 this.assertNotInstantiated('overrideComponent', 'override component metadata');
1729 this.compiler.overrideComponent(component, override);
1730 }
1731 overrideTemplateUsingTestingModule(component, template) {
1732 this.assertNotInstantiated('R3TestBed.overrideTemplateUsingTestingModule', 'Cannot override template when the test module has already been instantiated');
1733 this.compiler.overrideTemplateUsingTestingModule(component, template);
1734 }
1735 overrideDirective(directive, override) {
1736 this.assertNotInstantiated('overrideDirective', 'override directive metadata');
1737 this.compiler.overrideDirective(directive, override);
1738 }
1739 overridePipe(pipe, override) {
1740 this.assertNotInstantiated('overridePipe', 'override pipe metadata');
1741 this.compiler.overridePipe(pipe, override);
1742 }
1743 /**
1744 * Overwrites all providers for the given token with the given provider definition.
1745 */
1746 overrideProvider(token, provider) {
1747 this.assertNotInstantiated('overrideProvider', 'override provider');
1748 this.compiler.overrideProvider(token, provider);
1749 }
1750 createComponent(type) {
1751 const testComponentRenderer = this.inject(TestComponentRenderer);
1752 const rootElId = `root${_nextRootElementId++}`;
1753 testComponentRenderer.insertRootElement(rootElId);
1754 const componentDef = type.ɵcmp;
1755 if (!componentDef) {
1756 throw new Error(`It looks like '${ɵstringify(type)}' has not been IVY compiled - it has no 'ɵcmp' field`);
1757 }
1758 // TODO: Don't cast as `InjectionToken<boolean>`, proper type is boolean[]
1759 const noNgZone = this.inject(ComponentFixtureNoNgZone, false);
1760 // TODO: Don't cast as `InjectionToken<boolean>`, proper type is boolean[]
1761 const autoDetect = this.inject(ComponentFixtureAutoDetect, false);
1762 const ngZone = noNgZone ? null : this.inject(NgZone, null);
1763 const componentFactory = new ɵRender3ComponentFactory(componentDef);
1764 const initComponent = () => {
1765 const componentRef = componentFactory.create(Injector.NULL, [], `#${rootElId}`, this.testModuleRef);
1766 return new ComponentFixture(componentRef, ngZone, autoDetect);
1767 };
1768 const fixture = ngZone ? ngZone.run(initComponent) : initComponent();
1769 this._activeFixtures.push(fixture);
1770 return fixture;
1771 }
1772 /**
1773 * @internal strip this from published d.ts files due to
1774 * https://github.com/microsoft/TypeScript/issues/36216
1775 */
1776 get compiler() {
1777 if (this._compiler === null) {
1778 throw new Error(`Need to call TestBed.initTestEnvironment() first`);
1779 }
1780 return this._compiler;
1781 }
1782 /**
1783 * @internal strip this from published d.ts files due to
1784 * https://github.com/microsoft/TypeScript/issues/36216
1785 */
1786 get testModuleRef() {
1787 if (this._testModuleRef === null) {
1788 this._testModuleRef = this.compiler.finalize();
1789 }
1790 return this._testModuleRef;
1791 }
1792 assertNotInstantiated(methodName, methodDescription) {
1793 if (this._testModuleRef !== null) {
1794 throw new Error(`Cannot ${methodDescription} when the test module has already been instantiated. ` +
1795 `Make sure you are not using \`inject\` before \`${methodName}\`.`);
1796 }
1797 }
1798 /**
1799 * Check whether the module scoping queue should be flushed, and flush it if needed.
1800 *
1801 * When the TestBed is reset, it clears the JIT module compilation queue, cancelling any
1802 * in-progress module compilation. This creates a potential hazard - the very first time the
1803 * TestBed is initialized (or if it's reset without being initialized), there may be pending
1804 * compilations of modules declared in global scope. These compilations should be finished.
1805 *
1806 * To ensure that globally declared modules have their components scoped properly, this function
1807 * is called whenever TestBed is initialized or reset. The _first_ time that this happens, prior
1808 * to any other operations, the scoping queue is flushed.
1809 */
1810 checkGlobalCompilationFinished() {
1811 // Checking _testNgModuleRef is null should not be necessary, but is left in as an additional
1812 // guard that compilations queued in tests (after instantiation) are never flushed accidentally.
1813 if (!this._globalCompilationChecked && this._testModuleRef === null) {
1814 ɵflushModuleScopingQueueAsMuchAsPossible();
1815 }
1816 this._globalCompilationChecked = true;
1817 }
1818 destroyActiveFixtures() {
1819 let errorCount = 0;
1820 this._activeFixtures.forEach((fixture) => {
1821 try {
1822 fixture.destroy();
1823 }
1824 catch (e) {
1825 errorCount++;
1826 console.error('Error during cleanup of component', {
1827 component: fixture.componentInstance,
1828 stacktrace: e,
1829 });
1830 }
1831 });
1832 this._activeFixtures = [];
1833 if (errorCount > 0 && this.shouldRethrowTeardownErrors()) {
1834 throw Error(`${errorCount} ${(errorCount === 1 ? 'component' : 'components')} ` +
1835 `threw errors during cleanup`);
1836 }
1837 }
1838 shouldRethrowTeardownErrors() {
1839 var _a, _b;
1840 const instanceOptions = this._instanceTeardownOptions;
1841 const environmentOptions = TestBedRender3._environmentTeardownOptions;
1842 // If the new teardown behavior hasn't been configured, preserve the old behavior.
1843 if (!instanceOptions && !environmentOptions) {
1844 return false;
1845 }
1846 // Otherwise use the configured behavior or default to rethrowing.
1847 return (_b = (_a = instanceOptions === null || instanceOptions === void 0 ? void 0 : instanceOptions.rethrowErrors) !== null && _a !== void 0 ? _a : environmentOptions === null || environmentOptions === void 0 ? void 0 : environmentOptions.rethrowErrors) !== null && _b !== void 0 ? _b : true;
1848 }
1849 shouldTearDownTestingModule() {
1850 var _a, _b, _c, _d;
1851 return (_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.destroyAfterEach) !== null && _b !== void 0 ? _b : (_c = TestBedRender3._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.destroyAfterEach) !== null && _d !== void 0 ? _d : TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT;
1852 }
1853 tearDownTestingModule() {
1854 var _a;
1855 // If the module ref has already been destroyed, we won't be able to get a test renderer.
1856 if (this._testModuleRef === null) {
1857 return;
1858 }
1859 // Resolve the renderer ahead of time, because we want to remove the root elements as the very
1860 // last step, but the injector will be destroyed as a part of the module ref destruction.
1861 const testRenderer = this.inject(TestComponentRenderer);
1862 try {
1863 this._testModuleRef.destroy();
1864 }
1865 catch (e) {
1866 if (this.shouldRethrowTeardownErrors()) {
1867 throw e;
1868 }
1869 else {
1870 console.error('Error during cleanup of a testing module', {
1871 component: this._testModuleRef.instance,
1872 stacktrace: e,
1873 });
1874 }
1875 }
1876 finally {
1877 (_a = testRenderer.removeAllRootElements) === null || _a === void 0 ? void 0 : _a.call(testRenderer);
1878 }
1879 }
1880}
1881let testBed;
1882function _getTestBedRender3() {
1883 return testBed = testBed || new TestBedRender3();
1884}
1885
1886/**
1887 * @license
1888 * Copyright Google LLC All Rights Reserved.
1889 *
1890 * Use of this source code is governed by an MIT-style license that can be
1891 * found in the LICENSE file at https://angular.io/license
1892 */
1893function unimplemented() {
1894 throw Error('unimplemented');
1895}
1896/**
1897 * Special interface to the compiler only used by testing
1898 *
1899 * @publicApi
1900 */
1901class TestingCompiler extends Compiler {
1902 get injector() {
1903 throw unimplemented();
1904 }
1905 overrideModule(module, overrides) {
1906 throw unimplemented();
1907 }
1908 overrideDirective(directive, overrides) {
1909 throw unimplemented();
1910 }
1911 overrideComponent(component, overrides) {
1912 throw unimplemented();
1913 }
1914 overridePipe(directive, overrides) {
1915 throw unimplemented();
1916 }
1917 /**
1918 * Allows to pass the compile summary from AOT compilation to the JIT compiler,
1919 * so that it can use the code generated by AOT.
1920 */
1921 loadAotSummaries(summaries) {
1922 throw unimplemented();
1923 }
1924 /**
1925 * Gets the component factory for the given component.
1926 * This assumes that the component has been compiled before calling this call using
1927 * `compileModuleAndAllComponents*`.
1928 */
1929 getComponentFactory(component) {
1930 throw unimplemented();
1931 }
1932 /**
1933 * Returns the component type that is stored in the given error.
1934 * This can be used for errors created by compileModule...
1935 */
1936 getComponentFromError(error) {
1937 throw unimplemented();
1938 }
1939}
1940TestingCompiler.decorators = [
1941 { type: Injectable }
1942];
1943/**
1944 * A factory for creating a Compiler
1945 *
1946 * @publicApi
1947 */
1948class TestingCompilerFactory {
1949}
1950
1951/**
1952 * @license
1953 * Copyright Google LLC All Rights Reserved.
1954 *
1955 * Use of this source code is governed by an MIT-style license that can be
1956 * found in the LICENSE file at https://angular.io/license
1957 */
1958let _nextRootElementId$1 = 0;
1959/**
1960 * @description
1961 * Configures and initializes environment for unit testing and provides methods for
1962 * creating components and services in unit tests.
1963 *
1964 * `TestBed` is the primary api for writing unit tests for Angular applications and libraries.
1965 *
1966 * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
1967 * according to the compiler used.
1968 */
1969class TestBedViewEngine {
1970 constructor() {
1971 this._instantiated = false;
1972 this._compiler = null;
1973 this._moduleRef = null;
1974 this._moduleFactory = null;
1975 this._pendingModuleFactory = null;
1976 this._compilerOptions = [];
1977 this._moduleOverrides = [];
1978 this._componentOverrides = [];
1979 this._directiveOverrides = [];
1980 this._pipeOverrides = [];
1981 this._providers = [];
1982 this._declarations = [];
1983 this._imports = [];
1984 this._schemas = [];
1985 this._activeFixtures = [];
1986 this._testEnvAotSummaries = () => [];
1987 this._aotSummaries = [];
1988 this._templateOverrides = [];
1989 this._isRoot = true;
1990 this._rootProviderOverrides = [];
1991 this.platform = null;
1992 this.ngModule = null;
1993 }
1994 /**
1995 * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
1996 * angular module. These are common to every test in the suite.
1997 *
1998 * This may only be called once, to set up the common providers for the current test
1999 * suite on the current platform. If you absolutely need to change the providers,
2000 * first use `resetTestEnvironment`.
2001 *
2002 * Test modules and platforms for individual platforms are available from
2003 * '@angular/<platform_name>/testing'.
2004 */
2005 static initTestEnvironment(ngModule, platform, summariesOrOptions) {
2006 const testBed = _getTestBedViewEngine();
2007 testBed.initTestEnvironment(ngModule, platform, summariesOrOptions);
2008 return testBed;
2009 }
2010 /**
2011 * Reset the providers for the test injector.
2012 */
2013 static resetTestEnvironment() {
2014 _getTestBedViewEngine().resetTestEnvironment();
2015 }
2016 static resetTestingModule() {
2017 _getTestBedViewEngine().resetTestingModule();
2018 return TestBedViewEngine;
2019 }
2020 /**
2021 * Allows overriding default compiler providers and settings
2022 * which are defined in test_injector.js
2023 */
2024 static configureCompiler(config) {
2025 _getTestBedViewEngine().configureCompiler(config);
2026 return TestBedViewEngine;
2027 }
2028 /**
2029 * Allows overriding default providers, directives, pipes, modules of the test injector,
2030 * which are defined in test_injector.js
2031 */
2032 static configureTestingModule(moduleDef) {
2033 _getTestBedViewEngine().configureTestingModule(moduleDef);
2034 return TestBedViewEngine;
2035 }
2036 /**
2037 * Compile components with a `templateUrl` for the test's NgModule.
2038 * It is necessary to call this function
2039 * as fetching urls is asynchronous.
2040 */
2041 static compileComponents() {
2042 return getTestBed().compileComponents();
2043 }
2044 static overrideModule(ngModule, override) {
2045 _getTestBedViewEngine().overrideModule(ngModule, override);
2046 return TestBedViewEngine;
2047 }
2048 static overrideComponent(component, override) {
2049 _getTestBedViewEngine().overrideComponent(component, override);
2050 return TestBedViewEngine;
2051 }
2052 static overrideDirective(directive, override) {
2053 _getTestBedViewEngine().overrideDirective(directive, override);
2054 return TestBedViewEngine;
2055 }
2056 static overridePipe(pipe, override) {
2057 _getTestBedViewEngine().overridePipe(pipe, override);
2058 return TestBedViewEngine;
2059 }
2060 static overrideTemplate(component, template) {
2061 _getTestBedViewEngine().overrideComponent(component, { set: { template, templateUrl: null } });
2062 return TestBedViewEngine;
2063 }
2064 /**
2065 * Overrides the template of the given component, compiling the template
2066 * in the context of the TestingModule.
2067 *
2068 * Note: This works for JIT and AOTed components as well.
2069 */
2070 static overrideTemplateUsingTestingModule(component, template) {
2071 _getTestBedViewEngine().overrideTemplateUsingTestingModule(component, template);
2072 return TestBedViewEngine;
2073 }
2074 static overrideProvider(token, provider) {
2075 _getTestBedViewEngine().overrideProvider(token, provider);
2076 return TestBedViewEngine;
2077 }
2078 static inject(token, notFoundValue, flags) {
2079 return _getTestBedViewEngine().inject(token, notFoundValue, flags);
2080 }
2081 /** @deprecated from v9.0.0 use TestBed.inject */
2082 static get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
2083 return _getTestBedViewEngine().inject(token, notFoundValue, flags);
2084 }
2085 static createComponent(component) {
2086 return _getTestBedViewEngine().createComponent(component);
2087 }
2088 static shouldTearDownTestingModule() {
2089 return _getTestBedViewEngine().shouldTearDownTestingModule();
2090 }
2091 static tearDownTestingModule() {
2092 _getTestBedViewEngine().tearDownTestingModule();
2093 }
2094 /**
2095 * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
2096 * angular module. These are common to every test in the suite.
2097 *
2098 * This may only be called once, to set up the common providers for the current test
2099 * suite on the current platform. If you absolutely need to change the providers,
2100 * first use `resetTestEnvironment`.
2101 *
2102 * Test modules and platforms for individual platforms are available from
2103 * '@angular/<platform_name>/testing'.
2104 */
2105 initTestEnvironment(ngModule, platform, summariesOrOptions) {
2106 if (this.platform || this.ngModule) {
2107 throw new Error('Cannot set base providers because it has already been called');
2108 }
2109 this.platform = platform;
2110 this.ngModule = ngModule;
2111 if (typeof summariesOrOptions === 'function') {
2112 this._testEnvAotSummaries = summariesOrOptions;
2113 TestBedViewEngine._environmentTeardownOptions = undefined;
2114 }
2115 else {
2116 this._testEnvAotSummaries = (summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.aotSummaries) || (() => []);
2117 TestBedViewEngine._environmentTeardownOptions = summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.teardown;
2118 }
2119 }
2120 /**
2121 * Reset the providers for the test injector.
2122 */
2123 resetTestEnvironment() {
2124 this.resetTestingModule();
2125 this.platform = null;
2126 this.ngModule = null;
2127 this._testEnvAotSummaries = () => [];
2128 TestBedViewEngine._environmentTeardownOptions = undefined;
2129 }
2130 resetTestingModule() {
2131 ɵclearOverrides();
2132 this._aotSummaries = [];
2133 this._templateOverrides = [];
2134 this._compiler = null;
2135 this._moduleOverrides = [];
2136 this._componentOverrides = [];
2137 this._directiveOverrides = [];
2138 this._pipeOverrides = [];
2139 this._isRoot = true;
2140 this._rootProviderOverrides = [];
2141 this._moduleFactory = null;
2142 this._pendingModuleFactory = null;
2143 this._compilerOptions = [];
2144 this._providers = [];
2145 this._declarations = [];
2146 this._imports = [];
2147 this._schemas = [];
2148 // We have to chain a couple of try/finally blocks, because each step can
2149 // throw errors and we don't want it to interrupt the next step and we also
2150 // want an error to be thrown at the end.
2151 try {
2152 this.destroyActiveFixtures();
2153 }
2154 finally {
2155 try {
2156 if (this.shouldTearDownTestingModule()) {
2157 this.tearDownTestingModule();
2158 }
2159 }
2160 finally {
2161 this._moduleRef = null;
2162 this._instanceTeardownOptions = undefined;
2163 this._instantiated = false;
2164 }
2165 }
2166 }
2167 configureCompiler(config) {
2168 this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler');
2169 this._compilerOptions.push(config);
2170 }
2171 configureTestingModule(moduleDef) {
2172 this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module');
2173 if (moduleDef.providers) {
2174 this._providers.push(...moduleDef.providers);
2175 }
2176 if (moduleDef.declarations) {
2177 this._declarations.push(...moduleDef.declarations);
2178 }
2179 if (moduleDef.imports) {
2180 this._imports.push(...moduleDef.imports);
2181 }
2182 if (moduleDef.schemas) {
2183 this._schemas.push(...moduleDef.schemas);
2184 }
2185 if (moduleDef.aotSummaries) {
2186 this._aotSummaries.push(moduleDef.aotSummaries);
2187 }
2188 // Always re-assign the teardown options, even if they're undefined.
2189 // This ensures that we don't carry the options between tests.
2190 this._instanceTeardownOptions = moduleDef.teardown;
2191 }
2192 compileComponents() {
2193 if (this._moduleFactory || this._instantiated) {
2194 return Promise.resolve(null);
2195 }
2196 const moduleType = this._createCompilerAndModule();
2197 this._pendingModuleFactory = moduleType;
2198 return this._compiler.compileModuleAndAllComponentsAsync(moduleType).then(result => {
2199 // If the module mismatches by the time the promise resolves, it means that the module has
2200 // already been destroyed and a new compilation has started. If that's the case, avoid
2201 // overwriting the module factory, because it can cause downstream errors.
2202 if (this._pendingModuleFactory === moduleType) {
2203 this._moduleFactory = result.ngModuleFactory;
2204 this._pendingModuleFactory = null;
2205 }
2206 });
2207 }
2208 _initIfNeeded() {
2209 if (this._instantiated) {
2210 return;
2211 }
2212 if (!this._moduleFactory) {
2213 try {
2214 const moduleType = this._createCompilerAndModule();
2215 this._moduleFactory =
2216 this._compiler.compileModuleAndAllComponentsSync(moduleType).ngModuleFactory;
2217 }
2218 catch (e) {
2219 const errorCompType = this._compiler.getComponentFromError(e);
2220 if (errorCompType) {
2221 throw new Error(`This test module uses the component ${ɵstringify(errorCompType)} which is using a "templateUrl" or "styleUrls", but they were never compiled. ` +
2222 `Please call "TestBed.compileComponents" before your test.`);
2223 }
2224 else {
2225 throw e;
2226 }
2227 }
2228 }
2229 for (const { component, templateOf } of this._templateOverrides) {
2230 const compFactory = this._compiler.getComponentFactory(templateOf);
2231 ɵoverrideComponentView(component, compFactory);
2232 }
2233 const ngZone = new NgZone({ enableLongStackTrace: true, shouldCoalesceEventChangeDetection: false });
2234 const providers = [{ provide: NgZone, useValue: ngZone }];
2235 const ngZoneInjector = Injector.create({
2236 providers: providers,
2237 parent: this.platform.injector,
2238 name: this._moduleFactory.moduleType.name
2239 });
2240 this._moduleRef = this._moduleFactory.create(ngZoneInjector);
2241 // ApplicationInitStatus.runInitializers() is marked @internal to core. So casting to any
2242 // before accessing it.
2243 this._moduleRef.injector.get(ApplicationInitStatus).runInitializers();
2244 this._instantiated = true;
2245 }
2246 _createCompilerAndModule() {
2247 const providers = this._providers.concat([{ provide: TestBed, useValue: this }]);
2248 const declarations = [...this._declarations, ...this._templateOverrides.map(entry => entry.templateOf)];
2249 const rootScopeImports = [];
2250 const rootProviderOverrides = this._rootProviderOverrides;
2251 if (this._isRoot) {
2252 class RootScopeModule {
2253 }
2254 RootScopeModule.decorators = [
2255 { type: NgModule, args: [{
2256 providers: [
2257 ...rootProviderOverrides,
2258 ],
2259 jit: true,
2260 },] }
2261 ];
2262 rootScopeImports.push(RootScopeModule);
2263 }
2264 providers.push({ provide: ɵINJECTOR_SCOPE, useValue: this._isRoot ? 'root' : null });
2265 const imports = [rootScopeImports, this.ngModule, this._imports];
2266 const schemas = this._schemas;
2267 class DynamicTestModule {
2268 }
2269 DynamicTestModule.decorators = [
2270 { type: NgModule, args: [{ providers, declarations, imports, schemas, jit: true },] }
2271 ];
2272 const compilerFactory = this.platform.injector.get(TestingCompilerFactory);
2273 this._compiler = compilerFactory.createTestingCompiler(this._compilerOptions);
2274 for (const summary of [this._testEnvAotSummaries, ...this._aotSummaries]) {
2275 this._compiler.loadAotSummaries(summary);
2276 }
2277 this._moduleOverrides.forEach((entry) => this._compiler.overrideModule(entry[0], entry[1]));
2278 this._componentOverrides.forEach((entry) => this._compiler.overrideComponent(entry[0], entry[1]));
2279 this._directiveOverrides.forEach((entry) => this._compiler.overrideDirective(entry[0], entry[1]));
2280 this._pipeOverrides.forEach((entry) => this._compiler.overridePipe(entry[0], entry[1]));
2281 return DynamicTestModule;
2282 }
2283 _assertNotInstantiated(methodName, methodDescription) {
2284 if (this._instantiated) {
2285 throw new Error(`Cannot ${methodDescription} when the test module has already been instantiated. ` +
2286 `Make sure you are not using \`inject\` before \`${methodName}\`.`);
2287 }
2288 }
2289 inject(token, notFoundValue, flags) {
2290 this._initIfNeeded();
2291 if (token === TestBed) {
2292 return this;
2293 }
2294 // Tests can inject things from the ng module and from the compiler,
2295 // but the ng module can't inject things from the compiler and vice versa.
2296 const UNDEFINED = {};
2297 const result = this._moduleRef.injector.get(token, UNDEFINED, flags);
2298 return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue, flags) :
2299 result;
2300 }
2301 /** @deprecated from v9.0.0 use TestBed.inject */
2302 get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
2303 return this.inject(token, notFoundValue, flags);
2304 }
2305 execute(tokens, fn, context) {
2306 this._initIfNeeded();
2307 const params = tokens.map(t => this.inject(t));
2308 return fn.apply(context, params);
2309 }
2310 overrideModule(ngModule, override) {
2311 this._assertNotInstantiated('overrideModule', 'override module metadata');
2312 this._moduleOverrides.push([ngModule, override]);
2313 }
2314 overrideComponent(component, override) {
2315 this._assertNotInstantiated('overrideComponent', 'override component metadata');
2316 this._componentOverrides.push([component, override]);
2317 }
2318 overrideDirective(directive, override) {
2319 this._assertNotInstantiated('overrideDirective', 'override directive metadata');
2320 this._directiveOverrides.push([directive, override]);
2321 }
2322 overridePipe(pipe, override) {
2323 this._assertNotInstantiated('overridePipe', 'override pipe metadata');
2324 this._pipeOverrides.push([pipe, override]);
2325 }
2326 overrideProvider(token, provider) {
2327 this._assertNotInstantiated('overrideProvider', 'override provider');
2328 this.overrideProviderImpl(token, provider);
2329 }
2330 overrideProviderImpl(token, provider, deprecated = false) {
2331 let def = null;
2332 if (typeof token !== 'string' && (def = ɵgetInjectableDef(token)) && def.providedIn === 'root') {
2333 if (provider.useFactory) {
2334 this._rootProviderOverrides.push({ provide: token, useFactory: provider.useFactory, deps: provider.deps || [] });
2335 }
2336 else {
2337 this._rootProviderOverrides.push({ provide: token, useValue: provider.useValue });
2338 }
2339 }
2340 let flags = 0;
2341 let value;
2342 if (provider.useFactory) {
2343 flags |= 1024 /* TypeFactoryProvider */;
2344 value = provider.useFactory;
2345 }
2346 else {
2347 flags |= 256 /* TypeValueProvider */;
2348 value = provider.useValue;
2349 }
2350 const deps = (provider.deps || []).map((dep) => {
2351 let depFlags = 0 /* None */;
2352 let depToken;
2353 if (Array.isArray(dep)) {
2354 dep.forEach((entry) => {
2355 if (entry instanceof Optional) {
2356 depFlags |= 2 /* Optional */;
2357 }
2358 else if (entry instanceof SkipSelf) {
2359 depFlags |= 1 /* SkipSelf */;
2360 }
2361 else {
2362 depToken = entry;
2363 }
2364 });
2365 }
2366 else {
2367 depToken = dep;
2368 }
2369 return [depFlags, depToken];
2370 });
2371 ɵoverrideProvider({ token, flags, deps, value, deprecatedBehavior: deprecated });
2372 }
2373 overrideTemplateUsingTestingModule(component, template) {
2374 this._assertNotInstantiated('overrideTemplateUsingTestingModule', 'override template');
2375 class OverrideComponent {
2376 }
2377 OverrideComponent.decorators = [
2378 { type: Component, args: [{ selector: 'empty', template, jit: true },] }
2379 ];
2380 this._templateOverrides.push({ component, templateOf: OverrideComponent });
2381 }
2382 createComponent(component) {
2383 this._initIfNeeded();
2384 const componentFactory = this._compiler.getComponentFactory(component);
2385 if (!componentFactory) {
2386 throw new Error(`Cannot create the component ${ɵstringify(component)} as it was not imported into the testing module!`);
2387 }
2388 // TODO: Don't cast as `InjectionToken<boolean>`, declared type is boolean[]
2389 const noNgZone = this.inject(ComponentFixtureNoNgZone, false);
2390 // TODO: Don't cast as `InjectionToken<boolean>`, declared type is boolean[]
2391 const autoDetect = this.inject(ComponentFixtureAutoDetect, false);
2392 const ngZone = noNgZone ? null : this.inject(NgZone, null);
2393 const testComponentRenderer = this.inject(TestComponentRenderer);
2394 const rootElId = `root${_nextRootElementId$1++}`;
2395 testComponentRenderer.insertRootElement(rootElId);
2396 const initComponent = () => {
2397 const componentRef = componentFactory.create(Injector.NULL, [], `#${rootElId}`, this._moduleRef);
2398 return new ComponentFixture(componentRef, ngZone, autoDetect);
2399 };
2400 const fixture = !ngZone ? initComponent() : ngZone.run(initComponent);
2401 this._activeFixtures.push(fixture);
2402 return fixture;
2403 }
2404 destroyActiveFixtures() {
2405 let errorCount = 0;
2406 this._activeFixtures.forEach((fixture) => {
2407 try {
2408 fixture.destroy();
2409 }
2410 catch (e) {
2411 errorCount++;
2412 console.error('Error during cleanup of component', {
2413 component: fixture.componentInstance,
2414 stacktrace: e,
2415 });
2416 }
2417 });
2418 this._activeFixtures = [];
2419 if (errorCount > 0 && this.shouldRethrowTeardownErrors()) {
2420 throw Error(`${errorCount} ${(errorCount === 1 ? 'component' : 'components')} ` +
2421 `threw errors during cleanup`);
2422 }
2423 }
2424 shouldRethrowTeardownErrors() {
2425 var _a, _b;
2426 const instanceOptions = this._instanceTeardownOptions;
2427 const environmentOptions = TestBedViewEngine._environmentTeardownOptions;
2428 // If the new teardown behavior hasn't been configured, preserve the old behavior.
2429 if (!instanceOptions && !environmentOptions) {
2430 return false;
2431 }
2432 // Otherwise use the configured behavior or default to rethrowing.
2433 return (_b = (_a = instanceOptions === null || instanceOptions === void 0 ? void 0 : instanceOptions.rethrowErrors) !== null && _a !== void 0 ? _a : environmentOptions === null || environmentOptions === void 0 ? void 0 : environmentOptions.rethrowErrors) !== null && _b !== void 0 ? _b : true;
2434 }
2435 shouldTearDownTestingModule() {
2436 var _a, _b, _c, _d;
2437 return (_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.destroyAfterEach) !== null && _b !== void 0 ? _b : (_c = TestBedViewEngine._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.destroyAfterEach) !== null && _d !== void 0 ? _d : TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT;
2438 }
2439 tearDownTestingModule() {
2440 var _a, _b, _c, _d, _e;
2441 // If the module ref has already been destroyed, we won't be able to get a test renderer.
2442 if (this._moduleRef === null) {
2443 return;
2444 }
2445 // Resolve the renderer ahead of time, because we want to remove the root elements as the very
2446 // last step, but the injector will be destroyed as a part of the module ref destruction.
2447 const testRenderer = this.inject(TestComponentRenderer);
2448 try {
2449 this._moduleRef.destroy();
2450 }
2451 catch (e) {
2452 if ((_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.rethrowErrors) !== null && _b !== void 0 ? _b : (_c = TestBedViewEngine._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.rethrowErrors) !== null && _d !== void 0 ? _d : true) {
2453 throw e;
2454 }
2455 else {
2456 console.error('Error during cleanup of a testing module', {
2457 component: this._moduleRef.instance,
2458 stacktrace: e,
2459 });
2460 }
2461 }
2462 finally {
2463 (_e = testRenderer === null || testRenderer === void 0 ? void 0 : testRenderer.removeAllRootElements) === null || _e === void 0 ? void 0 : _e.call(testRenderer);
2464 }
2465 }
2466}
2467/**
2468 * @description
2469 * Configures and initializes environment for unit testing and provides methods for
2470 * creating components and services in unit tests.
2471 *
2472 * `TestBed` is the primary api for writing unit tests for Angular applications and libraries.
2473 *
2474 * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
2475 * according to the compiler used.
2476 *
2477 * @publicApi
2478 */
2479const TestBed = ɵivyEnabled ? TestBedRender3 : TestBedViewEngine;
2480/**
2481 * Returns a singleton of the applicable `TestBed`.
2482 *
2483 * It will be either an instance of `TestBedViewEngine` or `TestBedRender3`.
2484 *
2485 * @publicApi
2486 */
2487const getTestBed = ɵivyEnabled ? _getTestBedRender3 : _getTestBedViewEngine;
2488let testBed$1;
2489function _getTestBedViewEngine() {
2490 return testBed$1 = testBed$1 || new TestBedViewEngine();
2491}
2492/**
2493 * Allows injecting dependencies in `beforeEach()` and `it()`.
2494 *
2495 * Example:
2496 *
2497 * ```
2498 * beforeEach(inject([Dependency, AClass], (dep, object) => {
2499 * // some code that uses `dep` and `object`
2500 * // ...
2501 * }));
2502 *
2503 * it('...', inject([AClass], (object) => {
2504 * object.doSomething();
2505 * expect(...);
2506 * })
2507 * ```
2508 *
2509 * @publicApi
2510 */
2511function inject(tokens, fn) {
2512 const testBed = getTestBed();
2513 // Not using an arrow function to preserve context passed from call site
2514 return function () {
2515 return testBed.execute(tokens, fn, this);
2516 };
2517}
2518/**
2519 * @publicApi
2520 */
2521class InjectSetupWrapper {
2522 constructor(_moduleDef) {
2523 this._moduleDef = _moduleDef;
2524 }
2525 _addModule() {
2526 const moduleDef = this._moduleDef();
2527 if (moduleDef) {
2528 getTestBed().configureTestingModule(moduleDef);
2529 }
2530 }
2531 inject(tokens, fn) {
2532 const self = this;
2533 // Not using an arrow function to preserve context passed from call site
2534 return function () {
2535 self._addModule();
2536 return inject(tokens, fn).call(this);
2537 };
2538 }
2539}
2540function withModule(moduleDef, fn) {
2541 if (fn) {
2542 // Not using an arrow function to preserve context passed from call site
2543 return function () {
2544 const testBed = getTestBed();
2545 if (moduleDef) {
2546 testBed.configureTestingModule(moduleDef);
2547 }
2548 return fn.apply(this);
2549 };
2550 }
2551 return new InjectSetupWrapper(() => moduleDef);
2552}
2553
2554/**
2555 * @license
2556 * Copyright Google LLC All Rights Reserved.
2557 *
2558 * Use of this source code is governed by an MIT-style license that can be
2559 * found in the LICENSE file at https://angular.io/license
2560 */
2561const _global = (typeof window === 'undefined' ? global : window);
2562// Reset the test providers and the fake async zone before each test.
2563if (_global.beforeEach) {
2564 _global.beforeEach(getCleanupHook(false));
2565}
2566// We provide both a `beforeEach` and `afterEach`, because the updated behavior for
2567// tearing down the module is supposed to run after the test so that we can associate
2568// teardown errors with the correct test.
2569if (_global.afterEach) {
2570 _global.afterEach(getCleanupHook(true));
2571}
2572function getCleanupHook(expectedTeardownValue) {
2573 return () => {
2574 if (TestBed.shouldTearDownTestingModule() ===
2575 expectedTeardownValue) {
2576 TestBed.resetTestingModule();
2577 resetFakeAsyncZone();
2578 }
2579 };
2580}
2581/**
2582 * This API should be removed. But doing so seems to break `google3` and so it requires a bit of
2583 * investigation.
2584 *
2585 * A work around is to mark it as `@codeGenApi` for now and investigate later.
2586 *
2587 * @codeGenApi
2588 */
2589// TODO(iminar): Remove this code in a safe way.
2590const __core_private_testing_placeholder__ = '';
2591
2592/**
2593 * @license
2594 * Copyright Google LLC All Rights Reserved.
2595 *
2596 * Use of this source code is governed by an MIT-style license that can be
2597 * found in the LICENSE file at https://angular.io/license
2598 */
2599
2600/**
2601 * @license
2602 * Copyright Google LLC All Rights Reserved.
2603 *
2604 * Use of this source code is governed by an MIT-style license that can be
2605 * found in the LICENSE file at https://angular.io/license
2606 */
2607
2608/**
2609 * @license
2610 * Copyright Google LLC All Rights Reserved.
2611 *
2612 * Use of this source code is governed by an MIT-style license that can be
2613 * found in the LICENSE file at https://angular.io/license
2614 */
2615
2616/**
2617 * @license
2618 * Copyright Google LLC All Rights Reserved.
2619 *
2620 * Use of this source code is governed by an MIT-style license that can be
2621 * found in the LICENSE file at https://angular.io/license
2622 */
2623// This file only reexports content of the `src` folder. Keep it that way.
2624
2625/**
2626 * @license
2627 * Copyright Google LLC All Rights Reserved.
2628 *
2629 * Use of this source code is governed by an MIT-style license that can be
2630 * found in the LICENSE file at https://angular.io/license
2631 */
2632
2633/**
2634 * Generated bundle index. Do not edit.
2635 */
2636
2637export { ComponentFixture, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, InjectSetupWrapper, TestBed, TestComponentRenderer, __core_private_testing_placeholder__, async, discardPeriodicTasks, fakeAsync, flush, flushMicrotasks, getTestBed, inject, resetFakeAsyncZone, tick, waitForAsync, withModule, MetadataOverrider as ɵMetadataOverrider, TestingCompiler as ɵTestingCompiler, TestingCompilerFactory as ɵTestingCompilerFactory, TestBedViewEngine as ɵangular_packages_core_testing_testing_a, TestBedRender3 as ɵangular_packages_core_testing_testing_b, _getTestBedRender3 as ɵangular_packages_core_testing_testing_c };
2638//# sourceMappingURL=testing.js.map
Note: See TracBrowser for help on using the repository browser.