@testforgejs/vue-test-core 1.0.0-beta.0

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.
@@ -0,0 +1,194 @@
1
+ import { Component, Plugin } from 'vue';
2
+ import { MountingOptions, mount } from '@vue/test-utils';
3
+ import { ComponentProps, ComponentSlots } from 'vue-component-type-helpers';
4
+
5
+ /** Plugin name (e.g., ‘pinia’, ‘i18n’, ‘router’) */
6
+ type PluginName = string;
7
+ /**
8
+ * Runtime value returned by a TestForge plugin factory.
9
+ *
10
+ * The returned value must be compatible with
11
+ * Vue Test Utils `global.plugins`.
12
+ */
13
+ type MountPlugin = Plugin | [Plugin, ...unknown[]];
14
+ interface PluginDefinition<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
15
+ beforeCreate?: (ctx: PipelineContext, options: TOptions) => TOptions;
16
+ create: (options: TOptions) => TPlugin;
17
+ afterCreate?: (plugin: TPlugin, ctx: PipelineContext) => void;
18
+ }
19
+ interface PluginModule<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
20
+ getName(): PluginName;
21
+ getDefinition(): PluginDefinition<TPlugin, TOptions>;
22
+ }
23
+ interface PluginManifestEntry<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
24
+ module: PluginModule<TPlugin, TOptions>;
25
+ enabled: boolean;
26
+ }
27
+ type SupportedPluginState = boolean;
28
+ type SupportedPluginsMap = Record<PluginName, SupportedPluginState>;
29
+ type RuntimePluginConfig = Record<string, any>;
30
+ type RuntimePluginOption = RuntimePluginConfig | false;
31
+ type ResolvedPluginOptions = Record<PluginName, RuntimePluginOption>;
32
+ type PluginConfigDefaults = Record<PluginName, RuntimePluginConfig>;
33
+ interface PluginRuntimeMeta<TInstance> {
34
+ __sharedInstance?: TInstance;
35
+ expose?: (instance: TInstance) => void;
36
+ }
37
+ type RuntimePluginOptions<TInstance, TOptions = object> = TOptions & PluginRuntimeMeta<TInstance>;
38
+ interface InstanceCapture<TInstance> {
39
+ expose(instance: TInstance): void;
40
+ readonly instance: TInstance | undefined;
41
+ }
42
+ interface PluginMeta {
43
+ instance?: unknown;
44
+ }
45
+ interface PluginOptionsMap {
46
+ }
47
+ type PluginOptionsInput = {
48
+ [K in keyof PluginOptionsMap]?: PluginOptionsMap[K] | false;
49
+ };
50
+ interface PluginControlOptions<TInstance> {
51
+ expose?: (instance: TInstance) => void;
52
+ }
53
+ type PluginOverride<T = unknown> = (T extends Record<string, any> ? Partial<T> & {
54
+ __meta?: PluginMeta;
55
+ } : T & {
56
+ __meta?: PluginMeta;
57
+ }) | false;
58
+ type PluginOverridesInput = {
59
+ [K in keyof PluginOptionsMap]?: PluginOverride<PluginOptionsMap[K]>;
60
+ };
61
+ interface ComponentFactoryOptions<Props = any, Slots = any, Data = any> extends Omit<MountingOptions<Props, Data>, "props" | "slots" | "data"> {
62
+ /** Strictly typed data */
63
+ data?: () => Data;
64
+ /** Strictly typed props */
65
+ props?: Props;
66
+ /** Strictly typed slots */
67
+ slots?: Slots;
68
+ /** Managed plugin configuration */
69
+ plugins?: PluginOptionsInput;
70
+ /** Disable managed plugins from presets */
71
+ skipManagedPlugins?: boolean;
72
+ }
73
+ type ComponentFactoryExtraOptions = {
74
+ /**
75
+ * Name of the preset to activate for this factory call.
76
+ * Controls which plugins and defaults will be applied.
77
+ */
78
+ preset?: keyof TestFrameworkPresets;
79
+ /**
80
+ * Skip factory-level default props during merge.
81
+ */
82
+ skipDefaultProps?: boolean;
83
+ /**
84
+ * Skip factory-level default slots during merge.
85
+ */
86
+ skipDefaultSlots?: boolean;
87
+ /**
88
+ * Skip BASE_MOUNT_OPTIONS during merge.
89
+ */
90
+ skipDefaultOptions?: boolean;
91
+ plugins?: PluginOverridesInput;
92
+ };
93
+ /**
94
+ * Default plugin configuration.
95
+ *
96
+ * The object keys must correspond to plugin names returned by
97
+ * `plugin.getName()` for plugins declared in `manifest`.
98
+ */
99
+ interface PresetDefinition {
100
+ manifest: PluginManifestEntry<any, any>[];
101
+ defaults: PluginConfigDefaults;
102
+ }
103
+ type TestFrameworkPresets = Record<string, PresetDefinition>;
104
+ interface PipelineContext {
105
+ defaultMountOptions: ComponentFactoryOptions;
106
+ mountOptions: ComponentFactoryOptions;
107
+ extraOptions: ComponentFactoryExtraOptions;
108
+ supportedPlugins: SupportedPluginsMap;
109
+ preset: PresetDefinition | undefined;
110
+ result: PipelineContextResult;
111
+ }
112
+ /**
113
+ * Runtime type.
114
+ *
115
+ * The pipeline operates without knowledge of a specific component,
116
+ * therefore Props/Data generics are intentionally erased.
117
+ */
118
+ type MountOptionsState = Partial<MountingOptions<any, any>>;
119
+ interface PipelineContextResult {
120
+ mountOptions: MountOptionsState;
121
+ global: NonNullable<MountingOptions<any, any>["global"]>;
122
+ pluginDefaultsState: PluginConfigDefaults;
123
+ plugins: ResolvedPluginOptions;
124
+ }
125
+ /**
126
+ * Input props accepted by TestForge.
127
+ *
128
+ * Props are intentionally typed as Partial<ComponentProps<T>>.
129
+ *
130
+ * TestForge merges props from multiple sources:
131
+ * - factory defaults
132
+ * - mount option props
133
+ * - per-test props
134
+ *
135
+ * Because each source represents only a partial contribution
136
+ * to the final prop set, requiring complete component props
137
+ * at every layer would be unnecessarily restrictive.
138
+ */
139
+ type ComponentPropsInput<T extends Component> = Partial<ComponentProps<T>>;
140
+ type RelaxedSlot<T> = T extends (props: infer P) => unknown ? (props: P) => unknown : () => unknown;
141
+ type ComponentSlotsInput<T extends Component> = Partial<{
142
+ [K in keyof ComponentSlots<T>]: RelaxedSlot<ComponentSlots<T>[K]>;
143
+ }>;
144
+ type ComponentData<T extends Component> = T extends {
145
+ data?(...args: any): infer D;
146
+ } ? D extends Record<string, any> ? D : Record<string, never> : Record<string, never>;
147
+ type ComponentDataInput<T extends Component> = Partial<ComponentData<T>>;
148
+ /**
149
+ * Main component factory returned by testComponentFactory
150
+ *
151
+ * Preserve exact Vue Test Utils wrapper typing.
152
+ *
153
+ * TestForge intentionally mirrors VTU mount() return types
154
+ * instead of maintaining a parallel wrapper type hierarchy.
155
+ */
156
+ type ComponentFactory<T extends Component> = (props?: ComponentPropsInput<T>, mountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, slots?: ComponentSlotsInput<T>, extraOptions?: ComponentFactoryExtraOptions) => ReturnType<typeof mount<T>>;
157
+ interface CreateTestFrameworkOptions {
158
+ /** Preset configurations for plugins */
159
+ presets?: TestFrameworkPresets;
160
+ /**
161
+ * Default value for Vue Test Utils `shallow` mounting.
162
+ *
163
+ * Used when a factory call does not explicitly provide
164
+ * the `shallow` option.
165
+ *
166
+ * @default false
167
+ */
168
+ shallowByDefault?: boolean;
169
+ }
170
+ interface ComponentFactoryCreator {
171
+ <T extends Component>(component: T, defaultProps?: ComponentPropsInput<T>, defaultMountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, defaultSlots?: ComponentSlotsInput<T>): ComponentFactory<T>;
172
+ }
173
+ interface TestFramework {
174
+ /**
175
+ * Creates a reusable component mounting factory.
176
+ */
177
+ testComponentFactory: ComponentFactoryCreator;
178
+ }
179
+
180
+ declare function createTestFramework(options?: CreateTestFrameworkOptions): TestFramework;
181
+
182
+ declare function createPluginInstance<TInstance, TOptions extends object>(factory: (options: TOptions) => TInstance, options: RuntimePluginOptions<TInstance, TOptions>): TInstance;
183
+
184
+ declare function createVuePlugin<TPlugin extends Plugin, TOptions extends object>(plugin: TPlugin, options: RuntimePluginOptions<[TPlugin, TOptions], TOptions>): [TPlugin, TOptions];
185
+
186
+ declare function captureInstance<T = unknown>(): InstanceCapture<T>;
187
+
188
+ declare function validatePreset(name: PluginName, preset: PresetDefinition): void;
189
+
190
+ declare function validatePresets(presets?: TestFrameworkPresets): void;
191
+
192
+ declare const Types: {};
193
+
194
+ export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type MountPlugin, type PluginControlOptions, type PluginModule, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, validatePreset, validatePresets };
@@ -0,0 +1,194 @@
1
+ import { Component, Plugin } from 'vue';
2
+ import { MountingOptions, mount } from '@vue/test-utils';
3
+ import { ComponentProps, ComponentSlots } from 'vue-component-type-helpers';
4
+
5
+ /** Plugin name (e.g., ‘pinia’, ‘i18n’, ‘router’) */
6
+ type PluginName = string;
7
+ /**
8
+ * Runtime value returned by a TestForge plugin factory.
9
+ *
10
+ * The returned value must be compatible with
11
+ * Vue Test Utils `global.plugins`.
12
+ */
13
+ type MountPlugin = Plugin | [Plugin, ...unknown[]];
14
+ interface PluginDefinition<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
15
+ beforeCreate?: (ctx: PipelineContext, options: TOptions) => TOptions;
16
+ create: (options: TOptions) => TPlugin;
17
+ afterCreate?: (plugin: TPlugin, ctx: PipelineContext) => void;
18
+ }
19
+ interface PluginModule<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
20
+ getName(): PluginName;
21
+ getDefinition(): PluginDefinition<TPlugin, TOptions>;
22
+ }
23
+ interface PluginManifestEntry<TPlugin extends MountPlugin = MountPlugin, TOptions = unknown> {
24
+ module: PluginModule<TPlugin, TOptions>;
25
+ enabled: boolean;
26
+ }
27
+ type SupportedPluginState = boolean;
28
+ type SupportedPluginsMap = Record<PluginName, SupportedPluginState>;
29
+ type RuntimePluginConfig = Record<string, any>;
30
+ type RuntimePluginOption = RuntimePluginConfig | false;
31
+ type ResolvedPluginOptions = Record<PluginName, RuntimePluginOption>;
32
+ type PluginConfigDefaults = Record<PluginName, RuntimePluginConfig>;
33
+ interface PluginRuntimeMeta<TInstance> {
34
+ __sharedInstance?: TInstance;
35
+ expose?: (instance: TInstance) => void;
36
+ }
37
+ type RuntimePluginOptions<TInstance, TOptions = object> = TOptions & PluginRuntimeMeta<TInstance>;
38
+ interface InstanceCapture<TInstance> {
39
+ expose(instance: TInstance): void;
40
+ readonly instance: TInstance | undefined;
41
+ }
42
+ interface PluginMeta {
43
+ instance?: unknown;
44
+ }
45
+ interface PluginOptionsMap {
46
+ }
47
+ type PluginOptionsInput = {
48
+ [K in keyof PluginOptionsMap]?: PluginOptionsMap[K] | false;
49
+ };
50
+ interface PluginControlOptions<TInstance> {
51
+ expose?: (instance: TInstance) => void;
52
+ }
53
+ type PluginOverride<T = unknown> = (T extends Record<string, any> ? Partial<T> & {
54
+ __meta?: PluginMeta;
55
+ } : T & {
56
+ __meta?: PluginMeta;
57
+ }) | false;
58
+ type PluginOverridesInput = {
59
+ [K in keyof PluginOptionsMap]?: PluginOverride<PluginOptionsMap[K]>;
60
+ };
61
+ interface ComponentFactoryOptions<Props = any, Slots = any, Data = any> extends Omit<MountingOptions<Props, Data>, "props" | "slots" | "data"> {
62
+ /** Strictly typed data */
63
+ data?: () => Data;
64
+ /** Strictly typed props */
65
+ props?: Props;
66
+ /** Strictly typed slots */
67
+ slots?: Slots;
68
+ /** Managed plugin configuration */
69
+ plugins?: PluginOptionsInput;
70
+ /** Disable managed plugins from presets */
71
+ skipManagedPlugins?: boolean;
72
+ }
73
+ type ComponentFactoryExtraOptions = {
74
+ /**
75
+ * Name of the preset to activate for this factory call.
76
+ * Controls which plugins and defaults will be applied.
77
+ */
78
+ preset?: keyof TestFrameworkPresets;
79
+ /**
80
+ * Skip factory-level default props during merge.
81
+ */
82
+ skipDefaultProps?: boolean;
83
+ /**
84
+ * Skip factory-level default slots during merge.
85
+ */
86
+ skipDefaultSlots?: boolean;
87
+ /**
88
+ * Skip BASE_MOUNT_OPTIONS during merge.
89
+ */
90
+ skipDefaultOptions?: boolean;
91
+ plugins?: PluginOverridesInput;
92
+ };
93
+ /**
94
+ * Default plugin configuration.
95
+ *
96
+ * The object keys must correspond to plugin names returned by
97
+ * `plugin.getName()` for plugins declared in `manifest`.
98
+ */
99
+ interface PresetDefinition {
100
+ manifest: PluginManifestEntry<any, any>[];
101
+ defaults: PluginConfigDefaults;
102
+ }
103
+ type TestFrameworkPresets = Record<string, PresetDefinition>;
104
+ interface PipelineContext {
105
+ defaultMountOptions: ComponentFactoryOptions;
106
+ mountOptions: ComponentFactoryOptions;
107
+ extraOptions: ComponentFactoryExtraOptions;
108
+ supportedPlugins: SupportedPluginsMap;
109
+ preset: PresetDefinition | undefined;
110
+ result: PipelineContextResult;
111
+ }
112
+ /**
113
+ * Runtime type.
114
+ *
115
+ * The pipeline operates without knowledge of a specific component,
116
+ * therefore Props/Data generics are intentionally erased.
117
+ */
118
+ type MountOptionsState = Partial<MountingOptions<any, any>>;
119
+ interface PipelineContextResult {
120
+ mountOptions: MountOptionsState;
121
+ global: NonNullable<MountingOptions<any, any>["global"]>;
122
+ pluginDefaultsState: PluginConfigDefaults;
123
+ plugins: ResolvedPluginOptions;
124
+ }
125
+ /**
126
+ * Input props accepted by TestForge.
127
+ *
128
+ * Props are intentionally typed as Partial<ComponentProps<T>>.
129
+ *
130
+ * TestForge merges props from multiple sources:
131
+ * - factory defaults
132
+ * - mount option props
133
+ * - per-test props
134
+ *
135
+ * Because each source represents only a partial contribution
136
+ * to the final prop set, requiring complete component props
137
+ * at every layer would be unnecessarily restrictive.
138
+ */
139
+ type ComponentPropsInput<T extends Component> = Partial<ComponentProps<T>>;
140
+ type RelaxedSlot<T> = T extends (props: infer P) => unknown ? (props: P) => unknown : () => unknown;
141
+ type ComponentSlotsInput<T extends Component> = Partial<{
142
+ [K in keyof ComponentSlots<T>]: RelaxedSlot<ComponentSlots<T>[K]>;
143
+ }>;
144
+ type ComponentData<T extends Component> = T extends {
145
+ data?(...args: any): infer D;
146
+ } ? D extends Record<string, any> ? D : Record<string, never> : Record<string, never>;
147
+ type ComponentDataInput<T extends Component> = Partial<ComponentData<T>>;
148
+ /**
149
+ * Main component factory returned by testComponentFactory
150
+ *
151
+ * Preserve exact Vue Test Utils wrapper typing.
152
+ *
153
+ * TestForge intentionally mirrors VTU mount() return types
154
+ * instead of maintaining a parallel wrapper type hierarchy.
155
+ */
156
+ type ComponentFactory<T extends Component> = (props?: ComponentPropsInput<T>, mountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, slots?: ComponentSlotsInput<T>, extraOptions?: ComponentFactoryExtraOptions) => ReturnType<typeof mount<T>>;
157
+ interface CreateTestFrameworkOptions {
158
+ /** Preset configurations for plugins */
159
+ presets?: TestFrameworkPresets;
160
+ /**
161
+ * Default value for Vue Test Utils `shallow` mounting.
162
+ *
163
+ * Used when a factory call does not explicitly provide
164
+ * the `shallow` option.
165
+ *
166
+ * @default false
167
+ */
168
+ shallowByDefault?: boolean;
169
+ }
170
+ interface ComponentFactoryCreator {
171
+ <T extends Component>(component: T, defaultProps?: ComponentPropsInput<T>, defaultMountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, defaultSlots?: ComponentSlotsInput<T>): ComponentFactory<T>;
172
+ }
173
+ interface TestFramework {
174
+ /**
175
+ * Creates a reusable component mounting factory.
176
+ */
177
+ testComponentFactory: ComponentFactoryCreator;
178
+ }
179
+
180
+ declare function createTestFramework(options?: CreateTestFrameworkOptions): TestFramework;
181
+
182
+ declare function createPluginInstance<TInstance, TOptions extends object>(factory: (options: TOptions) => TInstance, options: RuntimePluginOptions<TInstance, TOptions>): TInstance;
183
+
184
+ declare function createVuePlugin<TPlugin extends Plugin, TOptions extends object>(plugin: TPlugin, options: RuntimePluginOptions<[TPlugin, TOptions], TOptions>): [TPlugin, TOptions];
185
+
186
+ declare function captureInstance<T = unknown>(): InstanceCapture<T>;
187
+
188
+ declare function validatePreset(name: PluginName, preset: PresetDefinition): void;
189
+
190
+ declare function validatePresets(presets?: TestFrameworkPresets): void;
191
+
192
+ declare const Types: {};
193
+
194
+ export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type MountPlugin, type PluginControlOptions, type PluginModule, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, validatePreset, validatePresets };