@angular/core 12.1.0-next.3 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/bundles/core-testing.umd.js +229 -101
  2. package/bundles/core-testing.umd.js.map +1 -1
  3. package/bundles/core.umd.js +65 -28
  4. package/bundles/core.umd.js.map +1 -1
  5. package/core.d.ts +269 -19
  6. package/core.metadata.json +1 -1
  7. package/esm2015/src/application_ref.js +29 -8
  8. package/esm2015/src/change_detection/differs/iterable_differs.js +1 -1
  9. package/esm2015/src/debug/debug_node.js +1 -1
  10. package/esm2015/src/di/injectable.js +1 -1
  11. package/esm2015/src/di/injector_marker.js +1 -1
  12. package/esm2015/src/linker/component_factory_resolver.js +4 -1
  13. package/esm2015/src/linker/element_ref.js +1 -1
  14. package/esm2015/src/linker/query_list.js +2 -1
  15. package/esm2015/src/metadata/di.js +1 -1
  16. package/esm2015/src/metadata/do_boostrap.js +1 -1
  17. package/esm2015/src/metadata/ng_module.js +1 -1
  18. package/esm2015/src/metadata/schema.js +5 -1
  19. package/esm2015/src/render3/definition.js +16 -16
  20. package/esm2015/src/render3/node_assert.js +1 -1
  21. package/esm2015/src/util/assert.js +1 -1
  22. package/esm2015/src/util/decorators.js +1 -1
  23. package/esm2015/src/util/dom.js +1 -1
  24. package/esm2015/src/version.js +1 -1
  25. package/esm2015/src/view/util.js +3 -1
  26. package/esm2015/testing/src/r3_test_bed.js +84 -7
  27. package/esm2015/testing/src/test_bed.js +103 -42
  28. package/esm2015/testing/src/test_bed_common.js +7 -1
  29. package/esm2015/testing/src/test_hooks.js +45 -0
  30. package/esm2015/testing/src/testing.js +3 -3
  31. package/esm2015/testing/src/testing_internal.js +1 -182
  32. package/fesm2015/core.js +55 -24
  33. package/fesm2015/core.js.map +1 -1
  34. package/fesm2015/testing.js +206 -77
  35. package/fesm2015/testing.js.map +1 -1
  36. package/package.json +2 -2
  37. package/schematics/migrations/can-activate-with-redirect-to/util.js +1 -1
  38. package/schematics/migrations/can-activate-with-redirect-to/util.mjs +1 -1
  39. package/schematics/migrations/initial-navigation/collector.js +3 -2
  40. package/schematics/migrations/initial-navigation/collector.mjs +3 -2
  41. package/schematics/migrations/navigation-extras-omissions/util.js +2 -3
  42. package/schematics/migrations/navigation-extras-omissions/util.mjs +2 -3
  43. package/schematics/migrations/relative-link-resolution/collector.js +3 -2
  44. package/schematics/migrations/relative-link-resolution/collector.mjs +3 -2
  45. package/schematics/migrations/relative-link-resolution/update_recorder.js +1 -1
  46. package/schematics/migrations/relative-link-resolution/update_recorder.mjs +1 -1
  47. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.js +2 -2
  48. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.mjs +2 -2
  49. package/schematics/migrations/xhr-factory/index.js +1 -1
  50. package/schematics/migrations/xhr-factory/index.mjs +1 -1
  51. package/schematics/utils/typescript/imports.js +2 -2
  52. package/schematics/utils/typescript/imports.mjs +2 -2
  53. package/src/r3_symbols.d.ts +4 -1
  54. package/testing/testing.d.ts +63 -10
  55. package/testing/testing.metadata.json +1 -1
  56. package/testing.d.ts +1 -1
  57. package/esm2015/testing/src/async_test_completer.js +0 -28
  58. package/esm2015/testing/src/before_each.js +0 -33
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v12.1.0-next.3
2
+ * @license Angular v12.1.0
3
3
  * (c) 2010-2021 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -412,34 +412,6 @@ function flushMicrotasks() {
412
412
  throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
413
413
  }
414
414
 
