1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | import { 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';
|
8 | import { __awaiter } from 'tslib';
|
9 | import { ResourceLoader } from '@angular/compiler';
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | const _global = (typeof window === 'undefined' ? global : window);
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | function asyncFallback(fn) {
|
37 |
|
38 |
|
39 | if (_global.jasmine) {
|
40 |
|
41 | return function (done) {
|
42 | if (!done) {
|
43 |
|
44 |
|
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 |
|
61 |
|
62 |
|
63 |
|
64 | return function () {
|
65 | return new Promise((finishCallback, failCallback) => {
|
66 | runInTestZone(fn, this, finishCallback, failCallback);
|
67 | });
|
68 | };
|
69 | }
|
70 | function 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 |
|
85 |
|
86 | const proxyZone = Zone.current.getZoneWith('ProxyZoneSpec');
|
87 | const previousDelegate = proxyZoneSpec.getDelegate();
|
88 | proxyZone.parent.run(() => {
|
89 | const testZoneSpec = new AsyncTestZoneSpec(() => {
|
90 |
|
91 | currentZone.run(() => {
|
92 | if (proxyZoneSpec.getDelegate() == testZoneSpec) {
|
93 |
|
94 | proxyZoneSpec.setDelegate(previousDelegate);
|
95 | }
|
96 | finishCallback();
|
97 | });
|
98 | }, (error) => {
|
99 |
|
100 | currentZone.run(() => {
|
101 | if (proxyZoneSpec.getDelegate() == testZoneSpec) {
|
102 |
|
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 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | function 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 |
|
150 |
|
151 |
|
152 | return asyncFallback(fn);
|
153 | }
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | class 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 |
|
189 |
|
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 |
|
200 |
|
201 | this.detectChanges(true);
|
202 | }
|
203 | }
|
204 | });
|
205 | this._onStableSubscription = ngZone.onStable.subscribe({
|
206 | next: () => {
|
207 | this._isStable = true;
|
208 |
|
209 | if (this._promise !== null) {
|
210 |
|
211 |
|
212 |
|
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 |
|
241 |
|
242 | detectChanges(checkNoChanges = true) {
|
243 | if (this.ngZone != null) {
|
244 |
|
245 |
|
246 | this.ngZone.run(() => {
|
247 | this._tick(checkNoChanges);
|
248 | });
|
249 | }
|
250 | else {
|
251 |
|
252 | this._tick(checkNoChanges);
|
253 | }
|
254 | }
|
255 | |
256 |
|
257 |
|
258 | checkNoChanges() {
|
259 | this.changeDetectorRef.checkNoChanges();
|
260 | }
|
261 | |
262 |
|
263 |
|
264 |
|
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 |
|
275 |
|
276 |
|
277 | isStable() {
|
278 | return this._isStable && !this.ngZone.hasPendingMacrotasks;
|
279 | }
|
280 | |
281 |
|
282 |
|
283 |
|
284 |
|
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 |
|
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 |
|
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 | }
|
342 | function scheduleMicroTask(fn) {
|
343 | Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
|
344 | }
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 | const _Zone = typeof Zone !== 'undefined' ? Zone : null;
|
358 | const FakeAsyncTestZoneSpec = _Zone && _Zone['FakeAsyncTestZoneSpec'];
|
359 | const ProxyZoneSpec = _Zone && _Zone['ProxyZoneSpec'];
|
360 | let _fakeAsyncTestZoneSpec = null;
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 | function resetFakeAsyncZoneFallback() {
|
368 | if (_fakeAsyncTestZoneSpec) {
|
369 | _fakeAsyncTestZoneSpec.unlockDatePatch();
|
370 | }
|
371 | _fakeAsyncTestZoneSpec = null;
|
372 |
|
373 | ProxyZoneSpec && ProxyZoneSpec.assertPresent().resetDelegate();
|
374 | }
|
375 | let _inFakeAsyncCall = false;
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 | function fakeAsyncFallback(fn) {
|
396 |
|
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 | }
|
436 | function _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 |
|
444 |
|
445 |
|
446 |
|
447 |
|
448 |
|
449 |
|
450 |
|
451 |
|
452 |
|
453 |
|
454 |
|
455 | function tickFallback(millis = 0, tickOptions = {
|
456 | processNewMacroTasksSynchronously: true
|
457 | }) {
|
458 | _getFakeAsyncZoneSpec().tick(millis, null, tickOptions);
|
459 | }
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 | function flushFallback(maxTurns) {
|
471 | return _getFakeAsyncZoneSpec().flush(maxTurns);
|
472 | }
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 | function discardPeriodicTasksFallback() {
|
479 | const zoneSpec = _getFakeAsyncZoneSpec();
|
480 | zoneSpec.pendingPeriodicTimers.length = 0;
|
481 | }
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 | function flushMicrotasksFallback() {
|
488 | _getFakeAsyncZoneSpec().flushMicrotasks();
|
489 | }
|
490 |
|
491 |
|
492 |
|
493 |
|
494 |
|
495 |
|
496 |
|
497 |
|
498 | const _Zone$1 = typeof Zone !== 'undefined' ? Zone : null;
|
499 | const fakeAsyncTestModule = _Zone$1 && _Zone$1[_Zone$1.__symbol__('fakeAsyncTest')];
|
500 |
|
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 | function resetFakeAsyncZone() {
|
507 | if (fakeAsyncTestModule) {
|
508 | return fakeAsyncTestModule.resetFakeAsyncZone();
|
509 | }
|
510 | else {
|
511 | return resetFakeAsyncZoneFallback();
|
512 | }
|
513 | }
|
514 |
|
515 |
|
516 |
|
517 |
|
518 |
|
519 |
|
520 |
|
521 |
|
522 |
|
523 |
|
524 |
|
525 |
|
526 |
|
527 |
|
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 | function fakeAsync(fn) {
|
534 | if (fakeAsyncTestModule) {
|
535 | return fakeAsyncTestModule.fakeAsync(fn);
|
536 | }
|
537 | else {
|
538 | return fakeAsyncFallback(fn);
|
539 | }
|
540 | }
|
541 |
|
542 |
|
543 |
|
544 |
|
545 |
|
546 |
|
547 |
|
548 |
|
549 |
|
550 |
|
551 |
|
552 |
|
553 |
|
554 |
|
555 |
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 |
|
562 |
|
563 |
|
564 |
|
565 |
|
566 |
|
567 |
|
568 |
|
569 |
|
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 |
|
586 |
|
587 |
|
588 |
|
589 |
|
590 |
|
591 |
|
592 | function 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 |
|
604 |
|
605 |
|
606 |
|
607 |
|
608 |
|
609 |
|
610 |
|
611 |
|
612 | function flush(maxTurns) {
|
613 | if (fakeAsyncTestModule) {
|
614 | return fakeAsyncTestModule.flush(maxTurns);
|
615 | }
|
616 | else {
|
617 | return flushFallback(maxTurns);
|
618 | }
|
619 | }
|
620 |
|
621 |
|
622 |
|
623 |
|
624 |
|
625 | function discardPeriodicTasks() {
|
626 | if (fakeAsyncTestModule) {
|
627 | return fakeAsyncTestModule.discardPeriodicTasks();
|
628 | }
|
629 | else {
|
630 | discardPeriodicTasksFallback();
|
631 | }
|
632 | }
|
633 |
|
634 |
|
635 |
|
636 |
|
637 |
|
638 | function flushMicrotasks() {
|
639 | if (fakeAsyncTestModule) {
|
640 | return fakeAsyncTestModule.flushMicrotasks();
|
641 | }
|
642 | else {
|
643 | return flushMicrotasksFallback();
|
644 | }
|
645 | }
|
646 |
|
647 |
|
648 |
|
649 |
|
650 |
|
651 |
|
652 |
|
653 |
|
654 |
|
655 |
|
656 |
|
657 | class 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 |
|
677 |
|
678 |
|
679 |
|
680 |
|
681 |
|
682 |
|
683 |
|
684 |
|
685 |
|
686 |
|
687 |
|
688 |
|
689 |
|
690 |
|
691 |
|
692 |
|
693 |
|
694 |
|
695 |
|
696 |
|
697 |
|
698 |
|
699 |
|
700 |
|
701 |
|
702 |
|
703 |
|
704 |
|
705 |
|
706 |
|
707 |
|
708 |
|
709 |
|
710 |
|
711 |
|
712 |
|
713 |
|
714 | function resolveComponentResources(resourceResolver) {
|
715 |
|
716 | const componentResolved = [];
|
717 |
|
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('');
|
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 | }
|
753 | let componentResourceResolutionQueue = new Map();
|
754 |
|
755 | const componentDefPendingResolution = new Set();
|
756 | function maybeQueueResolutionOfComponentResources(type, metadata) {
|
757 | if (componentNeedsResolution(metadata)) {
|
758 | componentResourceResolutionQueue.set(type, metadata);
|
759 | componentDefPendingResolution.add(type);
|
760 | }
|
761 | }
|
762 | function isComponentDefPendingResolution(type) {
|
763 | return componentDefPendingResolution.has(type);
|
764 | }
|
765 | function componentNeedsResolution(component) {
|
766 | return !!((component.templateUrl && !component.hasOwnProperty('template')) ||
|
767 | component.styleUrls && component.styleUrls.length);
|
768 | }
|
769 | function clearResolutionOfComponentResourcesQueue() {
|
770 | const old = componentResourceResolutionQueue;
|
771 | componentResourceResolutionQueue = new Map();
|
772 | return old;
|
773 | }
|
774 | function restoreComponentResolutionQueue(queue) {
|
775 | componentDefPendingResolution.clear();
|
776 | queue.forEach((_, type) => componentDefPendingResolution.add(type));
|
777 | componentResourceResolutionQueue = queue;
|
778 | }
|
779 | function isComponentResourceResolutionQueueEmpty() {
|
780 | return componentResourceResolutionQueue.size === 0;
|
781 | }
|
782 | function unwrapResponse(response) {
|
783 | return typeof response == 'string' ? response : response.text();
|
784 | }
|
785 | function componentDefResolved(type) {
|
786 | componentDefPendingResolution.delete(type);
|
787 | }
|
788 |
|
789 |
|
790 |
|
791 |
|
792 |
|
793 |
|
794 |
|
795 |
|
796 | let _nextReferenceId = 0;
|
797 | class MetadataOverrider {
|
798 | constructor() {
|
799 | this._references = new Map();
|
800 | }
|
801 | |
802 |
|
803 |
|
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 | }
|
825 | function 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 | }
|
850 | function 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 | }
|
862 | function setMetadata(metadata, set) {
|
863 | for (const prop in set) {
|
864 | metadata[prop] = set[prop];
|
865 | }
|
866 | }
|
867 | function _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 | }
|
876 | function _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 | }
|
884 | function _valueProps(obj) {
|
885 | const props = [];
|
886 |
|
887 | Object.keys(obj).forEach((prop) => {
|
888 | if (!prop.startsWith('_')) {
|
889 | props.push(prop);
|
890 | }
|
891 | });
|
892 |
|
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 |
|
907 |
|
908 |
|
909 |
|
910 |
|
911 |
|
912 | const reflection = new ɵReflectionCapabilities();
|
913 |
|
914 |
|
915 |
|
916 | class 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 |
|
936 |
|
937 |
|
938 |
|
939 |
|
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 | }
|
968 | class DirectiveResolver extends OverrideResolver {
|
969 | get type() {
|
970 | return Directive;
|
971 | }
|
972 | }
|
973 | class ComponentResolver extends OverrideResolver {
|
974 | get type() {
|
975 | return Component;
|
976 | }
|
977 | }
|
978 | class PipeResolver extends OverrideResolver {
|
979 | get type() {
|
980 | return Pipe;
|
981 | }
|
982 | }
|
983 | class NgModuleResolver extends OverrideResolver {
|
984 | get type() {
|
985 | return NgModule;
|
986 | }
|
987 | }
|
988 |
|
989 |
|
990 |
|
991 |
|
992 |
|
993 |
|
994 |
|
995 |
|
996 | var TestingModuleOverride;
|
997 | (function (TestingModuleOverride) {
|
998 | TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
|
999 | TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
|
1000 | })(TestingModuleOverride || (TestingModuleOverride = {}));
|
1001 | function isTestingModuleOverride(value) {
|
1002 | return value === TestingModuleOverride.DECLARATION ||
|
1003 | value === TestingModuleOverride.OVERRIDE_TEMPLATE;
|
1004 | }
|
1005 | class R3TestBedCompiler {
|
1006 | constructor(platform, additionalModuleTypes) {
|
1007 | this.platform = platform;
|
1008 | this.additionalModuleTypes = additionalModuleTypes;
|
1009 | this.originalComponentResolutionQueue = null;
|
1010 |
|
1011 | this.declarations = [];
|
1012 | this.imports = [];
|
1013 | this.providers = [];
|
1014 | this.schemas = [];
|
1015 |
|
1016 | this.pendingComponents = new Set();
|
1017 | this.pendingDirectives = new Set();
|
1018 | this.pendingPipes = new Set();
|
1019 |
|
1020 | this.seenComponents = new Set();
|
1021 | this.seenDirectives = new Set();
|
1022 |
|
1023 | this.overriddenModules = new Set();
|
1024 |
|
1025 |
|
1026 | this.existingComponentStyles = new Map();
|
1027 | this.resolvers = initResolvers();
|
1028 | this.componentToModuleScope = new Map();
|
1029 |
|
1030 |
|
1031 |
|
1032 |
|
1033 | this.initialNgDefs = new Map();
|
1034 |
|
1035 |
|
1036 | this.defCleanupOps = [];
|
1037 | this._injector = null;
|
1038 | this.compilerProviders = null;
|
1039 | this.providerOverrides = [];
|
1040 | this.rootProviderOverrides = [];
|
1041 |
|
1042 |
|
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 |
|
1057 | if (moduleDef.declarations !== undefined) {
|
1058 | this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
|
1059 | this.declarations.push(...moduleDef.declarations);
|
1060 | }
|
1061 |
|
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 |
|
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 |
|
1083 |
|
1084 |
|
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 |
|
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 |
|
1140 |
|
1141 |
|
1142 |
|
1143 |
|
1144 |
|
1145 |
|
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 |
|
1152 | this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
|
1153 | }
|
1154 | compileComponents() {
|
1155 | return __awaiter(this, void 0, void 0, function* () {
|
1156 | this.clearComponentResolutionQueue();
|
1157 |
|
1158 | let needsAsyncResources = this.compileTypesSync();
|
1159 |
|
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 |
|
1174 | this.compileTypesSync();
|
1175 |
|
1176 | this.compileTestModule();
|
1177 | this.applyTransitiveScopes();
|
1178 | this.applyProviderOverrides();
|
1179 |
|
1180 |
|
1181 | this.patchComponentsWithExistingStyles();
|
1182 |
|
1183 |
|
1184 | this.componentToModuleScope.clear();
|
1185 | const parentInjector = this.platform.injector;
|
1186 | this.testModuleRef = new ɵRender3NgModuleRef(this.testModuleType, parentInjector);
|
1187 |
|
1188 |
|
1189 | this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
|
1190 |
|
1191 |
|
1192 |
|
1193 | const localeId = this.testModuleRef.injector.get(LOCALE_ID, ɵDEFAULT_LOCALE_ID);
|
1194 | ɵsetLocaleId(localeId);
|
1195 | return this.testModuleRef;
|
1196 | }
|
1197 | |
1198 |
|
1199 |
|
1200 | _compileNgModuleSync(moduleType) {
|
1201 | this.queueTypesFromModulesArray([moduleType]);
|
1202 | this.compileTypesSync();
|
1203 | this.applyProviderOverrides();
|
1204 | this.applyProviderOverridesToModule(moduleType);
|
1205 | this.applyTransitiveScopes();
|
1206 | }
|
1207 | |
1208 |
|
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 |
|
1221 |
|
1222 | _getModuleResolver() {
|
1223 | return this.resolvers.module;
|
1224 | }
|
1225 | |
1226 |
|
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 |
|
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 |
|
1271 |
|
1272 |
|
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 |
|
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 |
|
1335 |
|
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 |
|
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 |
|
1372 |
|
1373 |
|
1374 | if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(ɵNG_COMP_DEF)) {
|
1375 | this.pendingComponents.add(type);
|
1376 | }
|
1377 | this.seenComponents.add(type);
|
1378 |
|
1379 |
|
1380 |
|
1381 |
|
1382 |
|
1383 |
|
1384 |
|
1385 |
|
1386 |
|
1387 |
|
1388 |
|
1389 |
|
1390 |
|
1391 |
|
1392 |
|
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 |
|
1415 |
|
1416 |
|
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 |
|
1430 |
|
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 |
|
1440 |
|
1441 |
|
1442 |
|
1443 |
|
1444 |
|
1445 |
|
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 |
|
1453 |
|
1454 | calcAffectedModulesRecur(value, path);
|
1455 | }
|
1456 | else if (hasNgModuleDef(value)) {
|
1457 | if (seenModules.has(value)) {
|
1458 |
|
1459 |
|
1460 |
|
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 |
|
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 |
|
1492 |
|
1493 |
|
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 |
|
1503 |
|
1504 |
|
1505 |
|
1506 | restoreComponentResolutionQueue() {
|
1507 | if (this.originalComponentResolutionQueue !== null) {
|
1508 | restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
|
1509 | this.originalComponentResolutionQueue = null;
|
1510 | }
|
1511 | }
|
1512 | restoreOriginalState() {
|
1513 |
|
1514 |
|
1515 | forEachRight(this.defCleanupOps, (op) => {
|
1516 | op.object[op.fieldName] = op.originalValue;
|
1517 | });
|
1518 |
|
1519 | this.initialNgDefs.forEach((value, type) => {
|
1520 | const [prop, descriptor] = value;
|
1521 | if (!descriptor) {
|
1522 |
|
1523 |
|
1524 |
|
1525 |
|
1526 |
|
1527 |
|
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 |
|
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 |
|
1555 | ɵcompileNgModuleDefs(this.testModuleType, {
|
1556 | declarations: this.declarations,
|
1557 | imports,
|
1558 | schemas: this.schemas,
|
1559 | providers,
|
1560 | }, true);
|
1561 |
|
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 |
|
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 |
|
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 |
|
1595 |
|
1596 |
|
1597 |
|
1598 |
|
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 |
|
1610 |
|
1611 |
|
1612 |
|
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 |
|
1619 |
|
1620 |
|
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 | }
|
1644 | function initResolvers() {
|
1645 | return {
|
1646 | module: new NgModuleResolver(),
|
1647 | component: new ComponentResolver(),
|
1648 | directive: new DirectiveResolver(),
|
1649 | pipe: new PipeResolver()
|
1650 | };
|
1651 | }
|
1652 | function hasNgModuleDef(value) {
|
1653 | return value.hasOwnProperty('ɵmod');
|
1654 | }
|
1655 | function maybeUnwrapFn(maybeFn) {
|
1656 | return maybeFn instanceof Function ? maybeFn() : maybeFn;
|
1657 | }
|
1658 | function 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 | }
|
1670 | function getProviderField(provider, field) {
|
1671 | return provider && typeof provider === 'object' && provider[field];
|
1672 | }
|
1673 | function getProviderToken(provider) {
|
1674 | return getProviderField(provider, 'provide') || provider;
|
1675 | }
|
1676 | function isModuleWithProviders(value) {
|
1677 | return value.hasOwnProperty('ngModule');
|
1678 | }
|
1679 | function forEachRight(values, fn) {
|
1680 | for (let idx = values.length - 1; idx >= 0; idx--) {
|
1681 | fn(values[idx], idx);
|
1682 | }
|
1683 | }
|
1684 | function invalidTypeError(name, expectedType) {
|
1685 | return new Error(`${name} class doesn't have @${expectedType} decorator or is missing metadata.`);
|
1686 | }
|
1687 | class 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 |
|
1723 |
|
1724 |
|
1725 |
|
1726 |
|
1727 |
|
1728 |
|
1729 |
|
1730 |
|
1731 |
|
1732 |
|
1733 | class TestComponentRenderer {
|
1734 | insertRootElement(rootElementId) { }
|
1735 | }
|
1736 |
|
1737 |
|
1738 |
|
1739 | const ComponentFixtureAutoDetect = new InjectionToken('ComponentFixtureAutoDetect');
|
1740 |
|
1741 |
|
1742 |
|
1743 | const ComponentFixtureNoNgZone = new InjectionToken('ComponentFixtureNoNgZone');
|
1744 |
|
1745 |
|
1746 |
|
1747 |
|
1748 |
|
1749 |
|
1750 |
|
1751 |
|
1752 | let _nextRootElementId = 0;
|
1753 |
|
1754 |
|
1755 |
|
1756 |
|
1757 |
|
1758 |
|
1759 |
|
1760 |
|
1761 |
|
1762 |
|
1763 | class TestBedRender3 {
|
1764 | constructor() {
|
1765 |
|
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 |
|
1775 |
|
1776 |
|
1777 |
|
1778 |
|
1779 |
|
1780 |
|
1781 |
|
1782 |
|
1783 |
|
1784 |
|
1785 |
|
1786 | static initTestEnvironment(ngModule, platform, aotSummaries) {
|
1787 | const testBed = _getTestBedRender3();
|
1788 | testBed.initTestEnvironment(ngModule, platform, aotSummaries);
|
1789 | return testBed;
|
1790 | }
|
1791 | |
1792 |
|
1793 |
|
1794 |
|
1795 |
|
1796 | static resetTestEnvironment() {
|
1797 | _getTestBedRender3().resetTestEnvironment();
|
1798 | }
|
1799 | static configureCompiler(config) {
|
1800 | _getTestBedRender3().configureCompiler(config);
|
1801 | return TestBedRender3;
|
1802 | }
|
1803 | |
1804 |
|
1805 |
|
1806 |
|
1807 | static configureTestingModule(moduleDef) {
|
1808 | _getTestBedRender3().configureTestingModule(moduleDef);
|
1809 | return TestBedRender3;
|
1810 | }
|
1811 | |
1812 |
|
1813 |
|
1814 |
|
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 |
|
1841 |
|
1842 |
|
1843 |
|
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 |
|
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 |
|
1869 |
|
1870 |
|
1871 |
|
1872 |
|
1873 |
|
1874 |
|
1875 |
|
1876 |
|
1877 |
|
1878 |
|
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 |
|
1890 |
|
1891 |
|
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 |
|
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 |
|
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 |
|
1976 | const noNgZone = this.inject(ComponentFixtureNoNgZone, false);
|
1977 |
|
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 |
|
1991 |
|
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 |
|
2001 |
|
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 |
|
2017 |
|
2018 |
|
2019 |
|
2020 |
|
2021 |
|
2022 |
|
2023 |
|
2024 |
|
2025 |
|
2026 |
|
2027 | checkGlobalCompilationFinished() {
|
2028 |
|
2029 |
|
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 | }
|
2050 | let testBed;
|
2051 | function _getTestBedRender3() {
|
2052 | return testBed = testBed || new TestBedRender3();
|
2053 | }
|
2054 |
|
2055 |
|
2056 |
|
2057 |
|
2058 |
|
2059 |
|
2060 |
|
2061 |
|
2062 | function unimplemented() {
|
2063 | throw Error('unimplemented');
|
2064 | }
|
2065 |
|
2066 |
|
2067 |
|
2068 |
|
2069 |
|
2070 | class 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 |
|
2088 |
|
2089 |
|
2090 | loadAotSummaries(summaries) {
|
2091 | throw unimplemented();
|
2092 | }
|
2093 | |
2094 |
|
2095 |
|
2096 |
|
2097 |
|
2098 | getComponentFactory(component) {
|
2099 | throw unimplemented();
|
2100 | }
|
2101 | |
2102 |
|
2103 |
|
2104 |
|
2105 | getComponentFromError(error) {
|
2106 | throw unimplemented();
|
2107 | }
|
2108 | }
|
2109 | TestingCompiler.decorators = [
|
2110 | { type: Injectable }
|
2111 | ];
|
2112 |
|
2113 |
|
2114 |
|
2115 |
|
2116 |
|
2117 | class TestingCompilerFactory {
|
2118 | }
|
2119 |
|
2120 |
|
2121 |
|
2122 |
|
2123 |
|
2124 |
|
2125 |
|
2126 |
|
2127 | let _nextRootElementId$1 = 0;
|
2128 |
|
2129 |
|
2130 |
|
2131 |
|
2132 |
|
2133 |
|
2134 |
|
2135 |
|
2136 |
|
2137 |
|
2138 | class 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 |
|
2164 |
|
2165 |
|
2166 |
|
2167 |
|
2168 |
|
2169 |
|
2170 |
|
2171 |
|
2172 |
|
2173 | static initTestEnvironment(ngModule, platform, aotSummaries) {
|
2174 | const testBed = _getTestBedViewEngine();
|
2175 | testBed.initTestEnvironment(ngModule, platform, aotSummaries);
|
2176 | return testBed;
|
2177 | }
|
2178 | |
2179 |
|
2180 |
|
2181 | static resetTestEnvironment() {
|
2182 | _getTestBedViewEngine().resetTestEnvironment();
|
2183 | }
|
2184 | static resetTestingModule() {
|
2185 | _getTestBedViewEngine().resetTestingModule();
|
2186 | return TestBedViewEngine;
|
2187 | }
|
2188 | |
2189 |
|
2190 |
|
2191 |
|
2192 | static configureCompiler(config) {
|
2193 | _getTestBedViewEngine().configureCompiler(config);
|
2194 | return TestBedViewEngine;
|
2195 | }
|
2196 | |
2197 |
|
2198 |
|
2199 |
|
2200 | static configureTestingModule(moduleDef) {
|
2201 | _getTestBedViewEngine().configureTestingModule(moduleDef);
|
2202 | return TestBedViewEngine;
|
2203 | }
|
2204 | |
2205 |
|
2206 |
|
2207 |
|
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 |
|
2234 |
|
2235 |
|
2236 |
|
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 |
|
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 |
|
2258 |
|
2259 |
|
2260 |
|
2261 |
|
2262 |
|
2263 |
|
2264 |
|
2265 |
|
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 |
|
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 |
|
2384 |
|
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 |
|
2437 |
|
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 |
|
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 ;
|
2485 | value = provider.useFactory;
|
2486 | }
|
2487 | else {
|
2488 | flags |= 256 ;
|
2489 | value = provider.useValue;
|
2490 | }
|
2491 | const deps = (provider.deps || []).map((dep) => {
|
2492 | let depFlags = 0 ;
|
2493 | let depToken;
|
2494 | if (Array.isArray(dep)) {
|
2495 | dep.forEach((entry) => {
|
2496 | if (entry instanceof Optional) {
|
2497 | depFlags |= 2 ;
|
2498 | }
|
2499 | else if (entry instanceof SkipSelf) {
|
2500 | depFlags |= 1 ;
|
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 |
|
2530 | const noNgZone = this.inject(ComponentFixtureNoNgZone, false);
|
2531 |
|
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 |
|
2548 |
|
2549 |
|
2550 |
|
2551 |
|
2552 |
|
2553 |
|
2554 |
|
2555 |
|
2556 |
|
2557 |
|
2558 | const TestBed = ɵivyEnabled ? TestBedRender3 : TestBedViewEngine;
|
2559 |
|
2560 |
|
2561 |
|
2562 |
|
2563 |
|
2564 |
|
2565 |
|
2566 | const getTestBed = ɵivyEnabled ? _getTestBedRender3 : _getTestBedViewEngine;
|
2567 | let testBed$1;
|
2568 | function _getTestBedViewEngine() {
|
2569 | return testBed$1 = testBed$1 || new TestBedViewEngine();
|
2570 | }
|
2571 |
|
2572 |
|
2573 |
|
2574 |
|
2575 |
|
2576 |
|
2577 |
|
2578 |
|
2579 |
|
2580 |
|
2581 |
|
2582 |
|
2583 |
|
2584 |
|
2585 |
|
2586 |
|
2587 |
|
2588 |
|
2589 |
|
2590 |
|
2591 |
|
2592 |
|
2593 |
|
2594 |
|
2595 | function inject(tokens, fn) {
|
2596 | const testBed = getTestBed();
|
2597 | if (tokens.indexOf(AsyncTestCompleter) >= 0) {
|
2598 |
|
2599 | return function () {
|
2600 |
|
2601 |
|
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 |
|
2611 | return function () {
|
2612 | return testBed.execute(tokens, fn, this);
|
2613 | };
|
2614 | }
|
2615 | }
|
2616 |
|
2617 |
|
2618 |
|
2619 | class 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 |
|
2632 | return function () {
|
2633 | self._addModule();
|
2634 | return inject(tokens, fn).call(this);
|
2635 | };
|
2636 | }
|
2637 | }
|
2638 | function withModule(moduleDef, fn) {
|
2639 | if (fn) {
|
2640 |
|
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 |
|
2654 |
|
2655 |
|
2656 |
|
2657 |
|
2658 |
|
2659 | const _global$1 = (typeof window === 'undefined' ? global : window);
|
2660 |
|
2661 | if (_global$1.beforeEach) {
|
2662 | _global$1.beforeEach(() => {
|
2663 | TestBed.resetTestingModule();
|
2664 | resetFakeAsyncZone();
|
2665 | });
|
2666 | }
|
2667 |
|
2668 |
|
2669 | const __core_private_testing_placeholder__ = '';
|
2670 |
|
2671 |
|
2672 |
|
2673 |
|
2674 |
|
2675 |
|
2676 |
|
2677 |
|
2678 |
|
2679 |
|
2680 |
|
2681 |
|
2682 |
|
2683 |
|
2684 |
|
2685 |
|
2686 |
|
2687 |
|
2688 |
|
2689 |
|
2690 |
|
2691 |
|
2692 |
|
2693 |
|
2694 |
|
2695 |
|
2696 |
|
2697 |
|
2698 |
|
2699 |
|
2700 |
|
2701 |
|
2702 |
|
2703 |
|
2704 |
|
2705 |
|
2706 |
|
2707 |
|
2708 |
|
2709 |
|
2710 |
|
2711 |
|
2712 |
|
2713 |
|
2714 |
|
2715 |
|
2716 | export { 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 |
|