@esmx/router 3.0.0-rc.29 → 3.0.0-rc.30

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 (59) hide show
  1. package/README.zh-CN.md +82 -1
  2. package/dist/index.d.ts +1 -2
  3. package/dist/index.mjs +0 -1
  4. package/package.json +3 -3
  5. package/src/index.ts +0 -3
  6. package/dist/index.test.d.ts +0 -1
  7. package/dist/index.test.mjs +0 -8
  8. package/dist/location.test.d.ts +0 -8
  9. package/dist/location.test.mjs +0 -370
  10. package/dist/matcher.test.d.ts +0 -1
  11. package/dist/matcher.test.mjs +0 -1492
  12. package/dist/micro-app.dom.test.d.ts +0 -1
  13. package/dist/micro-app.dom.test.mjs +0 -532
  14. package/dist/navigation.test.d.ts +0 -1
  15. package/dist/navigation.test.mjs +0 -681
  16. package/dist/route-task.test.d.ts +0 -1
  17. package/dist/route-task.test.mjs +0 -673
  18. package/dist/route-transition.test.d.ts +0 -1
  19. package/dist/route-transition.test.mjs +0 -146
  20. package/dist/route.test.d.ts +0 -1
  21. package/dist/route.test.mjs +0 -1664
  22. package/dist/router-back.test.d.ts +0 -1
  23. package/dist/router-back.test.mjs +0 -361
  24. package/dist/router-forward.test.d.ts +0 -1
  25. package/dist/router-forward.test.mjs +0 -376
  26. package/dist/router-go.test.d.ts +0 -1
  27. package/dist/router-go.test.mjs +0 -73
  28. package/dist/router-guards-cleanup.test.d.ts +0 -1
  29. package/dist/router-guards-cleanup.test.mjs +0 -437
  30. package/dist/router-push.test.d.ts +0 -1
  31. package/dist/router-push.test.mjs +0 -115
  32. package/dist/router-replace.test.d.ts +0 -1
  33. package/dist/router-replace.test.mjs +0 -114
  34. package/dist/router-resolve.test.d.ts +0 -1
  35. package/dist/router-resolve.test.mjs +0 -393
  36. package/dist/router-restart-app.dom.test.d.ts +0 -1
  37. package/dist/router-restart-app.dom.test.mjs +0 -616
  38. package/dist/router-window-navigation.test.d.ts +0 -1
  39. package/dist/router-window-navigation.test.mjs +0 -359
  40. package/dist/util.test.d.ts +0 -1
  41. package/dist/util.test.mjs +0 -1020
  42. package/src/index.test.ts +0 -9
  43. package/src/location.test.ts +0 -406
  44. package/src/matcher.test.ts +0 -1685
  45. package/src/micro-app.dom.test.ts +0 -708
  46. package/src/navigation.test.ts +0 -858
  47. package/src/route-task.test.ts +0 -901
  48. package/src/route-transition.test.ts +0 -178
  49. package/src/route.test.ts +0 -2014
  50. package/src/router-back.test.ts +0 -487
  51. package/src/router-forward.test.ts +0 -506
  52. package/src/router-go.test.ts +0 -91
  53. package/src/router-guards-cleanup.test.ts +0 -595
  54. package/src/router-push.test.ts +0 -140
  55. package/src/router-replace.test.ts +0 -139
  56. package/src/router-resolve.test.ts +0 -475
  57. package/src/router-restart-app.dom.test.ts +0 -783
  58. package/src/router-window-navigation.test.ts +0 -457
  59. package/src/util.test.ts +0 -1262