415
- /**
416
- * @license
417
- * Copyright Google LLC All Rights Reserved.
418
- *
419
- * Use of this source code is governed by an MIT-style license that can be
420
- * found in the LICENSE file at https://angular.io/license
421
- */
422
- /**
423
- * Injectable completer that allows signaling completion of an asynchronous test. Used internally.
424
- */
425
- class AsyncTestCompleter {
426
- constructor() {
427
- this._promise = new Promise((res, rej) => {
428
- this._resolve = res;
429
- this._reject = rej;
430
- });
431
- }
432
- done(value) {
433
- this._resolve(value);
434
- }
435
- fail(error, stackTrace) {
436
- this._reject(error);
437
- }
438
- get promise() {
439
- return this._promise;
440
- }
441
- }
442
-
443
415
  /**
444
416
  * @license
445
417
  * Copyright Google LLC All Rights Reserved.
@@ -1497,6 +1469,11 @@ class R3TestCompiler {
1497
1469
  * Use of this source code is governed by an MIT-style license that can be
1498
1470
  * found in the LICENSE file at https://angular.io/license
1499
1471
  */
1472
+ /**
1473
+ * Whether test modules should be torn down by default.
1474
+ * Currently disabled for backwards-compatibility reasons.
1475
+ */
1476
+ const TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT = false;
1500
1477
  /**
1501
1478
  * An abstract class for inserting the root test component element in a platform independent way.
1502
1479
  *
@@ -1504,6 +1481,7 @@ class R3TestCompiler {
1504
1481
  */
1505
1482
  class TestComponentRenderer {
1506
1483
  insertRootElement(rootElementId) { }
1484
+ removeAllRootElements() { }
1507
1485
  }
1508
1486
  /**
1509
1487
  * @publicApi
@@ -1555,9 +1533,9 @@ class TestBedRender3 {
1555
1533
  *
1556
1534
  * @publicApi
1557
1535
  */
