testing.mjs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * @license Angular v19.2.13
  3. * (c) 2010-2025 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. import * as i0 from '@angular/core';
  7. import { NgModule, signal, Injectable, ViewChild, Component } from '@angular/core';
  8. import { TestBed } from '@angular/core/testing';
  9. import { ROUTES, ROUTER_CONFIGURATION, Router, afterNextNavigation, RouterOutlet } from './router-Dwfin5Au.mjs';
  10. export { ɵEmptyOutletComponent as ɵɵEmptyOutletComponent } from './router-Dwfin5Au.mjs';
  11. import { RouterModule, ROUTER_PROVIDERS, withPreloading, NoPreloading } from './router_module-DTJgGWLd.mjs';
  12. export { RouterLink as ɵɵRouterLink, RouterLinkActive as ɵɵRouterLinkActive } from './router_module-DTJgGWLd.mjs';
  13. import { provideLocationMocks } from '@angular/common/testing';
  14. import '@angular/common';
  15. import 'rxjs';
  16. import 'rxjs/operators';
  17. import '@angular/platform-browser';
  18. /**
  19. * @description
  20. *
  21. * Sets up the router to be used for testing.
  22. *
  23. * The modules sets up the router to be used for testing.
  24. * It provides spy implementations of `Location` and `LocationStrategy`.
  25. *
  26. * @usageNotes
  27. * ### Example
  28. *
  29. * ```ts
  30. * beforeEach(() => {
  31. * TestBed.configureTestingModule({
  32. * imports: [
  33. * RouterModule.forRoot(
  34. * [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]
  35. * )
  36. * ]
  37. * });
  38. * });
  39. * ```
  40. *
  41. * @publicApi
  42. * @deprecated Use `provideRouter` or `RouterModule`/`RouterModule.forRoot` instead.
  43. * This module was previously used to provide a helpful collection of test fakes,
  44. * most notably those for `Location` and `LocationStrategy`. These are generally not
  45. * required anymore, as `MockPlatformLocation` is provided in `TestBed` by default.
  46. * However, you can use them directly with `provideLocationMocks`.
  47. */
  48. class RouterTestingModule {
  49. static withRoutes(routes, config) {
  50. return {
  51. ngModule: RouterTestingModule,
  52. providers: [
  53. { provide: ROUTES, multi: true, useValue: routes },
  54. { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
  55. ],
  56. };
  57. }
  58. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RouterTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
  59. static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.13", ngImport: i0, type: RouterTestingModule, exports: [RouterModule] });
  60. static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RouterTestingModule, providers: [
  61. ROUTER_PROVIDERS,
  62. provideLocationMocks(),
  63. withPreloading(NoPreloading).ɵproviders,
  64. { provide: ROUTES, multi: true, useValue: [] },
  65. ], imports: [RouterModule] });
  66. }
  67. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RouterTestingModule, decorators: [{
  68. type: NgModule,
  69. args: [{
  70. exports: [RouterModule],
  71. providers: [
  72. ROUTER_PROVIDERS,
  73. provideLocationMocks(),
  74. withPreloading(NoPreloading).ɵproviders,
  75. { provide: ROUTES, multi: true, useValue: [] },
  76. ],
  77. }]
  78. }] });
  79. class RootFixtureService {
  80. fixture;
  81. harness;
  82. createHarness() {
  83. if (this.harness) {
  84. throw new Error('Only one harness should be created per test.');
  85. }
  86. this.harness = new RouterTestingHarness(this.getRootFixture());
  87. return this.harness;
  88. }
  89. getRootFixture() {
  90. if (this.fixture !== undefined) {
  91. return this.fixture;
  92. }
  93. this.fixture = TestBed.createComponent(RootCmp);
  94. this.fixture.detectChanges();
  95. return this.fixture;
  96. }
  97. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RootFixtureService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
  98. static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RootFixtureService, providedIn: 'root' });
  99. }
  100. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RootFixtureService, decorators: [{
  101. type: Injectable,
  102. args: [{ providedIn: 'root' }]
  103. }] });
  104. class RootCmp {
  105. outlet;
  106. routerOutletData = signal(undefined);
  107. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RootCmp, deps: [], target: i0.ɵɵFactoryTarget.Component });
  108. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.13", type: RootCmp, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "outlet", first: true, predicate: RouterOutlet, descendants: true }], ngImport: i0, template: '<router-outlet [routerOutletData]="routerOutletData()"></router-outlet>', isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
  109. }
  110. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RootCmp, decorators: [{
  111. type: Component,
  112. args: [{
  113. template: '<router-outlet [routerOutletData]="routerOutletData()"></router-outlet>',
  114. imports: [RouterOutlet],
  115. }]
  116. }], propDecorators: { outlet: [{
  117. type: ViewChild,
  118. args: [RouterOutlet]
  119. }] } });
  120. /**
  121. * A testing harness for the `Router` to reduce the boilerplate needed to test routes and routed
  122. * components.
  123. *
  124. * @publicApi
  125. */
  126. class RouterTestingHarness {
  127. /**
  128. * Creates a `RouterTestingHarness` instance.
  129. *
  130. * The `RouterTestingHarness` also creates its own root component with a `RouterOutlet` for the
  131. * purposes of rendering route components.
  132. *
  133. * Throws an error if an instance has already been created.
  134. * Use of this harness also requires `destroyAfterEach: true` in the `ModuleTeardownOptions`
  135. *
  136. * @param initialUrl The target of navigation to trigger before returning the harness.
  137. */
  138. static async create(initialUrl) {
  139. const harness = TestBed.inject(RootFixtureService).createHarness();
  140. if (initialUrl !== undefined) {
  141. await harness.navigateByUrl(initialUrl);
  142. }
  143. return harness;
  144. }
  145. /**
  146. * Fixture of the root component of the RouterTestingHarness
  147. */
  148. fixture;
  149. /** @internal */
  150. constructor(fixture) {
  151. this.fixture = fixture;
  152. }
  153. /** Instructs the root fixture to run change detection. */
  154. detectChanges() {
  155. this.fixture.detectChanges();
  156. }
  157. /** The `DebugElement` of the `RouterOutlet` component. `null` if the outlet is not activated. */
  158. get routeDebugElement() {
  159. const outlet = this.fixture.componentInstance.outlet;
  160. if (!outlet || !outlet.isActivated) {
  161. return null;
  162. }
  163. return this.fixture.debugElement.query((v) => v.componentInstance === outlet.component);
  164. }
  165. /** The native element of the `RouterOutlet` component. `null` if the outlet is not activated. */
  166. get routeNativeElement() {
  167. return this.routeDebugElement?.nativeElement ?? null;
  168. }
  169. async navigateByUrl(url, requiredRoutedComponentType) {
  170. const router = TestBed.inject(Router);
  171. let resolveFn;
  172. const redirectTrackingPromise = new Promise((resolve) => {
  173. resolveFn = resolve;
  174. });
  175. afterNextNavigation(TestBed.inject(Router), resolveFn);
  176. await router.navigateByUrl(url);
  177. await redirectTrackingPromise;
  178. this.fixture.detectChanges();
  179. const outlet = this.fixture.componentInstance.outlet;
  180. // The outlet might not be activated if the user is testing a navigation for a guard that
  181. // rejects
  182. if (outlet && outlet.isActivated && outlet.activatedRoute.component) {
  183. const activatedComponent = outlet.component;
  184. if (requiredRoutedComponentType !== undefined &&
  185. !(activatedComponent instanceof requiredRoutedComponentType)) {
  186. throw new Error(`Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but got ${activatedComponent.constructor.name}`);
  187. }
  188. return activatedComponent;
  189. }
  190. else {
  191. if (requiredRoutedComponentType !== undefined) {
  192. throw new Error(`Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but the navigation did not activate any component.`);
  193. }
  194. return null;
  195. }
  196. }
  197. }
  198. export { RouterTestingHarness, RouterTestingModule, RouterOutlet as ɵɵRouterOutlet };
  199. //# sourceMappingURL=testing.mjs.map