-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsetup-nested-components.ts
More file actions
75 lines (65 loc) · 2.13 KB
/
setup-nested-components.ts
File metadata and controls
75 lines (65 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { createApp, defineComponent, inject, provide } from "vue";
import { AppDisposer } from "@/tests/vue";
type SetupFunction = () => Record<string, unknown>;
/**
* Options for setting up nested components.
*/
export interface SetupNestedComponentsOptions {
/** Setup function for the parent component */
setupParent: SetupFunction;
/** Setup function for the child component */
setupChild: SetupFunction;
}
/**
* Sets up a Vue application with nested parent and child components.
*
* This function creates a Vue application with a parent component that includes
* a child component. Both components are configured using the provided setup functions.
* The resulting app is mounted to a new div element and wrapped in an AppDisposer
* for proper cleanup.
*
* @param options - Configuration options for the parent and child components
* @returns An object containing the Vue app instance and a Symbol.dispose method
*
* @example
* ```
* const { app } = setupNestedComponents({
* setupParent: () => ({ parentData: ref('Parent') }),
* setupChild: () => ({ childData: ref('Child') })
* });
* ```
*/
export function setupNestedComponents(options: SetupNestedComponentsOptions) {
const ParentComponent = defineComponent({
setup: options.setupParent,
template: "<child-component />",
});
const ChildComponent = defineComponent({
setup: options.setupChild,
template: "<template />",
});
const app = createApp(ParentComponent);
app.component("ChildComponent", ChildComponent);
app.mount(document.createElement("div"));
const disposable = new AppDisposer(app);
return { app, [Symbol.dispose]: () => disposable[Symbol.dispose]() };
}
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest;
it("setupNestedComponents", () => {
const key = Symbol();
const provided = {}; // a sentinel
let injected: object | undefined;
using _ = setupNestedComponents({
setupParent: () => {
provide(key, provided);
return {};
},
setupChild: () => {
injected = inject(key);
return {};
},
});
expect(injected).toBe(provided);
});
}