@esmx/router 3.0.0-rc.27 → 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 +4 -4
  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,437 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
2
- import { Router } from "./router.mjs";
3
- import { RouterMode } from "./types.mjs";
4
- import { removeFromArray } from "./util.mjs";
5
- describe("Router Guards Cleanup Tests", () => {
6
- let router;
7
- beforeEach(async () => {
8
- router = new Router({
9
- mode: RouterMode.memory,
10
- base: new URL("http://localhost:3000/"),
11
- routes: [
12
- {
13
- path: "/",
14
- component: () => "Home"
15
- },
16
- {
17
- path: "/test1",
18
- component: () => "Test1"
19
- },
20
- {
21
- path: "/test2",
22
- component: () => "Test2"
23
- },
24
- {
25
- path: "/test3",
26
- component: () => "Test3"
27
- }
28
- ]
29
- });
30
- await router.replace("/");
31
- });
32
- afterEach(() => {
33
- router.destroy();
34
- });
35
- describe("\u{1F525} Guard Cleanup Effect Verification", () => {
36
- describe("beforeEach cleanup effects", () => {
37
- test("guard should not execute after cleanup", async () => {
38
- const spy = vi.fn();
39
- const unregister = router.beforeEach(spy);
40
- await router.push("/test1");
41
- expect(spy).toHaveBeenCalledTimes(1);
42
- unregister();
43
- await router.push("/test2");
44
- expect(spy).toHaveBeenCalledTimes(1);
45
- });
46
- test("guard should not execute after cleanup for multiple navigations", async () => {
47
- const spy = vi.fn();
48
- const unregister = router.beforeEach(spy);
49
- await router.push("/test1");
50
- expect(spy).toHaveBeenCalledTimes(1);
51
- unregister();
52
- await router.push("/test2");
53
- await router.push("/test3");
54
- await router.push("/");
55
- expect(spy).toHaveBeenCalledTimes(1);
56
- });
57
- test("async guard should not execute after cleanup", async () => {
58
- const spy = vi.fn();
59
- const asyncGuard = async (to, from) => {
60
- await new Promise((resolve) => setTimeout(resolve, 10));
61
- spy(to, from);
62
- };
63
- const unregister = router.beforeEach(asyncGuard);
64
- await router.push("/test1");
65
- expect(spy).toHaveBeenCalledTimes(1);
66
- unregister();
67
- await router.push("/test2");
68
- expect(spy).toHaveBeenCalledTimes(1);
69
- });
70
- });
71
- describe("afterEach cleanup effects", () => {
72
- test("guard should not execute after cleanup", async () => {
73
- const spy = vi.fn();
74
- const unregister = router.afterEach(spy);
75
- await router.push("/test1");
76
- expect(spy).toHaveBeenCalledTimes(1);
77
- unregister();
78
- await router.push("/test2");
79
- expect(spy).toHaveBeenCalledTimes(1);
80
- });
81
- test("guard should not execute after cleanup for multiple navigations", async () => {
82
- const spy = vi.fn();
83
- const unregister = router.afterEach(spy);
84
- await router.push("/test1");
85
- expect(spy).toHaveBeenCalledTimes(1);
86
- unregister();
87
- await router.push("/test2");
88
- await router.push("/test3");
89
- await router.push("/");
90
- expect(spy).toHaveBeenCalledTimes(1);
91
- });
92
- });
93
- });
94
- describe("\u26A1 Multiple Guards Independent Cleanup", () => {
95
- describe("beforeEach multiple guards cleanup", () => {
96
- test("cleaning single guard should not affect other guards", async () => {
97
- const spy1 = vi.fn();
98
- const spy2 = vi.fn();
99
- const spy3 = vi.fn();
100
- const unregister1 = router.beforeEach(spy1);
101
- const unregister2 = router.beforeEach(spy2);
102
- const unregister3 = router.beforeEach(spy3);
103
- await router.push("/test1");
104
- expect(spy1).toHaveBeenCalledTimes(1);
105
- expect(spy2).toHaveBeenCalledTimes(1);
106
- expect(spy3).toHaveBeenCalledTimes(1);
107
- unregister2();
108
- await router.push("/test2");
109
- expect(spy1).toHaveBeenCalledTimes(2);
110
- expect(spy2).toHaveBeenCalledTimes(1);
111
- expect(spy3).toHaveBeenCalledTimes(2);
112
- unregister1();
113
- unregister3();
114
- });
115
- test("cleaning multiple guards should work correctly", async () => {
116
- const spy1 = vi.fn();
117
- const spy2 = vi.fn();
118
- const spy3 = vi.fn();
119
- const spy4 = vi.fn();
120
- const unregister1 = router.beforeEach(spy1);
121
- const unregister2 = router.beforeEach(spy2);
122
- const unregister3 = router.beforeEach(spy3);
123
- const unregister4 = router.beforeEach(spy4);
124
- await router.push("/test1");
125
- expect(spy1).toHaveBeenCalledTimes(1);
126
- expect(spy2).toHaveBeenCalledTimes(1);
127
- expect(spy3).toHaveBeenCalledTimes(1);
128
- expect(spy4).toHaveBeenCalledTimes(1);
129
- unregister1();
130
- unregister3();
131
- spy1.mockClear();
132
- spy2.mockClear();
133
- spy3.mockClear();
134
- spy4.mockClear();
135
- await router.push("/test2");
136
- expect(spy1).not.toHaveBeenCalled();
137
- expect(spy2).toHaveBeenCalledTimes(1);
138
- expect(spy3).not.toHaveBeenCalled();
139
- expect(spy4).toHaveBeenCalledTimes(1);
140
- unregister2();
141
- unregister4();
142
- });
143
- test("guard execution order should remain correct after cleanup", async () => {
144
- const executionOrder = [];
145
- const guard1 = () => {
146
- executionOrder.push("guard1");
147
- };
148
- const guard2 = () => {
149
- executionOrder.push("guard2");
150
- };
151
- const guard3 = () => {
152
- executionOrder.push("guard3");
153
- };
154
- router.beforeEach(guard1);
155
- const unregister2 = router.beforeEach(guard2);
156
- router.beforeEach(guard3);
157
- await router.push("/test1");
158
- expect(executionOrder).toEqual(["guard1", "guard2", "guard3"]);
159
- executionOrder.length = 0;
160
- unregister2();
161
- await router.push("/test2");
162
- expect(executionOrder).toEqual(["guard1", "guard3"]);
163
- });
164
- });
165
- describe("afterEach multiple guards cleanup", () => {
166
- test("cleaning single afterEach guard should not affect other guards", async () => {
167
- const spy1 = vi.fn();
168
- const spy2 = vi.fn();
169
- const spy3 = vi.fn();
170
- const unregister1 = router.afterEach(spy1);
171
- const unregister2 = router.afterEach(spy2);
172
- const unregister3 = router.afterEach(spy3);
173
- await router.push("/test1");
174
- expect(spy1).toHaveBeenCalledTimes(1);
175
- expect(spy2).toHaveBeenCalledTimes(1);
176
- expect(spy3).toHaveBeenCalledTimes(1);
177
- unregister2();
178
- await router.push("/test2");
179
- expect(spy1).toHaveBeenCalledTimes(2);
180
- expect(spy2).toHaveBeenCalledTimes(1);
181
- expect(spy3).toHaveBeenCalledTimes(2);
182
- unregister1();
183
- unregister3();
184
- });
185
- test("afterEach guard execution order should remain correct after cleanup", async () => {
186
- const executionOrder = [];
187
- const guard1 = () => {
188
- executionOrder.push("after1");
189
- };
190
- const guard2 = () => {
191
- executionOrder.push("after2");
192
- };
193
- const guard3 = () => {
194
- executionOrder.push("after3");
195
- };
196
- router.afterEach(guard1);
197
- const unregister2 = router.afterEach(guard2);
198
- router.afterEach(guard3);
199
- await router.push("/test1");
200
- expect(executionOrder).toEqual(["after1", "after2", "after3"]);
201
- executionOrder.length = 0;
202
- unregister2();
203
- await router.push("/test2");
204
- expect(executionOrder).toEqual(["after1", "after3"]);
205
- });
206
- });
207
- describe("mixed guards cleanup", () => {
208
- test("beforeEach and afterEach guards should cleanup independently", async () => {
209
- const beforeSpy = vi.fn();
210
- const afterSpy = vi.fn();
211
- const unregisterBefore = router.beforeEach(beforeSpy);
212
- const unregisterAfter = router.afterEach(afterSpy);
213
- await router.push("/test1");
214
- expect(beforeSpy).toHaveBeenCalledTimes(1);
215
- expect(afterSpy).toHaveBeenCalledTimes(1);
216
- unregisterBefore();
217
- await router.push("/test2");
218
- expect(beforeSpy).toHaveBeenCalledTimes(1);
219
- expect(afterSpy).toHaveBeenCalledTimes(2);
220
- unregisterAfter();
221
- await router.push("/test3");
222
- expect(beforeSpy).toHaveBeenCalledTimes(1);
223
- expect(afterSpy).toHaveBeenCalledTimes(2);
224
- });
225
- });
226
- });
227
- describe("\u{1F6E1}\uFE0F Edge Cases Testing", () => {
228
- describe("repeated cleanup safety", () => {
229
- test("repeated cleanup function calls should be safe", () => {
230
- const spy = vi.fn();
231
- const unregister = router.beforeEach(spy);
232
- expect(() => {
233
- unregister();
234
- unregister();
235
- unregister();
236
- }).not.toThrow();
237
- });
238
- test("guard should still not execute after repeated cleanup", async () => {
239
- const spy = vi.fn();
240
- const unregister = router.beforeEach(spy);
241
- await router.push("/test1");
242
- expect(spy).toHaveBeenCalledTimes(1);
243
- unregister();
244
- unregister();
245
- unregister();
246
- await router.push("/test2");
247
- expect(spy).toHaveBeenCalledTimes(1);
248
- });
249
- });
250
- describe("cleanup and re-registration", () => {
251
- test("can re-register same guard after cleanup", async () => {
252
- const spy = vi.fn();
253
- const unregister1 = router.beforeEach(spy);
254
- await router.push("/test1");
255
- expect(spy).toHaveBeenCalledTimes(1);
256
- unregister1();
257
- const unregister2 = router.beforeEach(spy);
258
- await router.push("/test2");
259
- expect(spy).toHaveBeenCalledTimes(2);
260
- unregister2();
261
- });
262
- test("re-registration after cleanup should work normally", async () => {
263
- const spy = vi.fn();
264
- let unregister = router.beforeEach(spy);
265
- await router.push("/test1");
266
- expect(spy).toHaveBeenCalledTimes(1);
267
- unregister();
268
- unregister = router.beforeEach(spy);
269
- await router.push("/test2");
270
- expect(spy).toHaveBeenCalledTimes(2);
271
- unregister();
272
- unregister = router.beforeEach(spy);
273
- await router.push("/test3");
274
- expect(spy).toHaveBeenCalledTimes(3);
275
- unregister();
276
- });
277
- });
278
- describe("same guard multiple registrations", () => {
279
- test("same guard function registered multiple times should handle correctly", async () => {
280
- const spy = vi.fn();
281
- const unregister1 = router.beforeEach(spy);
282
- const unregister2 = router.beforeEach(spy);
283
- await router.push("/test1");
284
- expect(spy).toHaveBeenCalledTimes(2);
285
- unregister1();
286
- await router.push("/test2");
287
- expect(spy).toHaveBeenCalledTimes(3);
288
- unregister2();
289
- await router.push("/test3");
290
- expect(spy).toHaveBeenCalledTimes(3);
291
- });
292
- test("complex scenario with same guard multiple registrations and cleanups", async () => {
293
- const spy = vi.fn();
294
- const unregister1 = router.beforeEach(spy);
295
- const unregister2 = router.beforeEach(spy);
296
- const unregister3 = router.beforeEach(spy);
297
- await router.push("/test1");
298
- expect(spy).toHaveBeenCalledTimes(3);
299
- unregister2();
300
- await router.push("/test2");
301
- expect(spy).toHaveBeenCalledTimes(5);
302
- unregister1();
303
- unregister3();
304
- await router.push("/test3");
305
- expect(spy).toHaveBeenCalledTimes(5);
306
- });
307
- });
308
- describe("empty array and non-existent element handling", () => {
309
- test("removing element from empty array should be safe", () => {
310
- const emptyArray = [];
311
- const element = vi.fn();
312
- expect(() => {
313
- removeFromArray(emptyArray, element);
314
- }).not.toThrow();
315
- expect(emptyArray).toEqual([]);
316
- });
317
- test("removing non-existent element should be safe", () => {
318
- const array = [vi.fn(), vi.fn(), vi.fn()];
319
- const nonExistentElement = vi.fn();
320
- const originalLength = array.length;
321
- expect(() => {
322
- removeFromArray(array, nonExistentElement);
323
- }).not.toThrow();
324
- expect(array).toHaveLength(originalLength);
325
- });
326
- });
327
- describe("special value handling", () => {
328
- test("removeFromArray should handle NaN values correctly", () => {
329
- const arr = [1, Number.NaN, 3, Number.NaN, 5];
330
- removeFromArray(arr, Number.NaN);
331
- expect(arr).toEqual([1, 3, Number.NaN, 5]);
332
- });
333
- test("removeFromArray should handle function references correctly", () => {
334
- const func1 = () => "func1";
335
- const func2 = () => "func2";
336
- const func3 = () => "func3";
337
- const arr = [func1, func2, func3];
338
- removeFromArray(arr, func2);
339
- expect(arr).toEqual([func1, func3]);
340
- });
341
- test("removeFromArray should handle object references correctly", () => {
342
- const obj1 = { id: 1 };
343
- const obj2 = { id: 2 };
344
- const obj3 = { id: 3 };
345
- const arr = [obj1, obj2, obj3];
346
- removeFromArray(arr, obj2);
347
- expect(arr).toEqual([obj1, obj3]);
348
- });
349
- });
350
- describe("memory leak protection", () => {
351
- test("large number of guard registrations and cleanups should not cause memory leaks", () => {
352
- const unregisters = [];
353
- for (let i = 0; i < 100; i++) {
354
- const guard = vi.fn();
355
- const unregister = router.beforeEach(guard);
356
- unregisters.push(unregister);
357
- }
358
- expect(router.transition.guards.beforeEach).toHaveLength(100);
359
- unregisters.forEach((unregister) => unregister());
360
- expect(router.transition.guards.beforeEach).toHaveLength(0);
361
- });
362
- test("mixed registration and cleanup should not cause memory leaks", () => {
363
- const guards = [];
364
- const unregisters = [];
365
- for (let i = 0; i < 50; i++) {
366
- const guard = vi.fn();
367
- guards.push(guard);
368
- const unregister = router.beforeEach(guard);
369
- unregisters.push(unregister);
370
- if (i % 5 === 0 && i > 0) {
371
- unregisters[i - 5]();
372
- }
373
- }
374
- unregisters.forEach((unregister) => unregister());
375
- expect(router.transition.guards.beforeEach).toHaveLength(0);
376
- expect(router.transition.guards.afterEach).toHaveLength(0);
377
- });
378
- });
379
- describe("concurrent cleanup safety", () => {
380
- test("cleaning guard during navigation should be safe", async () => {
381
- let unregister = null;
382
- let guardExecuted = false;
383
- const guard = async () => {
384
- guardExecuted = true;
385
- unregister == null ? void 0 : unregister();
386
- await new Promise((resolve) => setTimeout(resolve, 10));
387
- };
388
- unregister = router.beforeEach(guard);
389
- await expect(router.push("/test1")).resolves.toBeDefined();
390
- expect(guardExecuted).toBe(true);
391
- guardExecuted = false;
392
- await router.push("/test2");
393
- expect(guardExecuted).toBe(false);
394
- });
395
- test("cleaning multiple guards simultaneously should be safe", async () => {
396
- const guards = Array.from({ length: 10 }, () => vi.fn());
397
- const unregisters = guards.map(
398
- (guard) => router.beforeEach(guard)
399
- );
400
- await router.push("/test1");
401
- guards.forEach(
402
- (guard) => expect(guard).toHaveBeenCalledTimes(1)
403
- );
404
- unregisters.forEach((unregister) => unregister());
405
- await router.push("/test2");
406
- guards.forEach(
407
- (guard) => expect(guard).toHaveBeenCalledTimes(1)
408
- );
409
- });
410
- });
411
- });
412
- describe("\u{1F527} Router destroy cleanup verification", () => {
413
- test("Router destroy should cleanup all guards", async () => {
414
- const beforeSpy = vi.fn();
415
- const afterSpy = vi.fn();
416
- router.beforeEach(beforeSpy);
417
- router.afterEach(afterSpy);
418
- await router.push("/test1");
419
- expect(beforeSpy).toHaveBeenCalledTimes(1);
420
- expect(afterSpy).toHaveBeenCalledTimes(1);
421
- router.destroy();
422
- const newRouter = new Router({
423
- mode: RouterMode.memory,
424
- base: new URL("http://localhost:3000/"),
425
- routes: [
426
- { path: "/", component: () => "Home" },
427
- { path: "/test", component: () => "Test" }
428
- ]
429
- });
430
- await newRouter.replace("/");
431
- await newRouter.push("/test");
432
- expect(beforeSpy).toHaveBeenCalledTimes(1);
433
- expect(afterSpy).toHaveBeenCalledTimes(1);
434
- newRouter.destroy();
435
- });
436
- });
437
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,115 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from "vitest";
2
- import { Router } from "./router.mjs";
3
- import { RouteType, RouterMode } from "./types.mjs";
4
- describe("Router Push Tests", () => {
5
- let router;
6
- beforeEach(async () => {
7
- router = new Router({
8
- mode: RouterMode.memory,
9
- base: new URL("http://localhost:3000/"),
10
- routes: [
11
- { path: "/", component: () => "Home" },
12
- { path: "/user/:id", component: () => "User" },
13
- { path: "/about", component: () => "About" },
14
- {
15
- path: "/async",
16
- asyncComponent: () => new Promise(
17
- (resolve) => setTimeout(() => resolve("AsyncComponent"), 10)
18
- )
19
- }
20
- ]
21
- });
22
- await router.replace("/");
23
- });
24
- afterEach(() => {
25
- router.destroy();
26
- });
27
- describe("Basic push navigation", () => {
28
- test("should successfully push to new route", async () => {
29
- const route = await router.push("/user/123");
30
- expect(route.path).toBe("/user/123");
31
- expect(route.params.id).toBe("123");
32
- expect(route.type).toBe(RouteType.push);
33
- expect(route.handle).not.toBe(null);
34
- expect(router.route.path).toBe("/user/123");
35
- });
36
- test("should handle query parameters in push", async () => {
37
- const route = await router.push(
38
- "/user/123?tab=profile&active=true"
39
- );
40
- expect(route.params.id).toBe("123");
41
- expect(route.query.tab).toBe("profile");
42
- expect(route.query.active).toBe("true");
43
- });
44
- test("should handle async component loading", async () => {
45
- const route = await router.push("/async");
46
- expect(route.path).toBe("/async");
47
- expect(route.handle).not.toBe(null);
48
- });
49
- });
50
- describe("Error handling", () => {
51
- test("should throw error for async component loading failure", async () => {
52
- const errorRouter = new Router({
53
- mode: RouterMode.memory,
54
- base: new URL("http://localhost:3000/"),
55
- routes: [
56
- { path: "/", component: () => "Home" },
57
- {
58
- path: "/error",
59
- asyncComponent: () => Promise.reject(new Error("Loading failed"))
60
- }
61
- ]
62
- });
63
- await errorRouter.replace("/");
64
- await expect(errorRouter.push("/error")).rejects.toThrow();
65
- errorRouter.destroy();
66
- });
67
- test("should throw error when guard prevents navigation", async () => {
68
- const guardRouter = new Router({
69
- mode: RouterMode.memory,
70
- base: new URL("http://localhost:3000/"),
71
- routes: [
72
- { path: "/", component: () => "Home" },
73
- {
74
- path: "/protected",
75
- component: () => "Protected",
76
- beforeEnter: () => false
77
- }
78
- ]
79
- });
80
- await guardRouter.replace("/");
81
- await expect(guardRouter.push("/protected")).rejects.toThrow();
82
- guardRouter.destroy();
83
- });
84
- });
85
- describe("Concurrent navigation", () => {
86
- test("should handle concurrent push operations", async () => {
87
- const promises = [
88
- router.push("/user/1").catch((err) => err),
89
- router.push("/user/2").catch((err) => err)
90
- ];
91
- const [result1, result2] = await Promise.all(promises);
92
- const successResults = [result1, result2].filter(
93
- (r) => !(r instanceof Error)
94
- );
95
- const errorResults = [result1, result2].filter(
96
- (r) => r instanceof Error
97
- );
98
- expect(successResults).toHaveLength(1);
99
- expect(errorResults).toHaveLength(1);
100
- });
101
- });
102
- describe("Edge cases", () => {
103
- test("should handle push to current route", async () => {
104
- await router.push("/about");
105
- const route = await router.push("/about");
106
- expect(route.path).toBe("/about");
107
- expect(route.handle).not.toBe(null);
108
- });
109
- test("should handle empty parameter", async () => {
110
- const route = await router.push("");
111
- expect(route).toBeDefined();
112
- expect(typeof route.path).toBe("string");
113
- });
114
- });
115
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,114 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from "vitest";
2
- import { Router } from "./router.mjs";
3
- import { RouteType, RouterMode } from "./types.mjs";
4
- describe("Router Replace Tests", () => {
5
- let router;
6
- beforeEach(async () => {
7
- router = new Router({
8
- mode: RouterMode.memory,
9
- base: new URL("http://localhost:3000/"),
10
- routes: [
11
- { path: "/", component: () => "Home" },
12
- { path: "/user/:id", component: () => "User" },
13
- { path: "/about", component: () => "About" },
14
- {
15
- path: "/async",
16
- asyncComponent: () => new Promise(
17
- (resolve) => setTimeout(() => resolve("AsyncComponent"), 10)
18
- )
19
- }
20
- ]
21
- });
22
- await router.replace("/");
23
- });
24
- afterEach(() => {
25
- router.destroy();
26
- });
27
- describe("Basic replace navigation", () => {
28
- test("should successfully replace current route", async () => {
29
- await router.push("/about");
30
- const route = await router.replace("/user/123");
31
- expect(route.path).toBe("/user/123");
32
- expect(route.params.id).toBe("123");
33
- expect(route.type).toBe(RouteType.replace);
34
- expect(route.handle).not.toBe(null);
35
- expect(router.route.path).toBe("/user/123");
36
- });
37
- test("should handle query parameters in replace", async () => {
38
- const route = await router.replace(
39
- "/user/123?tab=profile&active=true"
40
- );
41
- expect(route.params.id).toBe("123");
42
- expect(route.query.tab).toBe("profile");
43
- expect(route.query.active).toBe("true");
44
- });
45
- test("should handle async component loading", async () => {
46
- const route = await router.replace("/async");
47
- expect(route.path).toBe("/async");
48
- expect(route.handle).not.toBe(null);
49
- });
50
- });
51
- describe("Error handling", () => {
52
- test("should throw error for async component loading failure", async () => {
53
- const errorRouter = new Router({
54
- mode: RouterMode.memory,
55
- base: new URL("http://localhost:3000/"),
56
- routes: [
57
- { path: "/", component: () => "Home" },
58
- {
59
- path: "/error",
60
- asyncComponent: () => Promise.reject(new Error("Loading failed"))
61
- }
62
- ]
63
- });
64
- await errorRouter.replace("/");
65
- await expect(errorRouter.replace("/error")).rejects.toThrow();
66
- errorRouter.destroy();
67
- });
68
- test("should throw error when guard prevents navigation", async () => {
69
- const guardRouter = new Router({
70
- mode: RouterMode.memory,
71
- base: new URL("http://localhost:3000/"),
72
- routes: [
73
- { path: "/", component: () => "Home" },
74
- {
75
- path: "/protected",
76
- component: () => "Protected",
77
- beforeEnter: () => false
78
- }
79
- ]
80
- });
81
- await guardRouter.replace("/");
82
- await expect(guardRouter.replace("/protected")).rejects.toThrow();
83
- guardRouter.destroy();
84
- });
85
- });
86
- describe("History management", () => {
87
- test("should not create new history entry", async () => {
88
- await router.push("/about");
89
- await router.replace("/user/123");
90
- const backRoute = await router.back();
91
- expect(backRoute == null ? void 0 : backRoute.path).toBe("/");
92
- });
93
- test("should replace current entry in history", async () => {
94
- await router.push("/about");
95
- await router.push("/user/456");
96
- await router.replace("/user/789");
97
- const backRoute = await router.back();
98
- expect(backRoute == null ? void 0 : backRoute.path).toBe("/about");
99
- });
100
- });
101
- describe("Edge cases", () => {
102
- test("should handle replace to current route", async () => {
103
- await router.push("/about");
104
- const route = await router.replace("/about");
105
- expect(route.path).toBe("/about");
106
- expect(route.handle).not.toBe(null);
107
- });
108
- test("should handle empty parameter", async () => {
109
- const route = await router.replace("");
110
- expect(route).toBeDefined();
111
- expect(typeof route.path).toBe("string");
112
- });
113
- });
114
- });
@@ -1 +0,0 @@
1
- export {};