@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.
package/dist/index.js ADDED
@@ -0,0 +1,831 @@
1
+ // src/utils/mergeComponentData.ts
2
+ function mergeComponentData({
3
+ defaultMountData = {},
4
+ defaultData = {},
5
+ mountData = {},
6
+ directData = {},
7
+ skipDefault = false,
8
+ skipOptions = false
9
+ }) {
10
+ const level1 = skipDefault ? {} : {
11
+ ...!skipOptions ? defaultMountData : {},
12
+ ...defaultData
13
+ };
14
+ const level2 = {
15
+ ...mountData,
16
+ ...directData
17
+ };
18
+ return { ...level1, ...level2 };
19
+ }
20
+
21
+ // src/constants/constants.ts
22
+ var FRAMEWORK_NAME = "TestForge";
23
+ var ERROR_PREFIX = `[${FRAMEWORK_NAME}]`;
24
+ var DEFAULT_PRESET_NAME = "default";
25
+
26
+ // src/validators/validatePreset.ts
27
+ function validatePreset(name, preset) {
28
+ if (!preset) {
29
+ throw new Error(`${ERROR_PREFIX} Preset "${name}" is null or undefined.`);
30
+ }
31
+ if (!Array.isArray(preset.manifest)) {
32
+ throw new Error(`${ERROR_PREFIX} Preset "${name}" must have a "manifest" array.`);
33
+ }
34
+ const manifestPluginNames = /* @__PURE__ */ new Set();
35
+ preset.manifest.forEach((entry, index) => {
36
+ const { module, enabled } = entry;
37
+ if (!module || typeof module.getName !== "function") {
38
+ throw new Error(`${ERROR_PREFIX} Invalid module at manifest[${index}] in preset "${name}".`);
39
+ }
40
+ const pluginName = module.getName();
41
+ if (manifestPluginNames.has(pluginName)) {
42
+ throw new Error(
43
+ `${ERROR_PREFIX} Duplicate plugin "${pluginName}" in manifest of preset "${name}".`
44
+ );
45
+ }
46
+ if (typeof enabled !== "boolean") {
47
+ throw new Error(
48
+ `${ERROR_PREFIX} Plugin "${pluginName}" in preset "${name}" must have a boolean "enabled" flag.`
49
+ );
50
+ }
51
+ manifestPluginNames.add(pluginName);
52
+ });
53
+ if (preset.defaults) {
54
+ const defaultKeys = Object.keys(preset.defaults);
55
+ defaultKeys.forEach((key) => {
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
+ const isObject = value !== null && typeof value === "object" && !Array.isArray(value);
63
+ if (!isObject) {
64
+ throw new Error(
65
+ `${ERROR_PREFIX} Invalid default configuration for plugin "${key}" in preset "${name}". Expected Object, but received ${typeof value}.`
66
+ );
67
+ }
68
+ });
69
+ }
70
+ }
71
+
72
+ // src/utils/getActivePreset.ts
73
+ function getActivePreset(presets = {}, extraOptions) {
74
+ const requestedPresetName = extraOptions?.preset?.trim();
75
+ const activeName = requestedPresetName || DEFAULT_PRESET_NAME;
76
+ const preset = presets[activeName];
77
+ if (requestedPresetName && !preset) {
78
+ throw new Error(
79
+ `[withPreset] Requested preset "${requestedPresetName}" not found in available presets.`
80
+ );
81
+ }
82
+ if (preset) {
83
+ validatePreset(activeName, preset);
84
+ }
85
+ return preset;
86
+ }
87
+
88
+ // src/utils/getPresetManifest.ts
89
+ function getPresetManifest(preset) {
90
+ return preset?.manifest ?? [];
91
+ }
92
+
93
+ // src/utils/createSupportedPluginsState.ts
94
+ function createSupportedPluginsState(preset) {
95
+ const map = {};
96
+ for (const { module, enabled } of getPresetManifest(preset)) {
97
+ if (typeof enabled !== "boolean") {
98
+ throw new Error(
99
+ `[TestForge] Plugin "${module.getName()}" has invalid "enabled" value: ${String(enabled)}. Expected boolean.`
100
+ );
101
+ }
102
+ map[module.getName()] = enabled;
103
+ }
104
+ return map;
105
+ }
106
+
107
+ // src/pipeline/core/createPipelineContext.ts
108
+ function createPipelineContext(params) {
109
+ const { defaultMountOptions = {}, mountOptions = {}, extraOptions = {}, presets = {} } = params;
110
+ const activePreset = getActivePreset(presets, extraOptions);
111
+ const supportedPlugins = createSupportedPluginsState(activePreset);
112
+ return {
113
+ defaultMountOptions,
114
+ mountOptions,
115
+ extraOptions,
116
+ supportedPlugins,
117
+ preset: activePreset,
118
+ result: {
119
+ mountOptions: {},
120
+ global: {},
121
+ pluginDefaultsState: {},
122
+ plugins: {}
123
+ }
124
+ };
125
+ }
126
+
127
+ // src/pipeline/core/runPipeline.ts
128
+ function runPipeline(ctx, middlewares) {
129
+ let context = ctx;
130
+ for (const middleware of middlewares) {
131
+ const result = middleware(context);
132
+ if (result) {
133
+ context = result;
134
+ }
135
+ }
136
+ return context;
137
+ }
138
+
139
+ // src/pipeline/core/createPipeline.ts
140
+ function createPipeline(middlewares) {
141
+ return {
142
+ /*
143
+ * Runs the middleware chain sequentially.
144
+ */
145
+ run(ctx) {
146
+ return runPipeline(ctx, middlewares);
147
+ }
148
+ };
149
+ }
150
+
151
+ // src/pipeline/middleware/typeGuards/assertIsObject.ts
152
+ function assertIsObject(val, name) {
153
+ if (val !== null && typeof val === "object" && !Array.isArray(val)) return;
154
+ throw new Error(
155
+ `${ERROR_PREFIX} Critical error: "${name}" must be an Object. Received ${Array.isArray(val) ? "array" : typeof val} (${val}).`
156
+ );
157
+ }
158
+
159
+ // src/pipeline/middleware/validation/assertConfigurationShape.ts
160
+ var assertConfigurationShape = (ctx) => {
161
+ assertIsObject(ctx.defaultMountOptions, "defaultMountOptions");
162
+ assertIsObject(ctx.mountOptions, "mountOptions");
163
+ assertIsObject(ctx.extraOptions, "extraOptions");
164
+ return ctx;
165
+ };
166
+
167
+ // src/pipeline/plugins/logic/resolveExtraOptions.ts
168
+ function resolveExtraOptions(extraOptions) {
169
+ return extraOptions;
170
+ }
171
+
172
+ // src/pipeline/middleware/validation/validators/assertUnsupportedPlugins.ts
173
+ var assertUnsupportedPlugins = (plugins, supported) => {
174
+ for (const name of Object.keys(plugins)) {
175
+ if (!supported.has(name)) {
176
+ throw new Error(
177
+ `${ERROR_PREFIX} Plugin "${name}" is configured but not supported by the active preset.`
178
+ );
179
+ }
180
+ }
181
+ };
182
+
183
+ // src/pipeline/middleware/validation/validators/assertExtraOptionUnsupportedPlugins.ts
184
+ var assertExtraOptionUnsupportedPlugins = (extraOptions, supported) => {
185
+ assertUnsupportedPlugins(extraOptions.plugins ?? {}, supported);
186
+ };
187
+
188
+ // src/pipeline/middleware/typeGuards/assertPluginValue.ts
189
+ function assertPluginValue(val, name, source) {
190
+ const isObject = val !== null && typeof val === "object" && !Array.isArray(val);
191
+ const isValid = val === void 0 || val === false || isObject;
192
+ if (!isValid) {
193
+ throw new Error(
194
+ `${ERROR_PREFIX} Invalid configuration for plugin "${name}" in ${source}. Expected Object or Boolean (false), but received ${typeof val} (${val}).`
195
+ );
196
+ }
197
+ }
198
+
199
+ // src/pipeline/middleware/validation/validators/assertResolvedPluginValues.ts
200
+ var assertResolvedPluginValues = (plugins) => {
201
+ for (const [name, value] of Object.entries(plugins)) {
202
+ assertPluginValue(value, name, "plugins");
203
+ }
204
+ };
205
+
206
+ // src/pipeline/middleware/validation/validators/assertExtraOptionPluginValues.ts
207
+ var assertExtraOptionPluginValues = (extraOptions, supported) => {
208
+ const plugins = extraOptions.plugins ?? {};
209
+ for (const name of supported) {
210
+ if (Object.prototype.hasOwnProperty.call(plugins, name)) {
211
+ assertPluginValue(plugins[name], name, "extraOptions");
212
+ }
213
+ }
214
+ };
215
+
216
+ // src/pipeline/middleware/validation/assertPluginOptions.ts
217
+ var assertPluginOptions = (ctx) => {
218
+ const { supportedPlugins, extraOptions } = ctx;
219
+ const { plugins } = ctx.result;
220
+ const supported = new Set(Object.keys(supportedPlugins));
221
+ assertUnsupportedPlugins(plugins || {}, supported);
222
+ assertExtraOptionUnsupportedPlugins(resolveExtraOptions(extraOptions), supported);
223
+ assertResolvedPluginValues(plugins);
224
+ assertExtraOptionPluginValues(resolveExtraOptions(extraOptions), supported);
225
+ return ctx;
226
+ };
227
+
228
+ // src/pipeline/middleware/validation/assertResultShape.ts
229
+ function validateResult(ctx) {
230
+ const { result } = ctx;
231
+ assertIsObject(result, "result");
232
+ assertIsObject(result.mountOptions, "result.mountOptions");
233
+ assertIsObject(result.global, "result.global");
234
+ assertIsObject(result.plugins, "result.plugins");
235
+ }
236
+ var assertResultShape = (ctx) => {
237
+ validateResult(ctx);
238
+ return ctx;
239
+ };
240
+ var assertFinalResultShape = (ctx) => {
241
+ validateResult(ctx);
242
+ return ctx;
243
+ };
244
+
245
+ // src/pipeline/state/mergeRecord.ts
246
+ function mergeRecord(base, patch) {
247
+ if (!patch) return base;
248
+ const result = { ...base };
249
+ for (const key in patch) {
250
+ const value = patch[key];
251
+ if (value !== void 0) {
252
+ result[key] = value;
253
+ }
254
+ }
255
+ return result;
256
+ }
257
+
258
+ // src/pipeline/state/patchResultState.ts
259
+ function patchResultState(ctx, patch) {
260
+ if (patch.mountOptions) {
261
+ ctx.result.mountOptions = mergeRecord(ctx.result.mountOptions, patch.mountOptions);
262
+ }
263
+ if (patch.plugins) {
264
+ ctx.result.plugins = mergeRecord(ctx.result.plugins, patch.plugins);
265
+ }
266
+ if (patch.pluginDefaultsState) {
267
+ ctx.result.pluginDefaultsState = mergeRecord(
268
+ ctx.result.pluginDefaultsState,
269
+ patch.pluginDefaultsState
270
+ );
271
+ }
272
+ if (patch.global) {
273
+ ctx.result.global = mergeRecord(ctx.result.global, patch.global);
274
+ }
275
+ return ctx;
276
+ }
277
+
278
+ // src/pipeline/middleware/transformers/withBaseMountOptions.ts
279
+ var withBaseMountOptions = (ctx) => {
280
+ const { defaultMountOptions, mountOptions, extraOptions } = ctx;
281
+ const {
282
+ global: _dg,
283
+ plugins: _dp,
284
+ attrs: _da,
285
+ props: _dpr,
286
+ slots: _ds,
287
+ ...flatDefaults
288
+ } = defaultMountOptions;
289
+ const {
290
+ global: _mg,
291
+ plugins: _mp,
292
+ attrs: _ma,
293
+ props: _mpr,
294
+ slots: _ms,
295
+ ...flatOverrides
296
+ } = mountOptions;
297
+ return patchResultState(ctx, {
298
+ mountOptions: extraOptions.skipDefaultOptions ? mergeRecord(flatOverrides) : mergeRecord(flatDefaults, flatOverrides)
299
+ });
300
+ };
301
+
302
+ // src/guards/isPlainObject.ts
303
+ function isPlainObject(item) {
304
+ if (item === null || typeof item !== "object" || Array.isArray(item)) {
305
+ return false;
306
+ }
307
+ const prototype = Object.getPrototypeOf(item);
308
+ return prototype === Object.prototype || prototype === null;
309
+ }
310
+
311
+ // src/utils/mergeConfigs.ts
312
+ function mergeConfigs(target, source) {
313
+ const arrays = Array.isArray(target) && Array.isArray(source);
314
+ const objects = isPlainObject(target) && isPlainObject(source);
315
+ if (arrays) {
316
+ return [.../* @__PURE__ */ new Set([...target, ...source])];
317
+ }
318
+ if (objects) {
319
+ const output = { ...target };
320
+ for (const key of Object.keys(source)) {
321
+ const targetValue = target[key];
322
+ const sourceValue = source[key];
323
+ if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
324
+ output[key] = [.../* @__PURE__ */ new Set([...targetValue, ...sourceValue])];
325
+ } else if (isPlainObject(targetValue) && isPlainObject(sourceValue)) {
326
+ output[key] = mergeConfigs(targetValue, sourceValue);
327
+ } else {
328
+ output[key] = sourceValue;
329
+ }
330
+ }
331
+ return output;
332
+ }
333
+ throw new Error(`${ERROR_PREFIX} mergeConfigs() expects two plain objects or two arrays.`);
334
+ }
335
+
336
+ // src/pipeline/middleware/transformers/withGlobal.ts
337
+ var withGlobal = (ctx) => {
338
+ const { defaultMountOptions, mountOptions, extraOptions } = ctx;
339
+ return patchResultState(ctx, {
340
+ global: mergeConfigs(
341
+ extraOptions.skipDefaultOptions ? {} : defaultMountOptions.global || {},
342
+ mountOptions.global || {}
343
+ )
344
+ });
345
+ };
346
+
347
+ // src/pipeline/middleware/transformers/withAttrs.ts
348
+ var withAttrs = (ctx) => {
349
+ const { defaultMountOptions, mountOptions, extraOptions } = ctx;
350
+ const attrs = mergeRecord(
351
+ extraOptions.skipDefaultOptions ? {} : defaultMountOptions.attrs || {},
352
+ mountOptions.attrs || {}
353
+ );
354
+ return patchResultState(ctx, {
355
+ mountOptions: Object.keys(attrs).length > 0 ? { attrs } : {}
356
+ });
357
+ };
358
+
359
+ // src/pipeline/plugins/logic/filterSupportedPlugins.ts
360
+ function filterSupportedPlugins(plugins = {}, supported) {
361
+ return Object.fromEntries(
362
+ Object.entries(plugins).filter(([name]) => supported[name] !== void 0)
363
+ );
364
+ }
365
+
366
+ // src/pipeline/middleware/transformers/withPluginsBase.ts
367
+ var withPluginsBase = (ctx) => {
368
+ const { defaultMountOptions, mountOptions, extraOptions, supportedPlugins } = ctx;
369
+ return patchResultState(ctx, {
370
+ plugins: {
371
+ ...extraOptions.skipDefaultOptions ? {} : filterSupportedPlugins(defaultMountOptions.plugins ?? {}, supportedPlugins),
372
+ ...mountOptions.plugins || {}
373
+ }
374
+ });
375
+ };
376
+
377
+ // src/pipeline/middleware/transformers/withPluginsManifest.ts
378
+ var withPluginsManifest = (ctx) => {
379
+ const plugins = Object.fromEntries(
380
+ Object.entries(ctx.supportedPlugins).map(([name, enabled]) => [name, enabled ? {} : false])
381
+ );
382
+ return patchResultState(ctx, {
383
+ plugins
384
+ });
385
+ };
386
+
387
+ // src/pipeline/middleware/transformers/withPreset.ts
388
+ var withPreset = (ctx) => {
389
+ const { preset } = ctx;
390
+ if (!preset?.defaults) return ctx;
391
+ return patchResultState(ctx, {
392
+ pluginDefaultsState: { ...preset.defaults }
393
+ });
394
+ };
395
+
396
+ // src/pipeline/middleware/typeGuards/isPluginOverlayObject.ts
397
+ function isPluginOverlayObject(val) {
398
+ return typeof val === "object" && val !== null && !Array.isArray(val);
399
+ }
400
+
401
+ // src/pipeline/plugins/logic/getExtraPluginOptions.ts
402
+ var getExtraPluginOptions = (extraOptions, name) => {
403
+ return extraOptions.plugins?.[name];
404
+ };
405
+
406
+ // src/pipeline/plugins/logic/getPluginConfig.ts
407
+ function getPluginConfig(ctx, name) {
408
+ const base = ctx.result.plugins[name];
409
+ const extraOptions = resolveExtraOptions(ctx.extraOptions);
410
+ const overlay = getExtraPluginOptions(extraOptions, name);
411
+ const isEnabled = overlay !== void 0 ? overlay !== false : base !== false && base !== void 0;
412
+ if (!isEnabled) {
413
+ return false;
414
+ }
415
+ const current = isPluginOverlayObject(base) ? base : {};
416
+ const extra = isPluginOverlayObject(overlay) ? overlay : {};
417
+ return {
418
+ ...current,
419
+ ...extra
420
+ };
421
+ }
422
+
423
+ // src/pipeline/plugins/logic/patchPluginState.ts
424
+ function patchPluginState(ctx, name, config) {
425
+ const current = ctx.result.plugins[name];
426
+ const currentObj = isPluginOverlayObject(current) ? current : {};
427
+ return patchResultState(ctx, {
428
+ plugins: {
429
+ [name]: {
430
+ ...currentObj,
431
+ ...config
432
+ }
433
+ }
434
+ });
435
+ }
436
+
437
+ // src/pipeline/plugins/logic/resolveRuntimePluginState.ts
438
+ function resolveRuntimePluginState(config, overlay) {
439
+ const runtimeConfig = {
440
+ ...config
441
+ };
442
+ if (isPluginOverlayObject(overlay)) {
443
+ const meta = overlay.__meta;
444
+ if (meta?.instance) {
445
+ runtimeConfig.__sharedInstance = meta.instance;
446
+ }
447
+ }
448
+ delete runtimeConfig.__meta;
449
+ return runtimeConfig;
450
+ }
451
+
452
+ // src/pipeline/plugins/adapters/createPluginMiddleware.ts
453
+ function createPluginMiddleware(name) {
454
+ return (ctx) => {
455
+ const config = getPluginConfig(ctx, name);
456
+ if (!config) return ctx;
457
+ const extraOptions = resolveExtraOptions(ctx.extraOptions);
458
+ const runtimeConfig = resolveRuntimePluginState(
459
+ config,
460
+ getExtraPluginOptions(extraOptions, name)
461
+ );
462
+ return patchPluginState(ctx, name, runtimeConfig);
463
+ };
464
+ }
465
+
466
+ // src/pipeline/plugins/builders/createPluginsMiddlewares.ts
467
+ function createPluginsMiddlewares(supportedPlugins) {
468
+ return Object.keys(supportedPlugins).map(
469
+ (name) => createPluginMiddleware(name)
470
+ );
471
+ }
472
+
473
+ // src/pipeline/plugins/logic/mergePluginDefaults.ts
474
+ function mergePluginDefaults(ctx, name) {
475
+ const { result } = ctx;
476
+ const current = result.plugins[name];
477
+ if (current === false) {
478
+ return ctx;
479
+ }
480
+ result.plugins[name] = {
481
+ ...result.pluginDefaultsState[name] ?? {},
482
+ ...current ?? {}
483
+ };
484
+ return ctx;
485
+ }
486
+
487
+ // src/pipeline/plugins/adapters/createPluginMergeMiddleware.ts
488
+ function createPluginMergeMiddleware(name) {
489
+ return (ctx) => {
490
+ return mergePluginDefaults(ctx, name);
491
+ };
492
+ }
493
+
494
+ // src/pipeline/plugins/builders/createPluginsMergeMiddlewares.ts
495
+ function createPluginsMergeMiddlewares(supportedPlugins) {
496
+ return Object.keys(supportedPlugins).map(
497
+ (name) => createPluginMergeMiddleware(name)
498
+ );
499
+ }
500
+
501
+ // src/pipeline/mount/createMountPipeline.ts
502
+ function createMountPipeline(ctx) {
503
+ return [
504
+ assertConfigurationShape,
505
+ assertResultShape,
506
+ withPreset,
507
+ withPluginsManifest,
508
+ withBaseMountOptions,
509
+ withGlobal,
510
+ withAttrs,
511
+ withPluginsBase,
512
+ assertPluginOptions,
513
+ ...createPluginsMiddlewares(ctx.supportedPlugins),
514
+ ...createPluginsMergeMiddlewares(ctx.supportedPlugins),
515
+ assertFinalResultShape
516
+ ];
517
+ }
518
+
519
+ // src/core/mountWithPlugins.ts
520
+ import { mount, shallowMount } from "@vue/test-utils";
521
+
522
+ // src/pluginsRegistry/createPluginRegistry.ts
523
+ function createPluginRegistry(manifest = []) {
524
+ const map = /* @__PURE__ */ new Map();
525
+ const register = (entry) => {
526
+ const { module } = entry;
527
+ if (!module) return;
528
+ const name = module.getName();
529
+ const definition = module.getDefinition();
530
+ map.set(name, definition);
531
+ };
532
+ manifest.forEach(register);
533
+ return {
534
+ register,
535
+ get: (name) => map.get(name),
536
+ has: (name) => map.has(name),
537
+ entries: () => map.entries(),
538
+ getNames: () => Array.from(map.keys())
539
+ };
540
+ }
541
+
542
+ // src/pluginsRegistry/createPlugins.ts
543
+ function createPlugins(options = {}, ctx) {
544
+ const plugins = [];
545
+ const { preset } = ctx;
546
+ const registry = createPluginRegistry(preset?.manifest);
547
+ for (const [name, definition] of registry.entries()) {
548
+ let pluginOptions = options[name];
549
+ if (pluginOptions !== false && pluginOptions && typeof pluginOptions === "object") {
550
+ if (definition.beforeCreate) {
551
+ pluginOptions = definition.beforeCreate(ctx, pluginOptions);
552
+ }
553
+ const pluginInstance = definition.create(pluginOptions);
554
+ if (definition.afterCreate) {
555
+ definition.afterCreate(pluginInstance, ctx);
556
+ }
557
+ plugins.push(pluginInstance);
558
+ }
559
+ }
560
+ return plugins;
561
+ }
562
+
563
+ // src/core/mountWithPlugins.ts
564
+ function mountWithPlugins(component, ctx, overrides = {}, runtimeOptions = {
565
+ shallowByDefault: false
566
+ }) {
567
+ const { result } = ctx;
568
+ const mergedOptions = {
569
+ ...result.mountOptions,
570
+ ...overrides,
571
+ plugins: result.plugins
572
+ };
573
+ const {
574
+ shallow,
575
+ plugins = {},
576
+ skipManagedPlugins = false,
577
+ global: overrideGlobal,
578
+ ...restOptions
579
+ } = mergedOptions;
580
+ const shouldUseShallow = shallow ?? runtimeOptions.shallowByDefault;
581
+ const mountFunction = shouldUseShallow ? shallowMount : mount;
582
+ const globalPlugins = skipManagedPlugins ? [] : createPlugins(plugins, ctx);
583
+ const finalGlobal = {
584
+ ...result.global,
585
+ ...overrideGlobal
586
+ };
587
+ if (globalPlugins.length > 0) {
588
+ finalGlobal.plugins = [...finalGlobal.plugins || [], ...globalPlugins];
589
+ }
590
+ return mountFunction(component, {
591
+ ...restOptions,
592
+ global: finalGlobal
593
+ });
594
+ }
595
+
596
+ // src/validators/validatePresets.ts
597
+ function validatePresets(presets = {}) {
598
+ if (!isPlainObject(presets)) {
599
+ throw new Error(`${ERROR_PREFIX} Presets must be a plain object.`);
600
+ }
601
+ Object.entries(presets).forEach(([name, preset]) => {
602
+ validatePreset(name, preset);
603
+ });
604
+ }
605
+
606
+ // src/assertions/assertIsPlainObject.ts
607
+ function assertIsPlainObject(value, name = "value") {
608
+ if (!isPlainObject(value)) {
609
+ throw new Error(`${name} must be a plain object.`);
610
+ }
611
+ }
612
+
613
+ // src/validators/validateCreateTestFrameworkOptions.ts
614
+ function validateCreateTestFrameworkOptions(options = {}) {
615
+ assertIsPlainObject(options, "createTestFramework options");
616
+ const { shallowByDefault, presets } = options;
617
+ if (presets !== void 0) {
618
+ validatePresets(presets);
619
+ }
620
+ if (shallowByDefault !== void 0 && typeof shallowByDefault !== "boolean") {
621
+ throw new Error(`${ERROR_PREFIX} "shallowByDefault" must be a boolean.`);
622
+ }
623
+ }
624
+
625
+ // src/validators/validatePlainObjectArgument.ts
626
+ function validatePlainObjectArgument(value, name) {
627
+ if (!isPlainObject(value)) {
628
+ throw new Error(`${ERROR_PREFIX} "${name}" must be a plain object.`);
629
+ }
630
+ }
631
+
632
+ // src/validators/validateBooleanOption.ts
633
+ function validateBooleanOption(value, name) {
634
+ if (value !== void 0 && typeof value !== "boolean") {
635
+ throw new Error(`${ERROR_PREFIX} "${name}" must be a boolean.`);
636
+ }
637
+ }
638
+
639
+ // src/utils/getSupportedPluginNames.ts
640
+ function getSupportedPluginNames(presets = {}, extraOptions) {
641
+ const activePreset = getActivePreset(presets, extraOptions);
642
+ return getPresetManifest(activePreset).map((entry) => entry.module.getName());
643
+ }
644
+
645
+ // src/utils/warnRootPluginOption.ts
646
+ function warnRootPluginOption(pluginName, context) {
647
+ console.warn(
648
+ [
649
+ `${ERROR_PREFIX} Detected plugin option "${pluginName}" at the root of "${context}".`,
650
+ "",
651
+ "Plugin options must be placed under:",
652
+ "",
653
+ "{",
654
+ " plugins: {",
655
+ ` ${pluginName}: { ... }`,
656
+ " }",
657
+ "}",
658
+ "",
659
+ `Did you mean to use "${context}.plugins.${pluginName}"?`
660
+ ].join("\n")
661
+ );
662
+ }
663
+
664
+ // src/validators/warnRootPluginOptions.ts
665
+ function warnRootPluginOptions(options, context, presets = {}, extraOptions) {
666
+ const pluginNames = getSupportedPluginNames(presets, extraOptions);
667
+ pluginNames.forEach((pluginName) => {
668
+ const pluginAlreadyConfigured = options.plugins && pluginName in options.plugins;
669
+ if (Object.hasOwn(options, pluginName) && !pluginAlreadyConfigured) {
670
+ warnRootPluginOption(pluginName, context);
671
+ }
672
+ });
673
+ }
674
+
675
+ // src/validators/validateComponentFactoryOptions.ts
676
+ function validateComponentFactoryOptions(options, context, presets = {}, extraOptions) {
677
+ validatePlainObjectArgument(options, context);
678
+ validateBooleanOption(options.skipManagedPlugins, "skipManagedPlugins");
679
+ warnRootPluginOptions(options, context, presets, extraOptions);
680
+ }
681
+
682
+ // src/validators/validateTestComponentFactoryArguments.ts
683
+ function validateTestComponentFactoryArguments(component, defaultProps, defaultMountOptions, defaultSlots, presets) {
684
+ const isComponent = component !== null && (typeof component === "object" || typeof component === "function");
685
+ if (!isComponent) {
686
+ throw new Error(`${ERROR_PREFIX} testComponentFactory() requires a valid Vue component.`);
687
+ }
688
+ validatePlainObjectArgument(defaultProps, "defaultProps");
689
+ validateComponentFactoryOptions(
690
+ defaultMountOptions,
691
+ "defaultMountOptions",
692
+ presets
693
+ );
694
+ validatePlainObjectArgument(defaultSlots, "defaultSlots");
695
+ }
696
+
697
+ // src/validators/validateComponentFactoryExtraOptions.ts
698
+ function validateComponentFactoryExtraOptions(options, presets = {}) {
699
+ validatePlainObjectArgument(options, "extraOptions");
700
+ validateBooleanOption(options.skipDefaultProps, "skipDefaultProps");
701
+ validateBooleanOption(options.skipDefaultSlots, "skipDefaultSlots");
702
+ validateBooleanOption(options.skipDefaultOptions, "skipDefaultOptions");
703
+ warnRootPluginOptions(options, "extraOptions", presets, options);
704
+ }
705
+
706
+ // src/validators/validateComponentFactoryArguments.ts
707
+ function validateComponentFactoryArguments(props, mountOptions, slots, extraOptions, presets = {}) {
708
+ validatePlainObjectArgument(props, "props");
709
+ validateComponentFactoryOptions(
710
+ mountOptions,
711
+ "mountOptions",
712
+ presets,
713
+ extraOptions
714
+ );
715
+ validatePlainObjectArgument(slots, "slots");
716
+ validateComponentFactoryExtraOptions(extraOptions, presets);
717
+ }
718
+
719
+ // src/core/createTestFramework.ts
720
+ function createTestFramework(options = {}) {
721
+ validateCreateTestFrameworkOptions(options);
722
+ const { presets = {}, shallowByDefault = false } = options;
723
+ const testComponentFactory = (component, defaultProps = {}, defaultMountOptions = {}, defaultSlots = {}) => {
724
+ validateTestComponentFactoryArguments(
725
+ component,
726
+ defaultProps,
727
+ defaultMountOptions,
728
+ defaultSlots,
729
+ presets
730
+ );
731
+ return (props = {}, mountOptions = {}, slots = {}, extraOptions = {}) => {
732
+ validateComponentFactoryArguments(props, mountOptions, slots, extraOptions, presets);
733
+ const {
734
+ skipDefaultProps = false,
735
+ skipDefaultSlots = false,
736
+ skipDefaultOptions = false
737
+ } = extraOptions;
738
+ const finalProps = mergeComponentData({
739
+ defaultMountData: defaultMountOptions.props,
740
+ defaultData: defaultProps,
741
+ mountData: mountOptions.props,
742
+ directData: props,
743
+ skipDefault: skipDefaultProps,
744
+ skipOptions: skipDefaultOptions
745
+ });
746
+ const finalSlots = mergeComponentData({
747
+ defaultMountData: defaultMountOptions.slots,
748
+ defaultData: defaultSlots,
749
+ mountData: mountOptions.slots,
750
+ directData: slots,
751
+ skipDefault: skipDefaultSlots,
752
+ skipOptions: skipDefaultOptions
753
+ });
754
+ const ctx = createPipelineContext({
755
+ defaultMountOptions,
756
+ mountOptions,
757
+ extraOptions,
758
+ presets
759
+ });
760
+ const pipeline = createPipeline(createMountPipeline(ctx));
761
+ const readyCtx = pipeline.run(ctx);
762
+ const mountRuntimeOptions = {
763
+ shallowByDefault
764
+ };
765
+ return mountWithPlugins(
766
+ component,
767
+ readyCtx,
768
+ {
769
+ props: finalProps,
770
+ slots: finalSlots
771
+ },
772
+ mountRuntimeOptions
773
+ );
774
+ };
775
+ };
776
+ return { testComponentFactory };
777
+ }
778
+
779
+ // src/pluginsRegistry/helpers/exposeInstance.ts
780
+ function exposeInstance(instance, options) {
781
+ if (typeof options?.expose === "function") {
782
+ options.expose(instance);
783
+ }
784
+ }
785
+
786
+ // src/pluginsRegistry/factory/createPluginInstance.ts
787
+ function createPluginInstance(factory, options) {
788
+ const instance = options.__sharedInstance ?? factory(options);
789
+ exposeInstance(instance, options);
790
+ return instance;
791
+ }
792
+
793
+ // src/pluginsRegistry/factory/createVuePlugin.ts
794
+ function createVuePlugin(plugin, options) {
795
+ if (options.__sharedInstance) {
796
+ throw new Error(
797
+ `${ERROR_PREFIX} __sharedInstance is not supported for non-instance Vue plugins. Shared instances are only supported for stateful plugin factories such as Router, Pinia or vue-i18n.`
798
+ );
799
+ }
800
+ if (options.expose) {
801
+ throw new Error(
802
+ `${ERROR_PREFIX} expose() is not supported for non-instance Vue plugins because they do not produce a runtime instance. The expose callback is only available for stateful plugin factories such as Router, Pinia or vue-i18n.`
803
+ );
804
+ }
805
+ return [plugin, options];
806
+ }
807
+
808
+ // src/utils/captureInstance.ts
809
+ function captureInstance() {
810
+ let instance;
811
+ return {
812
+ expose(ins) {
813
+ instance = ins;
814
+ },
815
+ get instance() {
816
+ return instance;
817
+ }
818
+ };
819
+ }
820
+
821
+ // src/index.ts
822
+ var Types = {};
823
+ export {
824
+ Types,
825
+ captureInstance,
826
+ createPluginInstance,
827
+ createTestFramework,
828
+ createVuePlugin,
829
+ validatePreset,
830
+ validatePresets
831
+ };