@@ -1,616 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { Router } from "./router.mjs";
3
- import { RouteType } from "./types.mjs";
4
- describe("Router.restartApp Focused Tests", () => {
5
- let router;
6
- let mockApps;
7
- beforeEach(async () => {
8
- mockApps = {
9
- home: vi.fn(() => ({ mount: vi.fn(), unmount: vi.fn() })),
10
- about: vi.fn(() => ({ mount: vi.fn(), unmount: vi.fn() })),
11
- user: vi.fn(() => ({ mount: vi.fn(), unmount: vi.fn() })),
12
- products: vi.fn(() => ({ mount: vi.fn(), unmount: vi.fn() }))
13
- };
14
- const options = {
15
- routes: [
16
- { path: "/", app: "home" },
17
- { path: "/about", app: "about" },
18
- { path: "/user/:id", app: "user" },
19
- { path: "/products/:category", app: "products" }
20
- ],
21
- apps: mockApps
22
- };
23
- router = new Router(options);
24
- await router.push("/");
25
- });
26
- afterEach(() => {
27
- router.destroy();
28
- vi.clearAllMocks();
29
- });
30
- describe("\u{1F3AF} Core Functionality Tests", () => {
31
- it("should support parameterless restart (restart to current path)", async () => {
32
- await router.push("/user/123");
33
- expect(router.route.url.pathname).toBe("/user/123");
34
- const result = await router.restartApp();
35
- expect(result.type).toBe(RouteType.restartApp);
36
- expect(result.url.pathname).toBe("/user/123");
37
- expect(result.handle).not.toBeNull();
38
- expect(router.route).toBe(result);
39
- });
40
- it("should support string path restart", async () => {
41
- const result = await router.restartApp("/about");
42
- expect(result.type).toBe(RouteType.restartApp);
43
- expect(result.url.pathname).toBe("/about");
44
- expect(result.handle).not.toBeNull();
45
- expect(router.route).toBe(result);
46
- });
47
- it("should support object parameter restart", async () => {
48
- const result = await router.restartApp({
49
- path: "/user/456",
50
- query: { tab: "profile", mode: "edit" },
51
- hash: "#section1"
52
- });
53
- expect(result.type).toBe(RouteType.restartApp);
54
- expect(result.url.pathname).toBe("/user/456");
55
- expect(result.query.tab).toBe("profile");
56
- expect(result.query.mode).toBe("edit");
57
- expect(result.url.hash).toBe("#section1");
58
- expect(result.params.id).toBe("456");
59
- expect(result.handle).not.toBeNull();
60
- });
61
- it("should support restart with state", async () => {
62
- const customState = { userId: 123, preferences: { theme: "dark" } };
63
- const result = await router.restartApp({
64
- path: "/about",
65
- state: customState
66
- });
67
- expect(result.state).toEqual(expect.objectContaining(customState));
68
- const state = result.state;
69
- expect(state.userId).toBe(123);
70
- expect(state.preferences.theme).toBe("dark");
71
- });
72
- it("should correctly handle route parameters", async () => {
73
- const result = await router.restartApp("/user/789");
74
- expect(result.params.id).toBe("789");
75
- expect(result.matched.length).toBeGreaterThan(0);
76
- expect(result.matched[0].path).toBe("/user/:id");
77
- });
78
- it("should correctly handle query parameters", async () => {
79
- const result = await router.restartApp("/about?tab=info&mode=edit");
80
- expect(result.query.tab).toBe("info");
81
- expect(result.query.mode).toBe("edit");
82
- expect(result.url.search).toBe("?tab=info&mode=edit");
83
- });
84
- it("should correctly handle hash", async () => {
85
- const result = await router.restartApp("/about#section2");
86
- expect(result.url.hash).toBe("#section2");
87
- });
88
- });
89
- describe("\u{1F504} restartApp-Specific Behavior Tests", () => {
90
- it("should force update MicroApp (even with same application)", async () => {
91
- await router.push("/about");
92
- const firstCallCount = mockApps.about.mock.calls.length;
93
- await router.restartApp("/about");
94
- const secondCallCount = mockApps.about.mock.calls.length;
95
- expect(secondCallCount).toBeGreaterThan(firstCallCount);
96
- });
97
- it("should call navigation.replace instead of push", async () => {
98
- const replaceSpy = vi.spyOn(router.navigation, "replace");
99
- const pushSpy = vi.spyOn(router.navigation, "push");
100
- await router.restartApp("/about");
101
- expect(replaceSpy).toHaveBeenCalled();
102
- expect(pushSpy).not.toHaveBeenCalled();
103
- });
104
- it("should correctly update router current route state", async () => {
105
- const result = await router.restartApp("/about");
106
- expect(router.route.url.pathname).toBe("/about");
107
- expect(router.route.type).toBe(RouteType.restartApp);
108
- expect(router.route).toBe(result);
109
- });
110
- it("should differentiate from other routing method behaviors", async () => {
111
- await router.push("/user/123");
112
- expect(router.route.type).toBe(RouteType.push);
113
- await router.replace("/about");
114
- expect(router.route.type).toBe(RouteType.replace);
115
- const result = await router.restartApp("/products/electronics");
116
- expect(result.type).toBe(RouteType.restartApp);
117
- expect(router.route.type).toBe(RouteType.restartApp);
118
- });
119
- });
120
- describe("\u{1F3AD} Edge Cases Tests", () => {
121
- it("should handle non-existent routes", async () => {
122
- const result = await router.restartApp("/nonexistent");
123
- expect(result.matched.length).toBe(0);
124
- expect(result.config).toBeNull();
125
- expect(result.url.pathname).toBe("/nonexistent");
126
- expect(result.type).toBe(RouteType.restartApp);
127
- });
128
- it("should handle empty string path", async () => {
129
- const result = await router.restartApp("");
130
- expect(result.url.pathname).toBe("/");
131
- expect(result.type).toBe(RouteType.restartApp);
132
- });
133
- it("should handle root path", async () => {
134
- const result = await router.restartApp("/");
135
- expect(result.url.pathname).toBe("/");
136
- expect(result.matched.length).toBeGreaterThan(0);
137
- expect(result.type).toBe(RouteType.restartApp);
138
- });
139
- it("should handle complex query parameters", async () => {
140
- const result = await router.restartApp("/about?a=1&b=2&a=3&c=");
141
- expect(result.query.b).toBe("2");
142
- expect(result.query.c).toBe("");
143
- expect(result.url.search).toContain("a=");
144
- expect(result.url.search).toContain("b=2");
145
- });
146
- it("should handle special character paths", async () => {
147
- const result = await router.restartApp("/user/\u6D4B\u8BD5\u7528\u6237");
148
- expect(result.url.pathname).toContain("/user/");
149
- expect(decodeURIComponent(result.params.id)).toBe("\u6D4B\u8BD5\u7528\u6237");
150
- });
151
- });
152
- describe("\u{1F517} URL Parsing Tests", () => {
153
- it("should correctly parse absolute paths", async () => {
154
- await router.push("/user/123");
155
- const result = await router.restartApp("/about");
156
- expect(result.url.pathname).toBe("/about");
157
- expect(result.url.href).toMatch(/\/about$/);
158
- });
159
- it("should correctly handle relative paths", async () => {
160
- await router.push("/user/123");
161
- const result = await router.restartApp("456");
162
- expect(result.url.pathname).toContain("456");
163
- if (result.matched.length > 0 && result.matched[0].path === "/user/:id") {
164
- expect(result.params.id).toBe("456");
165
- }
166
- });
167
- it("should correctly handle complete URLs", async () => {
168
- const result = await router.restartApp("http://example.com/test");
169
- expect(result.url.href).toBe("http://example.com/test");
170
- expect(result.url.pathname).toBe("/test");
171
- });
172
- });
173
- describe("\u{1F3AF} Type Overload Tests", () => {
174
- it("should support parameterless calls", async () => {
175
- await router.push("/user/123");
176
- const result = await router.restartApp();
177
- expect(result.url.pathname).toBe("/user/123");
178
- expect(result.type).toBe(RouteType.restartApp);
179
- });
180
- it("should support string parameter calls", async () => {
181
- const result = await router.restartApp("/about");
182
- expect(result.url.pathname).toBe("/about");
183
- expect(result.type).toBe(RouteType.restartApp);
184
- });
185
- it("should support object parameter calls", async () => {
186
- const routeLocation = {
187
- path: "/user/456",
188
- query: { tab: "settings" }
189
- };
190
- const result = await router.restartApp(routeLocation);
191
- expect(result.url.pathname).toBe("/user/456");
192
- expect(result.query.tab).toBe("settings");
193
- expect(result.type).toBe(RouteType.restartApp);
194
- });
195
- });
196
- describe("\u{1F504} Multiple Restart Tests", () => {
197
- it("should support consecutive multiple restarts", async () => {
198
- const paths = ["/about", "/user/123", "/products/electronics", "/"];
199
- for (const path of paths) {
200
- const result = await router.restartApp(path);
201
- expect(result.type).toBe(RouteType.restartApp);
202
- expect(result.handle).not.toBeNull();
203
- expect(router.route).toBe(result);
204
- }
205
- });
206
- it("should create new application instances on each restart", async () => {
207
- await router.restartApp("/about");
208
- const firstCallCount = mockApps.about.mock.calls.length;
209
- await router.restartApp("/about");
210
- const secondCallCount = mockApps.about.mock.calls.length;
211
- await router.restartApp("/about");
212
- const thirdCallCount = mockApps.about.mock.calls.length;
213
- expect(secondCallCount).toBeGreaterThan(firstCallCount);
214
- expect(thirdCallCount).toBeGreaterThan(secondCallCount);
215
- });
216
- });
217
- describe("\u{1F3A8} Status Code Handling Tests", () => {
218
- it("should support custom status codes", async () => {
219
- const result = await router.restartApp({
220
- path: "/about",
221
- statusCode: 201
222
- });
223
- expect(result.statusCode).toBe(201);
224
- });
225
- it("should maintain default status code as null", async () => {
226
- const result = await router.restartApp("/about");
227
- expect(result.statusCode).toBeNull();
228
- });
229
- });
230
- describe("\u{1F527} Consistency Tests with resolve Method", () => {
231
- it("should maintain consistency with resolve method results in URL parsing", async () => {
232
- const resolvedRoute = router.resolve("/user/789");
233
- const restartedRoute = await router.restartApp("/user/789");
234
- expect(restartedRoute.url.href).toBe(resolvedRoute.url.href);
235
- expect(restartedRoute.params).toEqual(resolvedRoute.params);
236
- expect(restartedRoute.matched).toEqual(resolvedRoute.matched);
237
- expect(restartedRoute.type).toBe(RouteType.restartApp);
238
- expect(resolvedRoute.type).toBe(RouteType.push);
239
- });
240
- });
241
- describe("\u{1F6E1}\uFE0F Route Guards Integration Tests", () => {
242
- let guardExecutionLog;
243
- beforeEach(() => {
244
- guardExecutionLog = [];
245
- });
246
- it("should correctly execute beforeEach guards", async () => {
247
- const unregister = router.beforeEach(async (to, from) => {
248
- guardExecutionLog.push(
249
- "beforeEach-".concat(to.path, "-from-").concat((from == null ? void 0 : from.path) || "null")
250
- );
251
- });
252
- await router.restartApp("/about");
253
- expect(guardExecutionLog).toContain("beforeEach-/about-from-/");
254
- unregister();
255
- });
256
- it("should correctly execute afterEach guards", async () => {
257
- const unregister = router.afterEach((to, from) => {
258
- guardExecutionLog.push(
259
- "afterEach-".concat(to.path, "-from-").concat((from == null ? void 0 : from.path) || "null")
260
- );
261
- });
262
- await router.restartApp("/about");
263
- expect(guardExecutionLog).toContain("afterEach-/about-from-/");
264
- unregister();
265
- });
266
- it("should abort restart when beforeEach guard returns false", async () => {
267
- const unregister = router.beforeEach(async (to, from) => {
268
- if (to.path === "/about") {
269
- return false;
270
- }
271
- });
272
- await expect(router.restartApp("/about")).rejects.toThrow();
273
- expect(router.route.path).toBe("/");
274
- unregister();
275
- });
276
- it("should support guard redirects", async () => {
277
- const unregister = router.beforeEach(async (to, from) => {
278
- if (to.path === "/about") {
279
- return "/user/redirected";
280
- }
281
- });
282
- const result = await router.restartApp("/about");
283
- expect(result.path).toBe("/user/redirected");
284
- expect(result.params.id).toBe("redirected");
285
- expect(result.handle).not.toBeNull();
286
- unregister();
287
- });
288
- });
289
- describe("\u{1F9E9} Async Component Handling Tests", () => {
290
- let asyncRouter;
291
- beforeEach(async () => {
292
- const asyncOptions = {
293
- routes: [
294
- {
295
- path: "/",
296
- app: "home",
297
- component: () => "HomeComponent"
298
- },
299
- {
300
- path: "/async",
301
- app: "async",
302
- asyncComponent: async () => {
303
- await new Promise(
304
- (resolve) => setTimeout(resolve, 10)
305
- );
306
- return () => "AsyncComponent";
307
- }
308
- },
309
- {
310
- path: "/async-error",
311
- app: "async-error",
312
- asyncComponent: async () => {
313
- throw new Error("Component load failed");
314
- }
315
- }
316
- ],
317
- apps: mockApps
318
- };
319
- asyncRouter = new Router(asyncOptions);
320
- await asyncRouter.push("/");
321
- });
322
- afterEach(() => {
323
- asyncRouter.destroy();
324
- });
325
- it("should correctly handle async component loading", async () => {
326
- const result = await asyncRouter.restartApp("/async");
327
- expect(result.handle).not.toBeNull();
328
- expect(result.matched[0].component).toBeDefined();
329
- expect(typeof result.matched[0].component).toBe("function");
330
- });
331
- it("should handle async component loading failures", async () => {
332
- await expect(
333
- asyncRouter.restartApp("/async-error")
334
- ).rejects.toThrow();
335
- });
336
- });
337
- describe("\u26A1 Task Cancellation and Concurrency Control Tests", () => {
338
- it("should cancel tasks interrupted by new restartApp calls", async () => {
339
- const unregister = router.beforeEach(async (to, from) => {
340
- if (to.path === "/user/slow") {
341
- await new Promise((resolve) => setTimeout(resolve, 50));
342
- }
343
- });
344
- const promises = [
345
- router.restartApp("/user/slow").catch((err) => err),
346
- router.restartApp("/about").catch((err) => err)
347
- ];
348
- const results = await Promise.all(promises);
349
- expect(results[0] instanceof Error).toBe(true);
350
- expect(results[1].handle).not.toBeNull();
351
- expect(router.route.path).toBe("/about");
352
- unregister();
353
- });
354
- it("should correctly handle multiple concurrent restartApp calls", async () => {
355
- const paths = ["/user/1", "/user/2", "/user/3"];
356
- const promises = paths.map(
357
- (path) => router.restartApp(path).catch((err) => err)
358
- );
359
- const results = await Promise.all(promises);
360
- expect(results[0] instanceof Error).toBe(true);
361
- expect(results[1] instanceof Error).toBe(true);
362
- expect(results[2].handle).not.toBeNull();
363
- expect(router.route.path).toBe("/user/3");
364
- });
365
- });
366
- describe("\u{1F30D} Route Override Tests", () => {
367
- let overrideRouter;
368
- beforeEach(async () => {
369
- const overrideOptions = {
370
- routes: [
371
- {
372
- path: "/",
373
- app: "home",
374
- component: () => "HomeComponent"
375
- },
376
- {
377
- path: "/override-test",
378
- app: "override",
379
- component: () => "OverrideComponent",
380
- override: (to, from) => {
381
- if (to.query.native === "true") {
382
- return async () => {
383
- return { native: true, path: to.path };
384
- };
385
- }
386
- }
387
- },
388
- {
389
- path: "/hybrid-page",
390
- app: "hybrid",
391
- component: () => "HybridComponent",
392
- override: (to, from) => {
393
- return async () => {
394
- return {
395
- hybrid: "native",
396
- component: "NativeComponent"
397
- };
398
- };
399
- }
400
- }
401
- ],
402
- apps: mockApps
403
- };
404
- overrideRouter = new Router(overrideOptions);
405
- await overrideRouter.push("/");
406
- });
407
- afterEach(() => {
408
- overrideRouter.destroy();
409
- });
410
- it("should use override when condition is met", async () => {
411
- var _a;
412
- const result = await overrideRouter.restartApp(
413
- "/override-test?native=true"
414
- );
415
- expect(result.handle).not.toBeNull();
416
- expect(result.handleResult).toBeUndefined();
417
- expect((_a = result.config) == null ? void 0 : _a.override).toBeDefined();
418
- });
419
- it("should use default behavior when override returns nothing", async () => {
420
- const result = await overrideRouter.restartApp(
421
- "/override-test?native=false"
422
- );
423
- expect(result.handle).not.toBeNull();
424
- expect(result.handle).not.toBeNull();
425
- });
426
- it("should always use override when function always returns handler", async () => {
427
- var _a;
428
- const result = await overrideRouter.restartApp("/hybrid-page");
429
- expect(result.handle).not.toBeNull();
430
- expect(result.handleResult).toBeUndefined();
431
- expect((_a = result.config) == null ? void 0 : _a.override).toBeDefined();
432
- });
433
- });
434
- describe("\u274C Error Handling and Exception Scenario Tests", () => {
435
- it("should handle exceptions thrown in guards", async () => {
436
- const unregister = router.beforeEach(async (to, from) => {
437
- if (to.path === "/about") {
438
- throw new Error("Guard error");
439
- }
440
- });
441
- await expect(router.restartApp("/about")).rejects.toThrow(
442
- "Guard error"
443
- );
444
- unregister();
445
- });
446
- it("should handle MicroApp update exceptions", async () => {
447
- const originalUpdate = router.microApp._update;
448
- router.microApp._update = vi.fn().mockImplementation(() => {
449
- throw new Error("MicroApp update failed");
450
- });
451
- await expect(router.restartApp("/about")).rejects.toThrow(
452
- "MicroApp update failed"
453
- );
454
- router.microApp._update = originalUpdate;
455
- });
456
- it("should handle navigation.replace exceptions", async () => {
457
- const originalReplace = router.navigation.replace;
458
- router.navigation.replace = vi.fn().mockImplementation(() => {
459
- throw new Error("Navigation replace failed");
460
- });
461
- await expect(router.restartApp("/about")).rejects.toThrow(
462
- "Navigation replace failed"
463
- );
464
- router.navigation.replace = originalReplace;
465
- });
466
- });
467
- describe("\u{1F504} Route Lifecycle Integrity Tests", () => {
468
- let lifecycleRouter;
469
- let lifecycleLog;
470
- beforeEach(async () => {
471
- lifecycleLog = [];
472
- const lifecycleOptions = {
473
- routes: [
474
- {
475
- path: "/",
476
- app: "home",
477
- component: () => "HomeComponent",
478
- beforeLeave: async (to, from) => {
479
- lifecycleLog.push("home-beforeLeave");
480
- }
481
- },
482
- {
483
- path: "/lifecycle",
484
- app: "lifecycle",
485
- component: () => "LifecycleComponent",
486
- beforeEnter: async (to, from) => {
487
- lifecycleLog.push("lifecycle-beforeEnter");
488
- },
489
- beforeUpdate: async (to, from) => {
490
- lifecycleLog.push("lifecycle-beforeUpdate");
491
- },
492
- beforeLeave: async (to, from) => {
493
- lifecycleLog.push("lifecycle-beforeLeave");
494
- }
495
- }
496
- ],
497
- apps: mockApps
498
- };
499
- lifecycleRouter = new Router(lifecycleOptions);
500
- await lifecycleRouter.push("/");
501
- });
502
- afterEach(() => {
503
- lifecycleRouter.destroy();
504
- });
505
- it("should correctly execute complete route lifecycle", async () => {
506
- const unregisterBefore = lifecycleRouter.beforeEach((to, from) => {
507
- lifecycleLog.push("global-beforeEach-".concat(to.path));
508
- });
509
- const unregisterAfter = lifecycleRouter.afterEach((to, from) => {
510
- lifecycleLog.push("global-afterEach-".concat(to.path));
511
- });
512
- await lifecycleRouter.restartApp("/lifecycle");
513
- expect(lifecycleLog).toEqual([
514
- "home-beforeLeave",
515
- "global-beforeEach-/lifecycle",
516
- "lifecycle-beforeEnter",
517
- "global-afterEach-/lifecycle"
518
- ]);
519
- unregisterBefore();
520
- unregisterAfter();
521
- });
522
- it("should execute beforeUpdate when restarting same route", async () => {
523
- await lifecycleRouter.push("/lifecycle");
524
- lifecycleLog = [];
525
- await lifecycleRouter.restartApp("/lifecycle?version=2");
526
- expect(lifecycleLog).toContain("lifecycle-beforeUpdate");
527
- expect(lifecycleLog).not.toContain("lifecycle-beforeEnter");
528
- });
529
- });
530
- describe("\u{1F3AF} Special Route Configuration Tests", () => {
531
- it("should handle routes with custom location handler", async () => {
532
- let locationCalled = false;
533
- const customLocationRouter = new Router({
534
- routes: [{ path: "/", app: "home" }],
535
- apps: mockApps,
536
- fallback: (to, from) => {
537
- locationCalled = true;
538
- return { customLocation: true, path: to.path };
539
- }
540
- });
541
- await customLocationRouter.push("/");
542
- const result = await customLocationRouter.restartApp("/nonexistent");
543
- expect(locationCalled).toBe(true);
544
- expect(result.matched.length).toBe(0);
545
- expect(typeof result.handle).toBe("function");
546
- expect(result.handleResult).toEqual({
547
- customLocation: true,
548
- path: "/nonexistent"
549
- });
550
- customLocationRouter.destroy();
551
- });
552
- it("should handle complex nested route restarts", async () => {
553
- const nestedRouter = new Router({
554
- routes: [
555
- {
556
- path: "/",
557
- app: "home",
558
- children: [
559
- {
560
- path: "nested/:id",
561
- app: "nested",
562
- children: [
563
- {
564
- path: "deep/:subId",
565
- app: "deep"
566
- }
567
- ]
568
- }
569
- ]
570
- }
571
- ],
572
- apps: mockApps
573
- });
574
- await nestedRouter.push("/");
575
- const result = await nestedRouter.restartApp(
576
- "/nested/123/deep/456"
577
- );
578
- expect(result.params.id).toBe("123");
579
- expect(result.params.subId).toBe("456");
580
- expect(result.matched.length).toBe(3);
581
- nestedRouter.destroy();
582
- });
583
- });
584
- describe("\u{1F4CA} Performance and Memory Tests", () => {
585
- it("should correctly clean up resources after extensive restarts", async () => {
586
- const initialAppsCallCount = Object.values(mockApps).reduce(
587
- (sum, app) => sum + app.mock.calls.length,
588
- 0
589
- );
590
- for (let i = 0; i < 50; i++) {
591
- await router.restartApp("/user/".concat(i));
592
- }
593
- const finalAppsCallCount = Object.values(mockApps).reduce(
594
- (sum, app) => sum + app.mock.calls.length,
595
- 0
596
- );
597
- expect(finalAppsCallCount).toBeGreaterThan(initialAppsCallCount);
598
- expect(router.route.params.id).toBe("49");
599
- });
600
- it("should correctly handle rapid consecutive restart calls", async () => {
601
- const startTime = Date.now();
602
- const promises = Array.from(
603
- { length: 10 },
604
- (_, i) => router.restartApp("/user/".concat(i)).catch((err) => err)
605
- );
606
- const results = await Promise.all(promises);
607
- const endTime = Date.now();
608
- const successfulResults = results.filter(
609
- (r) => !(r instanceof Error) && r.handle !== null
610
- );
611
- expect(successfulResults).toHaveLength(1);
612
- expect(successfulResults[0].params.id).toBe("9");
613
- expect(endTime - startTime).toBeLessThan(1e3);
614
- });
615
- });
616
- });
@@ -1 +0,0 @@
1
- export {};