UNPKG

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