1558
- static initTestEnvironment(ngModule, platform, aotSummaries) {
1536
+ static initTestEnvironment(ngModule, platform, summariesOrOptions) {
1559
1537
  const testBed = _getTestBedRender3();
1560
- testBed.initTestEnvironment(ngModule, platform, aotSummaries);
1538
+ testBed.initTestEnvironment(ngModule, platform, summariesOrOptions);
1561
1539
  return testBed;
1562
1540
  }
1563
1541
  /**
@@ -1636,6 +1614,12 @@ class TestBedRender3 {
1636
1614
  _getTestBedRender3().resetTestingModule();
1637
1615
  return TestBedRender3;
1638
1616
  }
1617
+ static shouldTearDownTestingModule() {
1618
+ return _getTestBedRender3().shouldTearDownTestingModule();
1619
+ }
1620
+ static tearDownTestingModule() {
1621
+ _getTestBedRender3().tearDownTestingModule();
1622
+ }
1639
1623
  /**
1640
1624
  * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
1641
1625
  * angular module. These are common to every test in the suite.
@@ -1649,10 +1633,14 @@ class TestBedRender3 {
1649
1633
  *
1650
1634
  * @publicApi
1651
1635
  */
1652
- initTestEnvironment(ngModule, platform, aotSummaries) {
1636
+ initTestEnvironment(ngModule, platform, summariesOrOptions) {
1653
1637
  if (this.platform || this.ngModule) {
1654
1638
  throw new Error('Cannot set base providers because it has already been called');
1655
1639
  }
1640
+ // If `summariesOrOptions` is a function, it means that it's
1641
+ // an AOT summaries factory which Ivy doesn't support.
1642
+ TestBedRender3._environmentTeardownOptions =
1643
+ typeof summariesOrOptions === 'function' ? undefined : summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.teardown;
1656
1644
  this.platform = platform;
1657
1645
  this.ngModule = ngModule;
1658
1646
  this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
@@ -1667,6 +1655,7 @@ class TestBedRender3 {
1667
1655
  this._compiler = null;
1668
1656
  this.platform = null;
1669
1657
  this.ngModule = null;
1658
+ TestBedRender3._environmentTeardownOptions = undefined;
1670
1659
  }
1671
1660
  resetTestingModule() {
1672
1661
  this.checkGlobalCompilationFinished();
@@ -1675,8 +1664,23 @@ class TestBedRender3 {
1675
1664
  this.compiler.restoreOriginalState();
1676
1665
  }
1677
1666
  this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
1678
- this._testModuleRef = null;
1679
- this.destroyActiveFixtures();
1667
+ // We have to chain a couple of try/finally blocks, because each step can
1668
+ // throw errors and we don't want it to interrupt the next step and we also
1669
+ // want an error to be thrown at the end.
1670
+ try {
1671
+ this.destroyActiveFixtures();
1672
+ }
1673
+ finally {
1674
+ try {
1675
+ if (this.shouldTearDownTestingModule()) {
1676
+ this.tearDownTestingModule();
1677
+ }
1678
+ }
1679
+ finally {
1680
+ this._testModuleRef = null;
1681
+ this._instanceTeardownOptions = undefined;
1682
+ }
1683
+ }
1680
1684
  }
1681
1685
  configureCompiler(config) {
1682
1686
  if (config.useJit != null) {
@@ -1688,6 +1692,9 @@ class TestBedRender3 {
1688
1692
  }
1689
1693
  configureTestingModule(moduleDef) {
1690
1694
  this.assertNotInstantiated('R3TestBed.configureTestingModule', 'configure the test module');
1695
+ // Always re-assign the teardown options, even if they're undefined.
1696
+ // This ensures that we don't carry the options between tests.
1697
+ this._instanceTeardownOptions = moduleDef.teardown;
1691
1698
  this.compiler.configureTestingModule(moduleDef);
1692
1699
  }
1693
1700
  compileComponents() {
@@ -1806,11 +1813,13 @@ class TestBedRender3 {
1806
1813
  this._globalCompilationChecked = true;
1807
1814
  }
1808
1815
  destroyActiveFixtures() {
1816
+ let errorCount = 0;
1809
1817
  this._activeFixtures.forEach((fixture) => {
1810
1818
  try {
1811
1819
  fixture.destroy();
1812
1820
  }
1813
1821
  catch (e) {
1822
+ errorCount++;
1814
1823
  console.error('Error during cleanup of component', {
1815
1824
  component: fixture.componentInstance,
1816
1825
  stacktrace: e,
@@ -1818,6 +1827,52 @@ class TestBedRender3 {
1818
1827
  }
1819
1828
  });
1820
1829
  this._activeFixtures = [];
1830
+ if (errorCount > 0 && this.shouldRethrowTeardownErrors()) {
1831
+ throw Error(`${errorCount} ${(errorCount === 1 ? 'component' : 'components')} ` +
1832
+ `threw errors during cleanup`);
1833
+ }
1834
+ }
1835
+ shouldRethrowTeardownErrors() {
1836
+ var _a, _b;
1837
+ const instanceOptions = this._instanceTeardownOptions;
1838
+ const environmentOptions = TestBedRender3._environmentTeardownOptions;
1839
+ // If the new teardown behavior hasn't been configured, preserve the old behavior.
1840
+ if (!instanceOptions && !environmentOptions) {
1841
+ return false;
1842
+ }
1843
+ // Otherwise use the configured behavior or default to rethrowing.
1844
+ return (_b = (_a = instanceOptions === null || instanceOptions === void 0 ? void 0 : instanceOptions.rethrowErrors) !== null && _a !== void 0 ? _a : environmentOptions === null || environmentOptions === void 0 ? void 0 : environmentOptions.rethrowErrors) !== null && _b !== void 0 ? _b : true;
1845
+ }
1846
+ shouldTearDownTestingModule() {
1847
+ var _a, _b, _c, _d;
1848
+ return (_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.destroyAfterEach) !== null && _b !== void 0 ? _b : (_c = TestBedRender3._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.destroyAfterEach) !== null && _d !== void 0 ? _d : TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT;
1849
+ }
1850
+ tearDownTestingModule() {
1851
+ var _a;
1852
+ // If the module ref has already been destroyed, we won't be able to get a test renderer.
1853
+ if (this._testModuleRef === null) {
1854
+ return;
1855
+ }
1856
+ // Resolve the renderer ahead of time, because we want to remove the root elements as the very
1857
+ // last step, but the injector will be destroyed as a part of the module ref destruction.
1858
+ const testRenderer = this.inject(TestComponentRenderer);
1859
+ try {
1860
+ this._testModuleRef.destroy();
1861
+ }
1862
+ catch (e) {
1863
+ if (this.shouldRethrowTeardownErrors()) {
1864
+ throw e;
1865
+ }
1866
+ else {
1867
+ console.error('Error during cleanup of a testing module', {
1868
+ component: this._testModuleRef.instance,
1869
+ stacktrace: e,
1870
+ });
1871
+ }
1872
+ }
1873
+ finally {
1874
+ (_a = testRenderer.removeAllRootElements) === null || _a === void 0 ? void 0 : _a.call(testRenderer);
1875
+ }
1821
1876
  }
1822
1877
  }
1823
1878
  let testBed;
@@ -1943,9 +1998,9 @@ class TestBedViewEngine {
1943
1998
  * Test modules and platforms for individual platforms are available from
1944
1999
  * '@angular/<platform_name>/testing'.
1945
2000
  */
1946
- static initTestEnvironment(ngModule, platform, aotSummaries) {
2001
+ static initTestEnvironment(ngModule, platform, summariesOrOptions) {
1947
2002
  const testBed = _getTestBedViewEngine();
1948
- testBed.initTestEnvironment(ngModule, platform, aotSummaries);
2003
+ testBed.initTestEnvironment(ngModule, platform, summariesOrOptions);
1949
2004
  return testBed;
1950
2005
  }
1951
2006
  /**
@@ -2026,6 +2081,12 @@ class TestBedViewEngine {
2026
2081
  static createComponent(component) {
2027
2082
  return _getTestBedViewEngine().createComponent(component);
2028
2083
  }
2084
+ static shouldTearDownTestingModule() {
2085
+ return _getTestBedViewEngine().shouldTearDownTestingModule();
2086
+ }
2087
+ static tearDownTestingModule() {
2088
+ _getTestBedViewEngine().tearDownTestingModule();
2089
+ }
2029
2090
  /**
2030
2091
  * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
2031
2092
  * angular module. These are common to every test in the suite.
@@ -2037,14 +2098,19 @@ class TestBedViewEngine {
2037
2098
  * Test modules and platforms for individual platforms are available from
2038
2099
  * '@angular/<platform_name>/testing'.
2039
2100
  */
2040
- initTestEnvironment(ngModule, platform, aotSummaries) {
2101
+ initTestEnvironment(ngModule, platform, summariesOrOptions) {
2041
2102
  if (this.platform || this.ngModule) {
2042
2103
  throw new Error('Cannot set base providers because it has already been called');
2043
2104
  }
2044
2105
  this.platform = platform;
2045
2106
  this.ngModule = ngModule;
2046
- if (aotSummaries) {
2047
- this._testEnvAotSummaries = aotSummaries;
2107
+ if (typeof summariesOrOptions === 'function') {
2108
+ this._testEnvAotSummaries = summariesOrOptions;
2109
+ TestBedViewEngine._environmentTeardownOptions = undefined;
2110
+ }
2111
+ else {
2112
+ this._testEnvAotSummaries = (summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.aotSummaries) || (() => []);
2113
+ TestBedViewEngine._environmentTeardownOptions = summariesOrOptions === null || summariesOrOptions === void 0 ? void 0 : summariesOrOptions.teardown;
2048
2114
  }
2049
2115
  }
2050
2116
  /**
@@ -2055,6 +2121,7 @@ class TestBedViewEngine {
2055
2121
  this.platform = null;
2056
2122
  this.ngModule = null;
2057
2123
  this._testEnvAotSummaries = () => [];
2124
+ TestBedViewEngine._environmentTeardownOptions = undefined;
2058
2125
  }
2059
2126
  resetTestingModule() {
2060
2127
  ɵclearOverrides();
@@ -2067,26 +2134,30 @@ class TestBedViewEngine {
2067
2134
  this._pipeOverrides = [];
2068
2135
  this._isRoot = true;
2069
2136
  this._rootProviderOverrides = [];
2070
- this._moduleRef = null;
2071
2137
  this._moduleFactory = null;
2072
2138
  this._compilerOptions = [];
2073
2139
  this._providers = [];
2074
2140
  this._declarations = [];
2075
2141
  this._imports = [];
2076
2142
  this._schemas = [];
2077
- this._instantiated = false;
2078
- this._activeFixtures.forEach((fixture) => {
2143
+ // We have to chain a couple of try/finally blocks, because each step can
2144
+ // throw errors and we don't want it to interrupt the next step and we also
2145
+ // want an error to be thrown at the end.
2146
+ try {
2147
+ this.destroyActiveFixtures();
2148
+ }
2149
+ finally {
2079
2150
  try {
2080
- fixture.destroy();
2151
+ if (this.shouldTearDownTestingModule()) {
2152
+ this.tearDownTestingModule();
2153
+ }
2081
2154
  }
2082
- catch (e) {
2083
- console.error('Error during cleanup of component', {
2084
- component: fixture.componentInstance,
2085
- stacktrace: e,
2086
- });
2155
+ finally {
2156
+ this._moduleRef = null;
2157
+ this._instanceTeardownOptions = undefined;
2158
+ this._instantiated = false;
2087
2159
  }
2088
- });
2089
- this._activeFixtures = [];
2160
+ }
2090
2161
  }
2091
2162
  configureCompiler(config) {
2092
2163
  this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler');
@@ -2109,6 +2180,9 @@ class TestBedViewEngine {
2109
2180
  if (moduleDef.aotSummaries) {
2110
2181
  this._aotSummaries.push(moduleDef.aotSummaries);
2111
2182
  }
2183
+ // Always re-assign the teardown options, even if they're undefined.
2184
+ // This ensures that we don't carry the options between tests.
2185
+ this._instanceTeardownOptions = moduleDef.teardown;
2112
2186
  }
2113
2187
  compileComponents() {
2114
2188
  if (this._moduleFactory || this._instantiated) {
@@ -2316,6 +2390,68 @@ class TestBedViewEngine {
2316
2390
  this._activeFixtures.push(fixture);
2317
2391
  return fixture;
2318
2392
  }
2393
+ destroyActiveFixtures() {
2394
+ let errorCount = 0;
2395
+ this._activeFixtures.forEach((fixture) => {
2396
+ try {
2397
+ fixture.destroy();
2398
+ }
2399
+ catch (e) {
2400
+ errorCount++;
2401
+ console.error('Error during cleanup of component', {
2402
+ component: fixture.componentInstance,
2403
+ stacktrace: e,
2404
+ });
2405
+ }
2406
+ });
2407
+ this._activeFixtures = [];
2408
+ if (errorCount > 0 && this.shouldRethrowTeardownErrors()) {
2409
+ throw Error(`${errorCount} ${(errorCount === 1 ? 'component' : 'components')} ` +
2410
+ `threw errors during cleanup`);
2411
+ }
2412
+ }
2413
+ shouldRethrowTeardownErrors() {
2414
+ var _a, _b;
2415
+ const instanceOptions = this._instanceTeardownOptions;
2416
+ const environmentOptions = TestBedViewEngine._environmentTeardownOptions;
2417
+ // If the new teardown behavior hasn't been configured, preserve the old behavior.
2418
+ if (!instanceOptions && !environmentOptions) {
2419
+ return false;
2420
+ }
2421
+ // Otherwise use the configured behavior or default to rethrowing.
2422
+ return (_b = (_a = instanceOptions === null || instanceOptions === void 0 ? void 0 : instanceOptions.rethrowErrors) !== null && _a !== void 0 ? _a : environmentOptions === null || environmentOptions === void 0 ? void 0 : environmentOptions.rethrowErrors) !== null && _b !== void 0 ? _b : true;
2423
+ }
2424
+ shouldTearDownTestingModule() {
2425
+ var _a, _b, _c, _d;
2426
+ return (_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.destroyAfterEach) !== null && _b !== void 0 ? _b : (_c = TestBedViewEngine._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.destroyAfterEach) !== null && _d !== void 0 ? _d : TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT;
2427
+ }
2428
+ tearDownTestingModule() {
2429
+ var _a, _b, _c, _d, _e;
2430
+ // If the module ref has already been destroyed, we won't be able to get a test renderer.
2431
+ if (this._moduleRef === null) {
2432
+ return;
2433
+ }
2434
+ // Resolve the renderer ahead of time, because we want to remove the root elements as the very
2435
+ // last step, but the injector will be destroyed as a part of the module ref destruction.
2436
+ const testRenderer = this.inject(TestComponentRenderer);
2437
+ try {
2438
+ this._moduleRef.destroy();
2439
+ }
2440
+ catch (e) {
2441
+ if ((_d = (_b = (_a = this._instanceTeardownOptions) === null || _a === void 0 ? void 0 : _a.rethrowErrors) !== null && _b !== void 0 ? _b : (_c = TestBedViewEngine._environmentTeardownOptions) === null || _c === void 0 ? void 0 : _c.rethrowErrors) !== null && _d !== void 0 ? _d : true) {
2442
+ throw e;
2443
+ }
2444
+ else {
2445
+ console.error('Error during cleanup of a testing module', {
2446
+ component: this._moduleRef.instance,
2447
+ stacktrace: e,
2448
+ });
2449
+ }
2450
+ }
2451
+ finally {
2452
+ (_e = testRenderer === null || testRenderer === void 0 ? void 0 : testRenderer.removeAllRootElements) === null || _e === void 0 ? void 0 : _e.call(testRenderer);
2453
+ }
2454
+ }
2319
2455
  }
2320
2456
  /**
2321
2457
  * @description
@@ -2359,33 +2495,14 @@ function _getTestBedViewEngine() {
2359
2495
  * })
2360
2496
  * ```
2361
2497
  *
2362
- * Notes:
2363
- * - inject is currently a function because of some Traceur limitation the syntax should
2364
- * eventually
2365
- * becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });`
2366
- *
2367
2498
  * @publicApi
2368
2499
  */
2369
2500
  function inject(tokens, fn) {
2370
2501
  const testBed = getTestBed();
2371
- if (tokens.indexOf(AsyncTestCompleter) >= 0) {
2372
- // Not using an arrow function to preserve context passed from call site
2373
- return function () {
2374
- // Return an async test method that returns a Promise if AsyncTestCompleter is one of
2375
- // the injected tokens.
2376
- return testBed.compileComponents().then(() => {
2377
- const completer = testBed.inject(AsyncTestCompleter);
2378
- testBed.execute(tokens, fn, this);
2379
- return completer.promise;
2380
- });
2381
- };
2382
- }
2383
- else {
2384
- // Not using an arrow function to preserve context passed from call site
2385
- return function () {
2386
- return testBed.execute(tokens, fn, this);
2387
- };
2388
- }
2502
+ // Not using an arrow function to preserve context passed from call site
2503
+ return function () {
2504
+ return testBed.execute(tokens, fn, this);
2505
+ };
2389
2506
  }
2390
2507
  /**
2391
2508
  * @publicApi
@@ -2433,10 +2550,22 @@ function withModule(moduleDef, fn) {
2433
2550
  const _global = (typeof window === 'undefined' ? global : window);
2434
2551
  // Reset the test providers and the fake async zone before each test.
2435
2552
  if (_global.beforeEach) {
2436
- _global.beforeEach(() => {
2437
- TestBed.resetTestingModule();
2438
- resetFakeAsyncZone();
2439
- });
2553
+ _global.beforeEach(getCleanupHook(false));
2554
+ }
2555
+ // We provide both a `beforeEach` and `afterEach`, because the updated behavior for
2556
+ // tearing down the module is supposed to run after the test so that we can associate
2557
+ // teardown errors with the correct test.
2558
+ if (_global.afterEach) {
2559
+ _global.afterEach(getCleanupHook(true));
2560
+ }
2561
+ function getCleanupHook(expectedTeardownValue) {
2562
+ return () => {
2563
+ if (TestBed.shouldTearDownTestingModule() ===
2564
+ expectedTeardownValue) {
2565
+ TestBed.resetTestingModule();
2566
+ resetFakeAsyncZone();
2567
+ }
2568
+ };
2440
2569
  }
2441
2570
  /**
2442
2571
  * This API should be removed. But doing so seems to break `google3` and so it requires a bit of