@testforgejs/vue-test-core 1.0.0-beta.1 → 1.0.0-beta.2
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/README.md +84 -2
- package/dist/index.cjs +55 -32
- package/dist/index.d.cts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +55 -32
- package/package.json +2 -6
package/README.md
CHANGED
|
@@ -60,6 +60,58 @@ A preset controls:
|
|
|
60
60
|
|
|
61
61
|
The preset system keeps the TestForge core independent from specific Vue ecosystem integrations. The core runtime does not need built-in knowledge of Pinia, Vue Router, Vue I18n, Vuetify, PrimeVue, or other integrations.
|
|
62
62
|
|
|
63
|
+
### Single and Multiple Presets
|
|
64
|
+
|
|
65
|
+
`createTestFramework()` supports two mutually exclusive ways to configure presets.
|
|
66
|
+
|
|
67
|
+
Use `preset` when the framework needs a single runtime environment:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
createTestFramework({
|
|
71
|
+
preset: projectPreset,
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `presets` when the framework should provide multiple named runtime environments:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
createTestFramework({
|
|
79
|
+
presets: {
|
|
80
|
+
default: projectPreset,
|
|
81
|
+
i18n: i18nPreset,
|
|
82
|
+
router: routerPreset,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
These options cannot be used together.
|
|
88
|
+
|
|
89
|
+
A single `preset` is treated as the framework's `default` preset internally. A `presets` registry allows individual factory invocations to select a named preset through `extraOptions.preset`.
|
|
90
|
+
|
|
91
|
+
For example:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const { testComponentFactory } = createTestFramework({
|
|
95
|
+
presets: {
|
|
96
|
+
default: defaultPreset,
|
|
97
|
+
i18n: i18nPreset,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const factory = testComponentFactory(MyComponent);
|
|
102
|
+
|
|
103
|
+
factory(
|
|
104
|
+
{},
|
|
105
|
+
{},
|
|
106
|
+
{},
|
|
107
|
+
{
|
|
108
|
+
preset: "i18n",
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This distinction allows a project to start with a single custom runtime environment and introduce named runtime profiles later without changing the preset definition itself.
|
|
114
|
+
|
|
63
115
|
### Official preset packages
|
|
64
116
|
|
|
65
117
|
TestForge provides a layered preset architecture:
|
|
@@ -100,7 +152,11 @@ The recommended presets include configurations for commonly used managed integra
|
|
|
100
152
|
- Vue I18n;
|
|
101
153
|
- Vue Router.
|
|
102
154
|
|
|
103
|
-
The recommended preset
|
|
155
|
+
The recommended preset is a convenient starting point for exploring TestForge and its approach to reusable component test environments.
|
|
156
|
+
|
|
157
|
+
However, recommended presets are intentionally generic. Real applications usually have application-specific routes, managed plugins, and plugin defaults. Most projects will therefore eventually benefit from a project-specific preset that extends or adapts an existing preset to the application's runtime environment.
|
|
158
|
+
|
|
159
|
+
The recommended preset packages are optional. You can also use the base preset directly or create your own project-specific preset.
|
|
104
160
|
|
|
105
161
|
> [!TIP]
|
|
106
162
|
> If you are getting started with TestForge, use the recommended preset that matches your test runner.
|
|
@@ -111,7 +167,7 @@ See the [Getting Started Guide](https://github.com/testforgejs/testforge/blob/ma
|
|
|
111
167
|
|
|
112
168
|
## Quick Usage
|
|
113
169
|
|
|
114
|
-
The following example uses Vitest and the recommended Vitest preset.
|
|
170
|
+
The following example uses Vitest and the recommended Vitest preset registry.
|
|
115
171
|
|
|
116
172
|
```typescript
|
|
117
173
|
// tests/setup.ts
|
|
@@ -126,6 +182,8 @@ const { testComponentFactory } = createTestFramework({
|
|
|
126
182
|
export { testComponentFactory };
|
|
127
183
|
```
|
|
128
184
|
|
|
185
|
+
This setup is a good starting point for exploring TestForge. As the application-specific testing environment grows, the project can define its own preset while continuing to reuse the official preset as a base.
|
|
186
|
+
|
|
129
187
|
The resulting `testComponentFactory` can then be imported and reused throughout your component tests.
|
|
130
188
|
|
|
131
189
|
```typescript
|
|
@@ -151,6 +209,30 @@ For Jest projects, use `@testforgejs/vue-test-preset-recommended-jest` instead.
|
|
|
151
209
|
|
|
152
210
|
👉 For a complete walkthrough, continue with the [Getting Started Guide](https://github.com/testforgejs/testforge/blob/main/docs/getting-started.md).
|
|
153
211
|
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Project-Specific Presets
|
|
215
|
+
|
|
216
|
+
Most applications will eventually benefit from some application-specific preset configuration.
|
|
217
|
+
|
|
218
|
+
For example, a project can extend the recommended preset with its own locale configuration:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { extendPreset } from "@testforgejs/vue-test-core";
|
|
222
|
+
import { presets as recommendedPresets } from "@testforgejs/vue-test-preset-recommended";
|
|
223
|
+
|
|
224
|
+
const projectPreset = extendPreset(recommendedPresets.default, {
|
|
225
|
+
defaults: {
|
|
226
|
+
i18n: () => ({
|
|
227
|
+
...recommendedPresets.default.defaults.i18n(),
|
|
228
|
+
locale: "uk",
|
|
229
|
+
}),
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
154
236
|
## Documentation
|
|
155
237
|
|
|
156
238
|
- [Getting Started Guide](https://github.com/testforgejs/testforge/blob/main/docs/getting-started.md) — Set up TestForge in a project and create reusable component test factories.
|
package/dist/index.cjs
CHANGED
|
@@ -56,16 +56,29 @@ var FRAMEWORK_NAME = "TestForge";
|
|
|
56
56
|
var ERROR_PREFIX = `[${FRAMEWORK_NAME}]`;
|
|
57
57
|
var DEFAULT_PRESET_NAME = "default";
|
|
58
58
|
|
|
59
|
+
// src/guards/isPlainObject.ts
|
|
60
|
+
function isPlainObject(item) {
|
|
61
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const prototype = Object.getPrototypeOf(item);
|
|
65
|
+
return prototype === Object.prototype || prototype === null;
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
// src/presets/validators/validatePreset.ts
|
|
60
69
|
function validatePreset(name, preset) {
|
|
61
70
|
if (!preset) {
|
|
62
71
|
throw new Error(`${ERROR_PREFIX} Preset "${name}" is null or undefined.`);
|
|
63
72
|
}
|
|
64
|
-
if (!
|
|
73
|
+
if (!isPlainObject(preset)) {
|
|
74
|
+
throw new Error(`${ERROR_PREFIX} Preset "${name}" must be a plain object.`);
|
|
75
|
+
}
|
|
76
|
+
const manifest = preset.manifest;
|
|
77
|
+
if (!Array.isArray(manifest)) {
|
|
65
78
|
throw new Error(`${ERROR_PREFIX} Preset "${name}" must have a "manifest" array.`);
|
|
66
79
|
}
|
|
67
80
|
const manifestPluginNames = /* @__PURE__ */ new Set();
|
|
68
|
-
|
|
81
|
+
manifest.forEach((entry, index) => {
|
|
69
82
|
const { module: module2, enabled } = entry;
|
|
70
83
|
if (!module2 || typeof module2.getName !== "function") {
|
|
71
84
|
throw new Error(`${ERROR_PREFIX} Invalid module at manifest[${index}] in preset "${name}".`);
|
|
@@ -83,22 +96,24 @@ function validatePreset(name, preset) {
|
|
|
83
96
|
}
|
|
84
97
|
manifestPluginNames.add(pluginName);
|
|
85
98
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (!manifestPluginNames.has(key)) {
|
|
90
|
-
throw new Error(
|
|
91
|
-
`${ERROR_PREFIX} Preset "${name}" contains defaults for unknown plugin "${key}". This plugin is not present in the manifest.`
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
const value = preset.defaults[key];
|
|
95
|
-
if (typeof value !== "function") {
|
|
96
|
-
throw new Error(
|
|
97
|
-
`${ERROR_PREFIX} Invalid default configuration for plugin "${key}" in preset "${name}". Expected a plugin options factory function, but received ${typeof value}.`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
99
|
+
const defaults = preset.defaults;
|
|
100
|
+
if (!isPlainObject(defaults)) {
|
|
101
|
+
throw new Error(`${ERROR_PREFIX} Preset "${name}" must have a "defaults" plain object.`);
|
|
101
102
|
}
|
|
103
|
+
const defaultKeys = Object.keys(defaults);
|
|
104
|
+
defaultKeys.forEach((key) => {
|
|
105
|
+
if (!manifestPluginNames.has(key)) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`${ERROR_PREFIX} Preset "${name}" contains defaults for unknown plugin "${key}". This plugin is not present in the manifest.`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const value = defaults[key];
|
|
111
|
+
if (typeof value !== "function") {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`${ERROR_PREFIX} Invalid default configuration for plugin "${key}" in preset "${name}". Expected a plugin options factory function, but received ${typeof value}.`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
102
117
|
}
|
|
103
118
|
|
|
104
119
|
// src/presets/getActivePreset.ts
|
|
@@ -331,15 +346,6 @@ var withBaseMountOptions = (ctx) => {
|
|
|
331
346
|
});
|
|
332
347
|
};
|
|
333
348
|
|
|
334
|
-
// src/guards/isPlainObject.ts
|
|
335
|
-
function isPlainObject(item) {
|
|
336
|
-
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
337
|
-
return false;
|
|
338
|
-
}
|
|
339
|
-
const prototype = Object.getPrototypeOf(item);
|
|
340
|
-
return prototype === Object.prototype || prototype === null;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
349
|
// src/utils/mergeConfigs.ts
|
|
344
350
|
function mergeConfigs(target, source) {
|
|
345
351
|
const arrays = Array.isArray(target) && Array.isArray(source);
|
|
@@ -643,7 +649,7 @@ function mountWithPlugins(component, ctx, overrides = {}, runtimeOptions = {
|
|
|
643
649
|
}
|
|
644
650
|
|
|
645
651
|
// src/presets/validators/validatePresets.ts
|
|
646
|
-
function validatePresets(presets
|
|
652
|
+
function validatePresets(presets) {
|
|
647
653
|
if (!isPlainObject(presets)) {
|
|
648
654
|
throw new Error(`${ERROR_PREFIX} Presets must be a plain object.`);
|
|
649
655
|
}
|
|
@@ -652,8 +658,8 @@ function validatePresets(presets = {}) {
|
|
|
652
658
|
});
|
|
653
659
|
}
|
|
654
660
|
|
|
655
|
-
// src/assertions/
|
|
656
|
-
function
|
|
661
|
+
// src/assertions/assertIsPlainObjectValue.ts
|
|
662
|
+
function assertIsPlainObjectValue(value, name = "value") {
|
|
657
663
|
if (!isPlainObject(value)) {
|
|
658
664
|
throw new Error(`${name} must be a plain object.`);
|
|
659
665
|
}
|
|
@@ -661,8 +667,14 @@ function assertIsPlainObject(value, name = "value") {
|
|
|
661
667
|
|
|
662
668
|
// src/validators/validateCreateTestFrameworkOptions.ts
|
|
663
669
|
function validateCreateTestFrameworkOptions(options = {}) {
|
|
664
|
-
|
|
665
|
-
const {
|
|
670
|
+
assertIsPlainObjectValue(options, "createTestFramework options");
|
|
671
|
+
const { preset, presets, shallowByDefault } = options;
|
|
672
|
+
if (preset !== void 0 && presets !== void 0) {
|
|
673
|
+
throw new Error(`${ERROR_PREFIX} "preset" and "presets" cannot be used together.`);
|
|
674
|
+
}
|
|
675
|
+
if (preset !== void 0) {
|
|
676
|
+
validatePreset("default", preset);
|
|
677
|
+
}
|
|
666
678
|
if (presets !== void 0) {
|
|
667
679
|
validatePresets(presets);
|
|
668
680
|
}
|
|
@@ -765,10 +777,21 @@ function validateComponentFactoryArguments(props, mountOptions, slots, extraOpti
|
|
|
765
777
|
validateComponentFactoryExtraOptions(extraOptions, presets);
|
|
766
778
|
}
|
|
767
779
|
|
|
780
|
+
// src/core/utils/resolvePresets.ts
|
|
781
|
+
function resolvePresets(options) {
|
|
782
|
+
if (options.preset !== void 0) {
|
|
783
|
+
return {
|
|
784
|
+
default: options.preset
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
return options.presets ?? {};
|
|
788
|
+
}
|
|
789
|
+
|
|
768
790
|
// src/core/createTestFramework.ts
|
|
769
791
|
function createTestFramework(options = {}) {
|
|
770
792
|
validateCreateTestFrameworkOptions(options);
|
|
771
|
-
const {
|
|
793
|
+
const { shallowByDefault = false } = options;
|
|
794
|
+
const presets = resolvePresets(options);
|
|
772
795
|
const testComponentFactory = (component, defaultProps = {}, defaultMountOptions = {}, defaultSlots = {}) => {
|
|
773
796
|
validateTestComponentFactoryArguments(
|
|
774
797
|
component,
|
package/dist/index.d.cts
CHANGED
|
@@ -29,6 +29,12 @@ type SupportedPluginsMap = Record<PluginName, SupportedPluginState>;
|
|
|
29
29
|
type RuntimePluginConfig = Record<string, any>;
|
|
30
30
|
type RuntimePluginOption = RuntimePluginConfig | false;
|
|
31
31
|
type ResolvedPluginOptions = Record<PluginName, RuntimePluginOption>;
|
|
32
|
+
/**
|
|
33
|
+
* Default plugin configuration factories.
|
|
34
|
+
*
|
|
35
|
+
* Only plugins that require preset-level default configuration
|
|
36
|
+
* need to be included.
|
|
37
|
+
*/
|
|
32
38
|
type PluginConfigDefaults = Record<PluginName, PluginOptionsFactory<RuntimePluginConfig>>;
|
|
33
39
|
type ResolvedPluginDefaults = Record<PluginName, RuntimePluginConfig>;
|
|
34
40
|
interface PluginRuntimeMeta<TInstance> {
|
|
@@ -98,7 +104,15 @@ type ComponentFactoryExtraOptions = {
|
|
|
98
104
|
* `plugin.getName()` for plugins declared in `manifest`.
|
|
99
105
|
*/
|
|
100
106
|
interface PresetDefinition {
|
|
107
|
+
/** Plugins available to the preset and their enabled state. */
|
|
101
108
|
manifest: PluginManifestEntry<any, any>[];
|
|
109
|
+
/**
|
|
110
|
+
* Default plugin configurations.
|
|
111
|
+
*
|
|
112
|
+
* A plugin declared in `manifest` does not have to be present here.
|
|
113
|
+
* Missing defaults mean that the preset provides no default configuration
|
|
114
|
+
* for that plugin.
|
|
115
|
+
*/
|
|
102
116
|
defaults: PluginConfigDefaults;
|
|
103
117
|
}
|
|
104
118
|
type TestFrameworkPresets = Record<string, PresetDefinition>;
|
|
@@ -160,9 +174,7 @@ type ComponentDataInput<T extends Component> = Partial<ComponentData<T>>;
|
|
|
160
174
|
* instead of maintaining a parallel wrapper type hierarchy.
|
|
161
175
|
*/
|
|
162
176
|
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>>;
|
|
163
|
-
interface
|
|
164
|
-
/** Preset configurations for plugins */
|
|
165
|
-
presets?: TestFrameworkPresets;
|
|
177
|
+
interface CommonCreateTestFrameworkOptions {
|
|
166
178
|
/**
|
|
167
179
|
* Default value for Vue Test Utils `shallow` mounting.
|
|
168
180
|
*
|
|
@@ -173,6 +185,17 @@ interface CreateTestFrameworkOptions {
|
|
|
173
185
|
*/
|
|
174
186
|
shallowByDefault?: boolean;
|
|
175
187
|
}
|
|
188
|
+
interface SinglePresetOptions extends CommonCreateTestFrameworkOptions {
|
|
189
|
+
/** Single preset used by the framework. */
|
|
190
|
+
preset: PresetDefinition;
|
|
191
|
+
presets?: never;
|
|
192
|
+
}
|
|
193
|
+
interface MultiplePresetsOptions extends CommonCreateTestFrameworkOptions {
|
|
194
|
+
/** Named preset configurations for plugins. */
|
|
195
|
+
preset?: never;
|
|
196
|
+
presets?: TestFrameworkPresets;
|
|
197
|
+
}
|
|
198
|
+
type CreateTestFrameworkOptions = SinglePresetOptions | MultiplePresetsOptions;
|
|
176
199
|
interface ComponentFactoryCreator {
|
|
177
200
|
<T extends Component>(component: T, defaultProps?: ComponentPropsInput<T>, defaultMountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, defaultSlots?: ComponentSlotsInput<T>): ComponentFactory<T>;
|
|
178
201
|
}
|
|
@@ -193,10 +216,10 @@ declare function captureInstance<T = unknown>(): InstanceCapture<T>;
|
|
|
193
216
|
|
|
194
217
|
declare function extendPreset(basePreset: PresetDefinition, extension: PresetExtension): PresetDefinition;
|
|
195
218
|
|
|
196
|
-
declare function validatePreset(name:
|
|
219
|
+
declare function validatePreset(name: string, preset: unknown): asserts preset is PresetDefinition;
|
|
197
220
|
|
|
198
|
-
declare function validatePresets(presets
|
|
221
|
+
declare function validatePresets(presets: unknown): asserts presets is TestFrameworkPresets;
|
|
199
222
|
|
|
200
223
|
declare const Types: {};
|
|
201
224
|
|
|
202
|
-
export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type MountPlugin, type PluginControlOptions, type PluginModule, type PluginOptionsFactory, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, extendPreset, validatePreset, validatePresets };
|
|
225
|
+
export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type CreateTestFrameworkOptions, type MountPlugin, type PluginControlOptions, type PluginManifestEntry, type PluginModule, type PluginOptionsFactory, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type PresetExtension, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, extendPreset, validatePreset, validatePresets };
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,12 @@ type SupportedPluginsMap = Record<PluginName, SupportedPluginState>;
|
|
|
29
29
|
type RuntimePluginConfig = Record<string, any>;
|
|
30
30
|
type RuntimePluginOption = RuntimePluginConfig | false;
|
|
31
31
|
type ResolvedPluginOptions = Record<PluginName, RuntimePluginOption>;
|
|
32
|
+
/**
|
|
33
|
+
* Default plugin configuration factories.
|
|
34
|
+
*
|
|
35
|
+
* Only plugins that require preset-level default configuration
|
|
36
|
+
* need to be included.
|
|
37
|
+
*/
|
|
32
38
|
type PluginConfigDefaults = Record<PluginName, PluginOptionsFactory<RuntimePluginConfig>>;
|
|
33
39
|
type ResolvedPluginDefaults = Record<PluginName, RuntimePluginConfig>;
|
|
34
40
|
interface PluginRuntimeMeta<TInstance> {
|
|
@@ -98,7 +104,15 @@ type ComponentFactoryExtraOptions = {
|
|
|
98
104
|
* `plugin.getName()` for plugins declared in `manifest`.
|
|
99
105
|
*/
|
|
100
106
|
interface PresetDefinition {
|
|
107
|
+
/** Plugins available to the preset and their enabled state. */
|
|
101
108
|
manifest: PluginManifestEntry<any, any>[];
|
|
109
|
+
/**
|
|
110
|
+
* Default plugin configurations.
|
|
111
|
+
*
|
|
112
|
+
* A plugin declared in `manifest` does not have to be present here.
|
|
113
|
+
* Missing defaults mean that the preset provides no default configuration
|
|
114
|
+
* for that plugin.
|
|
115
|
+
*/
|
|
102
116
|
defaults: PluginConfigDefaults;
|
|
103
117
|
}
|
|
104
118
|
type TestFrameworkPresets = Record<string, PresetDefinition>;
|
|
@@ -160,9 +174,7 @@ type ComponentDataInput<T extends Component> = Partial<ComponentData<T>>;
|
|
|
160
174
|
* instead of maintaining a parallel wrapper type hierarchy.
|
|
161
175
|
*/
|
|
162
176
|
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>>;
|
|
163
|
-
interface
|
|
164
|
-
/** Preset configurations for plugins */
|
|
165
|
-
presets?: TestFrameworkPresets;
|
|
177
|
+
interface CommonCreateTestFrameworkOptions {
|
|
166
178
|
/**
|
|
167
179
|
* Default value for Vue Test Utils `shallow` mounting.
|
|
168
180
|
*
|
|
@@ -173,6 +185,17 @@ interface CreateTestFrameworkOptions {
|
|
|
173
185
|
*/
|
|
174
186
|
shallowByDefault?: boolean;
|
|
175
187
|
}
|
|
188
|
+
interface SinglePresetOptions extends CommonCreateTestFrameworkOptions {
|
|
189
|
+
/** Single preset used by the framework. */
|
|
190
|
+
preset: PresetDefinition;
|
|
191
|
+
presets?: never;
|
|
192
|
+
}
|
|
193
|
+
interface MultiplePresetsOptions extends CommonCreateTestFrameworkOptions {
|
|
194
|
+
/** Named preset configurations for plugins. */
|
|
195
|
+
preset?: never;
|
|
196
|
+
presets?: TestFrameworkPresets;
|
|
197
|
+
}
|
|
198
|
+
type CreateTestFrameworkOptions = SinglePresetOptions | MultiplePresetsOptions;
|
|
176
199
|
interface ComponentFactoryCreator {
|
|
177
200
|
<T extends Component>(component: T, defaultProps?: ComponentPropsInput<T>, defaultMountOptions?: ComponentFactoryOptions<ComponentPropsInput<T>, ComponentSlotsInput<T>, ComponentDataInput<T>>, defaultSlots?: ComponentSlotsInput<T>): ComponentFactory<T>;
|
|
178
201
|
}
|
|
@@ -193,10 +216,10 @@ declare function captureInstance<T = unknown>(): InstanceCapture<T>;
|
|
|
193
216
|
|
|
194
217
|
declare function extendPreset(basePreset: PresetDefinition, extension: PresetExtension): PresetDefinition;
|
|
195
218
|
|
|
196
|
-
declare function validatePreset(name:
|
|
219
|
+
declare function validatePreset(name: string, preset: unknown): asserts preset is PresetDefinition;
|
|
197
220
|
|
|
198
|
-
declare function validatePresets(presets
|
|
221
|
+
declare function validatePresets(presets: unknown): asserts presets is TestFrameworkPresets;
|
|
199
222
|
|
|
200
223
|
declare const Types: {};
|
|
201
224
|
|
|
202
|
-
export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type MountPlugin, type PluginControlOptions, type PluginModule, type PluginOptionsFactory, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, extendPreset, validatePreset, validatePresets };
|
|
225
|
+
export { type ComponentFactory, type ComponentFactoryCreator, type ComponentFactoryExtraOptions, type ComponentFactoryOptions, type CreateTestFrameworkOptions, type MountPlugin, type PluginControlOptions, type PluginManifestEntry, type PluginModule, type PluginOptionsFactory, type PluginOptionsInput, type PluginOptionsMap, type PluginOverridesInput, type PresetDefinition, type PresetExtension, type TestFramework, type TestFrameworkPresets, Types, captureInstance, createPluginInstance, createTestFramework, createVuePlugin, extendPreset, validatePreset, validatePresets };
|
package/dist/index.js
CHANGED
|
@@ -23,16 +23,29 @@ var FRAMEWORK_NAME = "TestForge";
|
|
|
23
23
|
var ERROR_PREFIX = `[${FRAMEWORK_NAME}]`;
|
|
24
24
|
var DEFAULT_PRESET_NAME = "default";
|
|
25
25
|
|
|
26
|
+
// src/guards/isPlainObject.ts
|
|
27
|
+
function isPlainObject(item) {
|
|
28
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const prototype = Object.getPrototypeOf(item);
|
|
32
|
+
return prototype === Object.prototype || prototype === null;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
// src/presets/validators/validatePreset.ts
|
|
27
36
|
function validatePreset(name, preset) {
|
|
28
37
|
if (!preset) {
|
|
29
38
|
throw new Error(`${ERROR_PREFIX} Preset "${name}" is null or undefined.`);
|
|
30
39
|
}
|
|
31
|
-
if (!
|
|
40
|
+
if (!isPlainObject(preset)) {
|
|
41
|
+
throw new Error(`${ERROR_PREFIX} Preset "${name}" must be a plain object.`);
|
|
42
|
+
}
|
|
43
|
+
const manifest = preset.manifest;
|
|
44
|
+
if (!Array.isArray(manifest)) {
|
|
32
45
|
throw new Error(`${ERROR_PREFIX} Preset "${name}" must have a "manifest" array.`);
|
|
33
46
|
}
|
|
34
47
|
const manifestPluginNames = /* @__PURE__ */ new Set();
|
|
35
|
-
|
|
48
|
+
manifest.forEach((entry, index) => {
|
|
36
49
|
const { module, enabled } = entry;
|
|
37
50
|
if (!module || typeof module.getName !== "function") {
|
|
38
51
|
throw new Error(`${ERROR_PREFIX} Invalid module at manifest[${index}] in preset "${name}".`);
|
|
@@ -50,22 +63,24 @@ function validatePreset(name, preset) {
|
|
|
50
63
|
}
|
|
51
64
|
manifestPluginNames.add(pluginName);
|
|
52
65
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!manifestPluginNames.has(key)) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
`${ERROR_PREFIX} Preset "${name}" contains defaults for unknown plugin "${key}". This plugin is not present in the manifest.`
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
const value = preset.defaults[key];
|
|
62
|
-
if (typeof value !== "function") {
|
|
63
|
-
throw new Error(
|
|
64
|
-
`${ERROR_PREFIX} Invalid default configuration for plugin "${key}" in preset "${name}". Expected a plugin options factory function, but received ${typeof value}.`
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
66
|
+
const defaults = preset.defaults;
|
|
67
|
+
if (!isPlainObject(defaults)) {
|
|
68
|
+
throw new Error(`${ERROR_PREFIX} Preset "${name}" must have a "defaults" plain object.`);
|
|
68
69
|
}
|
|
70
|
+
const defaultKeys = Object.keys(defaults);
|
|
71
|
+
defaultKeys.forEach((key) => {
|
|
72
|
+
if (!manifestPluginNames.has(key)) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`${ERROR_PREFIX} Preset "${name}" contains defaults for unknown plugin "${key}". This plugin is not present in the manifest.`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const value = defaults[key];
|
|
78
|
+
if (typeof value !== "function") {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`${ERROR_PREFIX} Invalid default configuration for plugin "${key}" in preset "${name}". Expected a plugin options factory function, but received ${typeof value}.`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
// src/presets/getActivePreset.ts
|
|
@@ -298,15 +313,6 @@ var withBaseMountOptions = (ctx) => {
|
|
|
298
313
|
});
|
|
299
314
|
};
|
|
300
315
|
|
|
301
|
-
// src/guards/isPlainObject.ts
|
|
302
|
-
function isPlainObject(item) {
|
|
303
|
-
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
const prototype = Object.getPrototypeOf(item);
|
|
307
|
-
return prototype === Object.prototype || prototype === null;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
316
|
// src/utils/mergeConfigs.ts
|
|
311
317
|
function mergeConfigs(target, source) {
|
|
312
318
|
const arrays = Array.isArray(target) && Array.isArray(source);
|
|
@@ -610,7 +616,7 @@ function mountWithPlugins(component, ctx, overrides = {}, runtimeOptions = {
|
|
|
610
616
|
}
|
|
611
617
|
|
|
612
618
|
// src/presets/validators/validatePresets.ts
|
|
613
|
-
function validatePresets(presets
|
|
619
|
+
function validatePresets(presets) {
|
|
614
620
|
if (!isPlainObject(presets)) {
|
|
615
621
|
throw new Error(`${ERROR_PREFIX} Presets must be a plain object.`);
|
|
616
622
|
}
|
|
@@ -619,8 +625,8 @@ function validatePresets(presets = {}) {
|
|
|
619
625
|
});
|
|
620
626
|
}
|
|
621
627
|
|
|
622
|
-
// src/assertions/
|
|
623
|
-
function
|
|
628
|
+
// src/assertions/assertIsPlainObjectValue.ts
|
|
629
|
+
function assertIsPlainObjectValue(value, name = "value") {
|
|
624
630
|
if (!isPlainObject(value)) {
|
|
625
631
|
throw new Error(`${name} must be a plain object.`);
|
|
626
632
|
}
|
|
@@ -628,8 +634,14 @@ function assertIsPlainObject(value, name = "value") {
|
|
|
628
634
|
|
|
629
635
|
// src/validators/validateCreateTestFrameworkOptions.ts
|
|
630
636
|
function validateCreateTestFrameworkOptions(options = {}) {
|
|
631
|
-
|
|
632
|
-
const {
|
|
637
|
+
assertIsPlainObjectValue(options, "createTestFramework options");
|
|
638
|
+
const { preset, presets, shallowByDefault } = options;
|
|
639
|
+
if (preset !== void 0 && presets !== void 0) {
|
|
640
|
+
throw new Error(`${ERROR_PREFIX} "preset" and "presets" cannot be used together.`);
|
|
641
|
+
}
|
|
642
|
+
if (preset !== void 0) {
|
|
643
|
+
validatePreset("default", preset);
|
|
644
|
+
}
|
|
633
645
|
if (presets !== void 0) {
|
|
634
646
|
validatePresets(presets);
|
|
635
647
|
}
|
|
@@ -732,10 +744,21 @@ function validateComponentFactoryArguments(props, mountOptions, slots, extraOpti
|
|
|
732
744
|
validateComponentFactoryExtraOptions(extraOptions, presets);
|
|
733
745
|
}
|
|
734
746
|
|
|
747
|
+
// src/core/utils/resolvePresets.ts
|
|
748
|
+
function resolvePresets(options) {
|
|
749
|
+
if (options.preset !== void 0) {
|
|
750
|
+
return {
|
|
751
|
+
default: options.preset
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
return options.presets ?? {};
|
|
755
|
+
}
|
|
756
|
+
|
|
735
757
|
// src/core/createTestFramework.ts
|
|
736
758
|
function createTestFramework(options = {}) {
|
|
737
759
|
validateCreateTestFrameworkOptions(options);
|
|
738
|
-
const {
|
|
760
|
+
const { shallowByDefault = false } = options;
|
|
761
|
+
const presets = resolvePresets(options);
|
|
739
762
|
const testComponentFactory = (component, defaultProps = {}, defaultMountOptions = {}, defaultSlots = {}) => {
|
|
740
763
|
validateTestComponentFactoryArguments(
|
|
741
764
|
component,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testforgejs/vue-test-core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core testing utilities and pipeline orchestration for the TestForge component testing framework",
|
|
6
6
|
"homepage": "https://github.com/testforgejs/testforge#readme",
|
|
@@ -52,11 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@vue/test-utils": "^2.0.0",
|
|
55
|
-
"vue": "^3.3.0"
|
|
56
|
-
"vue-router": "^5.0.0",
|
|
57
|
-
"@testforgejs/vue-test-plugin-i18n": "1.0.0-beta.1",
|
|
58
|
-
"@testforgejs/vue-test-plugin-router": "1.0.0-beta.1",
|
|
59
|
-
"@testforgejs/vue-test-plugin-pinia": "1.0.0-beta.1"
|
|
55
|
+
"vue": "^3.3.0"
|
|
60
56
|
},
|
|
61
57
|
"tsd": {
|
|
62
58
|
"directory": "test-d"
|