UNPKG

11 kBJavaScriptView Raw
1/**
2 * @license Angular v15.2.3
3 * (c) 2010-2022 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { Location } from '@angular/common';
8import { provideLocationMocks } from '@angular/common/testing';
9import * as i0 from '@angular/core';
10import { inject, Compiler, Injector, NgModule, Injectable, Component, ViewChild } from '@angular/core';
11import { UrlSerializer, ChildrenOutletContexts, ROUTES, UrlHandlingStrategy, ROUTER_CONFIGURATION, RouteReuseStrategy, TitleStrategy, Router, RouterModule, ɵROUTER_PROVIDERS, ɵwithPreloading, NoPreloading, RouterOutlet, ɵafterNextNavigation } from '@angular/router';
12import { TestBed } from '@angular/core/testing';
13
14function isUrlHandlingStrategy(opts) {
15 // This property check is needed because UrlHandlingStrategy is an interface and doesn't exist at
16 // runtime.
17 return 'shouldProcessUrl' in opts;
18}
19function throwInvalidConfigError(parameter) {
20 throw new Error(`Parameter ${parameter} does not match the one available in the injector. ` +
21 '`setupTestingRouter` is meant to be used as a factory function with dependencies coming from DI.');
22}
23/**
24 * Router setup factory function used for testing.
25 *
26 * @publicApi
27 * @deprecated Use `provideRouter` or `RouterTestingModule` instead.
28 */
29function setupTestingRouter(urlSerializer, contexts, location, compiler, injector, routes, opts, urlHandlingStrategy, routeReuseStrategy, titleStrategy) {
30 // Note: The checks below are to detect misconfigured providers and invalid uses of
31 // `setupTestingRouter`. This function is not used internally (neither in router code or anywhere
32 // in g3). It appears this function was exposed as publicApi by mistake and should not be used
33 // externally either. However, if it is, the documented intent is to be used as a factory function
34 // and parameter values should always match what's available in DI.
35 if (urlSerializer !== inject(UrlSerializer)) {
36 throwInvalidConfigError('urlSerializer');
37 }
38 if (contexts !== inject(ChildrenOutletContexts)) {
39 throwInvalidConfigError('contexts');
40 }
41 if (location !== inject(Location)) {
42 throwInvalidConfigError('location');
43 }
44 if (compiler !== inject(Compiler)) {
45 throwInvalidConfigError('compiler');
46 }
47 if (injector !== inject(Injector)) {
48 throwInvalidConfigError('injector');
49 }
50 if (routes !== inject(ROUTES)) {
51 throwInvalidConfigError('routes');
52 }
53 if (opts) {
54 // Handle deprecated argument ordering.
55 if (isUrlHandlingStrategy(opts)) {
56 if (opts !== inject(UrlHandlingStrategy)) {
57 throwInvalidConfigError('opts (UrlHandlingStrategy)');
58 }
59 }
60 else {
61 if (opts !== inject(ROUTER_CONFIGURATION)) {
62 throwInvalidConfigError('opts (ROUTER_CONFIGURATION)');
63 }
64 }
65 }
66 if (urlHandlingStrategy !== inject(UrlHandlingStrategy)) {
67 throwInvalidConfigError('urlHandlingStrategy');
68 }
69 if (routeReuseStrategy !== inject(RouteReuseStrategy)) {
70 throwInvalidConfigError('routeReuseStrategy');
71 }
72 if (titleStrategy !== inject(TitleStrategy)) {
73 throwInvalidConfigError('titleStrategy');
74 }
75 return new Router();
76}
77/**
78 * @description
79 *
80 * Sets up the router to be used for testing.
81 *
82 * The modules sets up the router to be used for testing.
83 * It provides spy implementations of `Location` and `LocationStrategy`.
84 *
85 * @usageNotes
86 * ### Example
87 *
88 * ```
89 * beforeEach(() => {
90 * TestBed.configureTestingModule({
91 * imports: [
92 * RouterTestingModule.withRoutes(
93 * [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]
94 * )
95 * ]
96 * });
97 * });
98 * ```
99 *
100 * @publicApi
101 */
102class RouterTestingModule {
103 static withRoutes(routes, config) {
104 return {
105 ngModule: RouterTestingModule,
106 providers: [
107 { provide: ROUTES, multi: true, useValue: routes },
108 { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
109 ]
110 };
111 }
112}
113RouterTestingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RouterTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
114RouterTestingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.3", ngImport: i0, type: RouterTestingModule, exports: [RouterModule] });
115RouterTestingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RouterTestingModule, providers: [
116 ɵROUTER_PROVIDERS,
117 provideLocationMocks(),
118 ɵwithPreloading(NoPreloading).ɵproviders,
119 { provide: ROUTES, multi: true, useValue: [] },
120 ], imports: [RouterModule] });
121i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RouterTestingModule, decorators: [{
122 type: NgModule,
123 args: [{
124 exports: [RouterModule],
125 providers: [
126 ɵROUTER_PROVIDERS,
127 provideLocationMocks(),
128 ɵwithPreloading(NoPreloading).ɵproviders,
129 { provide: ROUTES, multi: true, useValue: [] },
130 ]
131 }]
132 }] });
133
134class RootFixtureService {
135 createHarness() {
136 if (this.harness) {
137 throw new Error('Only one harness should be created per test.');
138 }
139 this.harness = new RouterTestingHarness(this.getRootFixture());
140 return this.harness;
141 }
142 getRootFixture() {
143 if (this.fixture !== undefined) {
144 return this.fixture;
145 }
146 this.fixture = TestBed.createComponent(RootCmp);
147 this.fixture.detectChanges();
148 return this.fixture;
149 }
150}
151RootFixtureService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RootFixtureService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
152RootFixtureService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RootFixtureService, providedIn: 'root' });
153i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RootFixtureService, decorators: [{
154 type: Injectable,
155 args: [{ providedIn: 'root' }]
156 }] });
157class RootCmp {
158}
159RootCmp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RootCmp, deps: [], target: i0.ɵɵFactoryTarget.Component });
160RootCmp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: RootCmp, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "outlet", first: true, predicate: RouterOutlet, descendants: true }], ngImport: i0, template: '<router-outlet></router-outlet>', isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
161i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: RootCmp, decorators: [{
162 type: Component,
163 args: [{
164 standalone: true,
165 template: '<router-outlet></router-outlet>',
166 imports: [RouterOutlet],
167 }]
168 }], propDecorators: { outlet: [{
169 type: ViewChild,
170 args: [RouterOutlet]
171 }] } });
172/**
173 * A testing harness for the `Router` to reduce the boilerplate needed to test routes and routed
174 * components.
175 *
176 * @publicApi
177 */
178class RouterTestingHarness {
179 /**
180 * Creates a `RouterTestingHarness` instance.
181 *
182 * The `RouterTestingHarness` also creates its own root component with a `RouterOutlet` for the
183 * purposes of rendering route components.
184 *
185 * Throws an error if an instance has already been created.
186 * Use of this harness also requires `destroyAfterEach: true` in the `ModuleTeardownOptions`
187 *
188 * @param initialUrl The target of navigation to trigger before returning the harness.
189 */
190 static async create(initialUrl) {
191 const harness = TestBed.inject(RootFixtureService).createHarness();
192 if (initialUrl !== undefined) {
193 await harness.navigateByUrl(initialUrl);
194 }
195 return harness;
196 }
197 /** @internal */
198 constructor(fixture) {
199 this.fixture = fixture;
200 }
201 /** Instructs the root fixture to run change detection. */
202 detectChanges() {
203 this.fixture.detectChanges();
204 }
205 /** The `DebugElement` of the `RouterOutlet` component. `null` if the outlet is not activated. */
206 get routeDebugElement() {
207 const outlet = this.fixture.componentInstance.outlet;
208 if (!outlet || !outlet.isActivated) {
209 return null;
210 }
211 return this.fixture.debugElement.query(v => v.componentInstance === outlet.component);
212 }
213 /** The native element of the `RouterOutlet` component. `null` if the outlet is not activated. */
214 get routeNativeElement() {
215 return this.routeDebugElement?.nativeElement ?? null;
216 }
217 async navigateByUrl(url, requiredRoutedComponentType) {
218 const router = TestBed.inject(Router);
219 let resolveFn;
220 const redirectTrackingPromise = new Promise(resolve => {
221 resolveFn = resolve;
222 });
223 ɵafterNextNavigation(TestBed.inject(Router), resolveFn);
224 await router.navigateByUrl(url);
225 await redirectTrackingPromise;
226 this.fixture.detectChanges();
227 const outlet = this.fixture.componentInstance.outlet;
228 // The outlet might not be activated if the user is testing a navigation for a guard that
229 // rejects
230 if (outlet && outlet.isActivated && outlet.activatedRoute.component) {
231 const activatedComponent = outlet.component;
232 if (requiredRoutedComponentType !== undefined &&
233 !(activatedComponent instanceof requiredRoutedComponentType)) {
234 throw new Error(`Unexpected routed component type. Expected ${requiredRoutedComponentType.name} but got ${activatedComponent.constructor.name}`);
235 }
236 return activatedComponent;
237 }
238 else {
239 return null;
240 }
241 }
242}
243
244/**
245 * @module
246 * @description
247 * Entry point for all public APIs of the router/testing package.
248 */
249
250/**
251 * @module
252 * @description
253 * Entry point for all public APIs of this package.
254 */
255// This file only reexports content of the `src` folder. Keep it that way.
256
257// This file is not used to build this module. It is only used during editing
258
259/**
260 * Generated bundle index. Do not edit.
261 */
262
263export { RouterTestingHarness, RouterTestingModule, setupTestingRouter };
264//# sourceMappingURL=testing.mjs.map