@esmx/router-vue 3.0.0-rc.16 → 3.0.0-rc.19
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.
- package/LICENSE +1 -1
- package/README.md +563 -0
- package/README.zh-CN.md +563 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.mjs +11 -4
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.mjs +206 -0
- package/dist/plugin.d.ts +55 -11
- package/dist/plugin.mjs +32 -16
- package/dist/plugin.test.d.ts +1 -0
- package/dist/plugin.test.mjs +436 -0
- package/dist/router-link.d.ts +202 -0
- package/dist/router-link.mjs +84 -0
- package/dist/router-link.test.d.ts +1 -0
- package/dist/router-link.test.mjs +456 -0
- package/dist/router-view.d.ts +30 -0
- package/dist/router-view.mjs +17 -0
- package/dist/router-view.test.d.ts +1 -0
- package/dist/router-view.test.mjs +459 -0
- package/dist/use.d.ts +198 -3
- package/dist/use.mjs +75 -9
- package/dist/use.test.d.ts +1 -0
- package/dist/use.test.mjs +461 -0
- package/dist/util.d.ts +7 -0
- package/dist/util.mjs +24 -0
- package/dist/util.test.d.ts +1 -0
- package/dist/util.test.mjs +319 -0
- package/dist/vue2.d.ts +13 -0
- package/dist/vue2.mjs +0 -0
- package/dist/vue3.d.ts +13 -0
- package/dist/vue3.mjs +0 -0
- package/package.json +31 -14
- package/src/index.test.ts +263 -0
- package/src/index.ts +16 -4
- package/src/plugin.test.ts +574 -0
- package/src/plugin.ts +86 -31
- package/src/router-link.test.ts +569 -0
- package/src/router-link.ts +148 -0
- package/src/router-view.test.ts +599 -0
- package/src/router-view.ts +61 -0
- package/src/use.test.ts +616 -0
- package/src/use.ts +307 -11
- package/src/util.test.ts +418 -0
- package/src/util.ts +32 -0
- package/src/vue2.ts +16 -0
- package/src/vue3.ts +15 -0
- package/dist/link.d.ts +0 -101
- package/dist/link.mjs +0 -103
- package/dist/symbols.d.ts +0 -3
- package/dist/symbols.mjs +0 -3
- package/dist/view.d.ts +0 -21
- package/dist/view.mjs +0 -75
- package/src/link.ts +0 -177
- package/src/symbols.ts +0 -8
- package/src/view.ts +0 -95
package/src/index.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
export {
|
|
1
|
+
export type * from './vue2';
|
|
2
|
+
export type * from './vue3';
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
useRouter,
|
|
6
|
+
useRoute,
|
|
7
|
+
useProvideRouter,
|
|
8
|
+
useLink,
|
|
9
|
+
getRoute,
|
|
10
|
+
getRouter
|
|
11
|
+
} from './use';
|
|
12
|
+
|
|
13
|
+
export { RouterLink } from './router-link';
|
|
14
|
+
export { RouterView } from './router-view';
|
|
15
|
+
|
|
16
|
+
export { RouterPlugin } from './plugin';
|
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import type { Route, RouteConfig } from '@esmx/router';
|
|
2
|
+
import { Router, RouterMode } from '@esmx/router';
|
|
3
|
+
/**
|
|
4
|
+
* @vitest-environment happy-dom
|
|
5
|
+
*/
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
+
import { createApp, defineComponent, h, nextTick } from 'vue';
|
|
8
|
+
import { RouterPlugin } from './plugin';
|
|
9
|
+
import { RouterLink } from './router-link';
|
|
10
|
+
import { RouterView } from './router-view';
|
|
11
|
+
import { useProvideRouter } from './use';
|
|
12
|
+
|
|
13
|
+
describe('plugin.ts - RouterPlugin', () => {
|
|
14
|
+
let router: Router;
|
|
15
|
+
let app: ReturnType<typeof createApp>;
|
|
16
|
+
let container: HTMLElement;
|
|
17
|
+
|
|
18
|
+
beforeEach(async () => {
|
|
19
|
+
// Create DOM container
|
|
20
|
+
container = document.createElement('div');
|
|
21
|
+
container.id = 'test-app';
|
|
22
|
+
document.body.appendChild(container);
|
|
23
|
+
|
|
24
|
+
// Create test routes with render functions
|
|
25
|
+
const routes: RouteConfig[] = [
|
|
26
|
+
{
|
|
27
|
+
path: '/',
|
|
28
|
+
component: defineComponent({
|
|
29
|
+
name: 'Home',
|
|
30
|
+
render: () => h('div', 'Home Page')
|
|
31
|
+
}),
|
|
32
|
+
meta: { title: 'Home' }
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
path: '/about',
|
|
36
|
+
component: defineComponent({
|
|
37
|
+
name: 'About',
|
|
38
|
+
render: () => h('div', 'About Page')
|
|
39
|
+
}),
|
|
40
|
+
meta: { title: 'About' }
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// Create and initialize router
|
|
45
|
+
router = new Router({
|
|
46
|
+
mode: RouterMode.memory,
|
|
47
|
+
routes,
|
|
48
|
+
base: new URL('http://localhost:3000/')
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await router.replace('/');
|
|
52
|
+
await nextTick();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
if (app) {
|
|
57
|
+
app.unmount();
|
|
58
|
+
}
|
|
59
|
+
if (router) {
|
|
60
|
+
router.destroy();
|
|
61
|
+
}
|
|
62
|
+
if (container?.parentNode) {
|
|
63
|
+
container.parentNode.removeChild(container);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('Plugin Installation', () => {
|
|
68
|
+
it('should install plugin without errors', () => {
|
|
69
|
+
app = createApp({
|
|
70
|
+
setup() {
|
|
71
|
+
useProvideRouter(router);
|
|
72
|
+
return () => h('div', 'Test App');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
expect(() => {
|
|
77
|
+
app.use(RouterPlugin);
|
|
78
|
+
}).not.toThrow();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should throw error for invalid Vue app instance', () => {
|
|
82
|
+
const invalidApp = {};
|
|
83
|
+
expect(() => {
|
|
84
|
+
RouterPlugin.install(invalidApp);
|
|
85
|
+
}).toThrow('[@esmx/router-vue] Invalid Vue app instance');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should throw error for null app instance', () => {
|
|
89
|
+
expect(() => {
|
|
90
|
+
RouterPlugin.install(null);
|
|
91
|
+
}).toThrow();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should throw error for undefined app instance', () => {
|
|
95
|
+
expect(() => {
|
|
96
|
+
RouterPlugin.install(undefined);
|
|
97
|
+
}).toThrow();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('Global Properties Injection', () => {
|
|
102
|
+
it('should inject $router and $route properties', async () => {
|
|
103
|
+
app = createApp({
|
|
104
|
+
setup() {
|
|
105
|
+
useProvideRouter(router);
|
|
106
|
+
return () => h('div', 'Test App');
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
app.use(RouterPlugin);
|
|
111
|
+
app.mount(container);
|
|
112
|
+
await nextTick();
|
|
113
|
+
|
|
114
|
+
// Check that properties are defined using descriptors to avoid triggering getters
|
|
115
|
+
const globalProperties = app.config.globalProperties;
|
|
116
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
117
|
+
globalProperties,
|
|
118
|
+
'$router'
|
|
119
|
+
);
|
|
120
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
121
|
+
globalProperties,
|
|
122
|
+
'$route'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
expect(routerDescriptor).toBeDefined();
|
|
126
|
+
expect(routeDescriptor).toBeDefined();
|
|
127
|
+
expect(routerDescriptor?.get).toBeDefined();
|
|
128
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
129
|
+
expect(typeof routerDescriptor?.get).toBe('function');
|
|
130
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should provide reactive $route property', async () => {
|
|
134
|
+
app = createApp({
|
|
135
|
+
setup() {
|
|
136
|
+
useProvideRouter(router);
|
|
137
|
+
return () => h('div', 'Test App');
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
app.use(RouterPlugin);
|
|
142
|
+
app.mount(container);
|
|
143
|
+
await nextTick();
|
|
144
|
+
|
|
145
|
+
// Navigate to different route
|
|
146
|
+
await router.push('/about');
|
|
147
|
+
await nextTick();
|
|
148
|
+
|
|
149
|
+
// Check that global properties are reactive (structure test)
|
|
150
|
+
const globalProperties = app.config.globalProperties;
|
|
151
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
152
|
+
globalProperties,
|
|
153
|
+
'$route'
|
|
154
|
+
);
|
|
155
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
156
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
157
|
+
|
|
158
|
+
// Verify the descriptor is properly configured for reactivity
|
|
159
|
+
expect(routeDescriptor?.enumerable).toBe(false);
|
|
160
|
+
expect(routeDescriptor?.configurable).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should provide consistent $router instance across components', async () => {
|
|
164
|
+
const ChildComponent = defineComponent({
|
|
165
|
+
render() {
|
|
166
|
+
return h('div', 'Child');
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
app = createApp({
|
|
171
|
+
setup() {
|
|
172
|
+
useProvideRouter(router);
|
|
173
|
+
return () =>
|
|
174
|
+
h('div', [h('div', 'Parent'), h(ChildComponent)]);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
app.use(RouterPlugin);
|
|
179
|
+
app.mount(container);
|
|
180
|
+
await nextTick();
|
|
181
|
+
|
|
182
|
+
// Verify that global properties are consistently available
|
|
183
|
+
const globalProperties = app.config.globalProperties;
|
|
184
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
185
|
+
globalProperties,
|
|
186
|
+
'$router'
|
|
187
|
+
);
|
|
188
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
189
|
+
globalProperties,
|
|
190
|
+
'$route'
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
expect(routerDescriptor).toBeDefined();
|
|
194
|
+
expect(routeDescriptor).toBeDefined();
|
|
195
|
+
expect(routerDescriptor?.get).toBeDefined();
|
|
196
|
+
expect(typeof routerDescriptor?.get).toBe('function');
|
|
197
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
198
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should actually call $router getter when accessed in component', async () => {
|
|
202
|
+
let routerResult: Router | null = null;
|
|
203
|
+
|
|
204
|
+
const TestComponent = defineComponent({
|
|
205
|
+
mounted() {
|
|
206
|
+
// This will trigger the $router getter defined in the plugin
|
|
207
|
+
routerResult = this.$router;
|
|
208
|
+
},
|
|
209
|
+
render() {
|
|
210
|
+
return h('div', 'Test Component');
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
app = createApp({
|
|
215
|
+
setup() {
|
|
216
|
+
useProvideRouter(router);
|
|
217
|
+
return () => h(TestComponent);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
app.use(RouterPlugin);
|
|
222
|
+
app.mount(container);
|
|
223
|
+
await nextTick();
|
|
224
|
+
|
|
225
|
+
// Verify the getter was called and returned correct value
|
|
226
|
+
expect(routerResult).toBe(router);
|
|
227
|
+
expect(routerResult).toBeInstanceOf(Router);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should actually call $route getter when accessed in component', async () => {
|
|
231
|
+
let routeResult: Route | null = null;
|
|
232
|
+
|
|
233
|
+
const TestComponent = defineComponent({
|
|
234
|
+
mounted() {
|
|
235
|
+
routeResult = this.$route;
|
|
236
|
+
},
|
|
237
|
+
render() {
|
|
238
|
+
return h('div', 'Test Component');
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
app = createApp({
|
|
243
|
+
setup() {
|
|
244
|
+
useProvideRouter(router);
|
|
245
|
+
return () => h(TestComponent);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
app.use(RouterPlugin);
|
|
250
|
+
app.mount(container);
|
|
251
|
+
await nextTick();
|
|
252
|
+
|
|
253
|
+
// Navigate to ensure route state is set
|
|
254
|
+
await router.push('/about');
|
|
255
|
+
await nextTick();
|
|
256
|
+
|
|
257
|
+
// Verify the getter was called and returned correct value
|
|
258
|
+
expect(routeResult).toBeTruthy();
|
|
259
|
+
expect(routeResult).toHaveProperty('path', '/about');
|
|
260
|
+
expect(routeResult).toHaveProperty('meta.title', 'About');
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe('Component Registration', () => {
|
|
265
|
+
it('should register components with correct names', () => {
|
|
266
|
+
app = createApp({
|
|
267
|
+
setup() {
|
|
268
|
+
useProvideRouter(router);
|
|
269
|
+
return () => h('div', 'Test App');
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
app.use(RouterPlugin);
|
|
274
|
+
|
|
275
|
+
const globalComponents = app._context.components;
|
|
276
|
+
expect(globalComponents).toHaveProperty('RouterLink');
|
|
277
|
+
expect(globalComponents).toHaveProperty('RouterView');
|
|
278
|
+
expect(globalComponents.RouterLink).toBe(RouterLink);
|
|
279
|
+
expect(globalComponents.RouterView).toBe(RouterView);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should register RouterLink component for global use', async () => {
|
|
283
|
+
app = createApp({
|
|
284
|
+
setup() {
|
|
285
|
+
useProvideRouter(router);
|
|
286
|
+
return () => h('div', 'Test App with RouterLink available');
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
app.use(RouterPlugin);
|
|
291
|
+
app.mount(container);
|
|
292
|
+
await nextTick();
|
|
293
|
+
|
|
294
|
+
// Verify the component is registered globally
|
|
295
|
+
const globalComponents = app._context.components;
|
|
296
|
+
expect(globalComponents.RouterLink).toBeDefined();
|
|
297
|
+
expect(typeof globalComponents.RouterLink).toBe('object');
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should register RouterView component for global use', async () => {
|
|
301
|
+
app = createApp({
|
|
302
|
+
setup() {
|
|
303
|
+
useProvideRouter(router);
|
|
304
|
+
return () => h('div', 'Test App with RouterView available');
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
app.use(RouterPlugin);
|
|
309
|
+
app.mount(container);
|
|
310
|
+
await nextTick();
|
|
311
|
+
|
|
312
|
+
// Verify the component is registered globally
|
|
313
|
+
const globalComponents = app._context.components;
|
|
314
|
+
expect(globalComponents.RouterView).toBeDefined();
|
|
315
|
+
expect(typeof globalComponents.RouterView).toBe('object');
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
describe('Error Handling', () => {
|
|
320
|
+
it('should handle missing router context in global properties', () => {
|
|
321
|
+
// Create a mock component instance without router context
|
|
322
|
+
const mockComponent = {
|
|
323
|
+
$: {
|
|
324
|
+
provides: {}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Simulate accessing $router without context
|
|
329
|
+
const target = {};
|
|
330
|
+
Object.defineProperties(target, {
|
|
331
|
+
$router: {
|
|
332
|
+
get() {
|
|
333
|
+
// This simulates the getter function from the plugin
|
|
334
|
+
return require('./use').getRouter(mockComponent);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
expect(() => {
|
|
340
|
+
(target as Record<string, unknown>).$router;
|
|
341
|
+
}).toThrow();
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it('should handle missing router context in $route property', () => {
|
|
345
|
+
// Create a mock component instance without router context
|
|
346
|
+
const mockComponent = {
|
|
347
|
+
$: {
|
|
348
|
+
provides: {}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// Simulate accessing $route without context
|
|
353
|
+
const target = {};
|
|
354
|
+
Object.defineProperties(target, {
|
|
355
|
+
$route: {
|
|
356
|
+
get() {
|
|
357
|
+
// This simulates the getter function from the plugin
|
|
358
|
+
return require('./use').getRoute(mockComponent);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
expect(() => {
|
|
364
|
+
(target as Record<string, unknown>).$route;
|
|
365
|
+
}).toThrow();
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
describe('Plugin Integration', () => {
|
|
370
|
+
it('should work with multiple plugin installations', () => {
|
|
371
|
+
app = createApp({
|
|
372
|
+
setup() {
|
|
373
|
+
useProvideRouter(router);
|
|
374
|
+
return () => h('div', 'Test App');
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Install plugin multiple times
|
|
379
|
+
app.use(RouterPlugin);
|
|
380
|
+
app.use(RouterPlugin);
|
|
381
|
+
|
|
382
|
+
expect(() => {
|
|
383
|
+
app.mount(container);
|
|
384
|
+
}).not.toThrow();
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('should maintain global properties after installation', async () => {
|
|
388
|
+
app = createApp({
|
|
389
|
+
setup() {
|
|
390
|
+
useProvideRouter(router);
|
|
391
|
+
return () => h('div', 'Test App');
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
app.use(RouterPlugin);
|
|
396
|
+
app.mount(container);
|
|
397
|
+
await nextTick();
|
|
398
|
+
|
|
399
|
+
// Check that global properties are accessible using descriptors
|
|
400
|
+
const globalProperties = app.config.globalProperties;
|
|
401
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
402
|
+
globalProperties,
|
|
403
|
+
'$router'
|
|
404
|
+
);
|
|
405
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
406
|
+
globalProperties,
|
|
407
|
+
'$route'
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
expect(routerDescriptor).toBeDefined();
|
|
411
|
+
expect(routeDescriptor).toBeDefined();
|
|
412
|
+
expect(routerDescriptor?.get).toBeDefined();
|
|
413
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
414
|
+
expect(typeof routerDescriptor?.get).toBe('function');
|
|
415
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
describe('Type Safety', () => {
|
|
420
|
+
it('should provide properly typed global properties', async () => {
|
|
421
|
+
app = createApp({
|
|
422
|
+
setup() {
|
|
423
|
+
useProvideRouter(router);
|
|
424
|
+
return () => h('div', 'Test App');
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
app.use(RouterPlugin);
|
|
429
|
+
app.mount(container);
|
|
430
|
+
await nextTick();
|
|
431
|
+
|
|
432
|
+
// Check type safety through property descriptors
|
|
433
|
+
const globalProperties = app.config.globalProperties;
|
|
434
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
435
|
+
globalProperties,
|
|
436
|
+
'$router'
|
|
437
|
+
);
|
|
438
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
439
|
+
globalProperties,
|
|
440
|
+
'$route'
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
expect(routerDescriptor).toBeDefined();
|
|
444
|
+
expect(routeDescriptor).toBeDefined();
|
|
445
|
+
expect(typeof routerDescriptor?.get).toBe('function');
|
|
446
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
447
|
+
|
|
448
|
+
// Verify properties exist in global properties
|
|
449
|
+
expect(
|
|
450
|
+
Object.prototype.hasOwnProperty.call(
|
|
451
|
+
globalProperties,
|
|
452
|
+
'$router'
|
|
453
|
+
)
|
|
454
|
+
).toBe(true);
|
|
455
|
+
expect(
|
|
456
|
+
Object.prototype.hasOwnProperty.call(globalProperties, '$route')
|
|
457
|
+
).toBe(true);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('should provide correct component types', () => {
|
|
461
|
+
app = createApp({
|
|
462
|
+
setup() {
|
|
463
|
+
useProvideRouter(router);
|
|
464
|
+
return () => h('div', 'Test App');
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
app.use(RouterPlugin);
|
|
469
|
+
|
|
470
|
+
const globalComponents = app._context.components;
|
|
471
|
+
|
|
472
|
+
// Check component properties exist
|
|
473
|
+
expect(globalComponents.RouterLink.name).toBe('RouterLink');
|
|
474
|
+
expect(globalComponents.RouterView.name).toBe('RouterView');
|
|
475
|
+
|
|
476
|
+
// Check if components have setup functions (safely)
|
|
477
|
+
const routerLinkComponent = globalComponents.RouterLink as Record<
|
|
478
|
+
string,
|
|
479
|
+
unknown
|
|
480
|
+
>;
|
|
481
|
+
const routerViewComponent = globalComponents.RouterView as Record<
|
|
482
|
+
string,
|
|
483
|
+
unknown
|
|
484
|
+
>;
|
|
485
|
+
|
|
486
|
+
expect(typeof routerLinkComponent.setup).toBe('function');
|
|
487
|
+
expect(typeof routerViewComponent.setup).toBe('function');
|
|
488
|
+
});
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
describe('Advanced Plugin Features', () => {
|
|
492
|
+
it('should support property descriptor configuration', () => {
|
|
493
|
+
interface TestApp {
|
|
494
|
+
config: {
|
|
495
|
+
globalProperties: Record<string, unknown>;
|
|
496
|
+
};
|
|
497
|
+
component: (
|
|
498
|
+
name: string,
|
|
499
|
+
component: Record<string, unknown>
|
|
500
|
+
) => void;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const testApp: TestApp = {
|
|
504
|
+
config: {
|
|
505
|
+
globalProperties: {}
|
|
506
|
+
},
|
|
507
|
+
component: (
|
|
508
|
+
name: string,
|
|
509
|
+
component: Record<string, unknown>
|
|
510
|
+
) => {
|
|
511
|
+
// Mock component registration
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
RouterPlugin.install(testApp);
|
|
516
|
+
|
|
517
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
518
|
+
testApp.config.globalProperties,
|
|
519
|
+
'$router'
|
|
520
|
+
);
|
|
521
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
522
|
+
testApp.config.globalProperties,
|
|
523
|
+
'$route'
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
// Check descriptor properties - Object.defineProperties sets these to false by default
|
|
527
|
+
expect(routerDescriptor?.get).toBeDefined();
|
|
528
|
+
expect(routerDescriptor?.enumerable).toBe(false); // Default value from Object.defineProperty
|
|
529
|
+
expect(routerDescriptor?.configurable).toBe(false); // Default value from Object.defineProperty
|
|
530
|
+
|
|
531
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
532
|
+
expect(routeDescriptor?.enumerable).toBe(false); // Default value from Object.defineProperty
|
|
533
|
+
expect(routeDescriptor?.configurable).toBe(false); // Default value from Object.defineProperty
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
it('should handle different app instance structures', () => {
|
|
537
|
+
// Test with minimal app structure
|
|
538
|
+
interface MinimalApp {
|
|
539
|
+
config: {
|
|
540
|
+
globalProperties: Record<string, unknown>;
|
|
541
|
+
};
|
|
542
|
+
component: () => void;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const minimalApp: MinimalApp = {
|
|
546
|
+
config: {
|
|
547
|
+
globalProperties: {}
|
|
548
|
+
},
|
|
549
|
+
component: () => {}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
expect(() => {
|
|
553
|
+
RouterPlugin.install(minimalApp);
|
|
554
|
+
}).not.toThrow();
|
|
555
|
+
|
|
556
|
+
// Verify property descriptors are properly set using descriptors
|
|
557
|
+
const routerDescriptor = Object.getOwnPropertyDescriptor(
|
|
558
|
+
minimalApp.config.globalProperties,
|
|
559
|
+
'$router'
|
|
560
|
+
);
|
|
561
|
+
const routeDescriptor = Object.getOwnPropertyDescriptor(
|
|
562
|
+
minimalApp.config.globalProperties,
|
|
563
|
+
'$route'
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
expect(routerDescriptor).toBeDefined();
|
|
567
|
+
expect(routeDescriptor).toBeDefined();
|
|
568
|
+
expect(routerDescriptor?.get).toBeDefined();
|
|
569
|
+
expect(routeDescriptor?.get).toBeDefined();
|
|
570
|
+
expect(typeof routerDescriptor?.get).toBe('function');
|
|
571
|
+
expect(typeof routeDescriptor?.get).toBe('function');
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
});
|