@nuxt/test-utils-nightly 4.0.0-1699284628.89ffa77 → 4.0.0-1701501480.7490334

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,459 @@
1
+ import { pathToFileURL } from 'node:url';
2
+ import { resolvePath, useNuxt, resolveIgnorePatterns, addVitePlugin, defineNuxtModule, createResolver, logger } from '@nuxt/kit';
3
+ import { mergeConfig } from 'vite';
4
+ import { getPort } from 'get-port-please';
5
+ import { h } from 'vue';
6
+ import { debounce } from 'perfect-debounce';
7
+ import { isCI } from 'std-env';
8
+ import { defu } from 'defu';
9
+ import { getVitestConfigFromNuxt } from './config.mjs';
10
+ import { walk } from 'estree-walker';
11
+ import MagicString from 'magic-string';
12
+ import { normalize, resolve } from 'node:path';
13
+ import { createUnplugin } from 'unplugin';
14
+ import { readFileSync } from 'node:fs';
15
+
16
+ const PLUGIN_NAME$1 = "nuxt:vitest:mock-transform";
17
+ const HELPER_MOCK_IMPORT = "mockNuxtImport";
18
+ const HELPER_MOCK_COMPONENT = "mockComponent";
19
+ const HELPER_MOCK_HOIST = "__NUXT_VITEST_MOCKS";
20
+ const HELPERS_NAME = [HELPER_MOCK_IMPORT, HELPER_MOCK_COMPONENT];
21
+ const createMockPlugin = (ctx) => createUnplugin(() => {
22
+ let resolvedFirstSetupFile = null;
23
+ function transform(code, id) {
24
+ const isFirstSetupFile = normalize(id) === resolvedFirstSetupFile;
25
+ const shouldPrependMockHoist = resolvedFirstSetupFile ? isFirstSetupFile : true;
26
+ if (!HELPERS_NAME.some((n) => code.includes(n)))
27
+ return;
28
+ if (id.includes("/node_modules/"))
29
+ return;
30
+ let ast;
31
+ try {
32
+ ast = this.parse(code, {
33
+ // @ts-expect-error compatibility with rollup v3
34
+ sourceType: "module",
35
+ ecmaVersion: "latest",
36
+ ranges: true
37
+ });
38
+ } catch (e) {
39
+ return;
40
+ }
41
+ let insertionPoint = 0;
42
+ let hasViImport = false;
43
+ const s = new MagicString(code);
44
+ const mocksImport = [];
45
+ const mocksComponent = [];
46
+ const importPathsList = /* @__PURE__ */ new Set();
47
+ walk(ast, {
48
+ enter: (node, parent) => {
49
+ if (isImportDeclaration(node)) {
50
+ if (node.source.value === "vitest" && !hasViImport) {
51
+ const viImport = node.specifiers.find(
52
+ (i) => isImportSpecifier(i) && i.imported.name === "vi"
53
+ );
54
+ if (viImport) {
55
+ insertionPoint = endOf(node);
56
+ hasViImport = true;
57
+ }
58
+ return;
59
+ }
60
+ }
61
+ if (!isCallExpression(node))
62
+ return;
63
+ if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_IMPORT) {
64
+ if (node.arguments.length !== 2) {
65
+ return this.error(
66
+ new Error(
67
+ `${HELPER_MOCK_IMPORT}() should have exactly 2 arguments`
68
+ ),
69
+ startOf(node)
70
+ );
71
+ }
72
+ const importName = node.arguments[0];
73
+ if (!isLiteral(importName) || typeof importName.value !== "string") {
74
+ return this.error(
75
+ new Error(
76
+ `The first argument of ${HELPER_MOCK_IMPORT}() must be a string literal`
77
+ ),
78
+ startOf(importName)
79
+ );
80
+ }
81
+ const name = importName.value;
82
+ const importItem = ctx.imports.find((_) => name === (_.as || _.name));
83
+ if (!importItem) {
84
+ console.log({ imports: ctx.imports });
85
+ return this.error(`Cannot find import "${name}" to mock`);
86
+ }
87
+ s.overwrite(
88
+ isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[0]),
89
+ isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
90
+ ""
91
+ );
92
+ mocksImport.push({
93
+ name,
94
+ import: importItem,
95
+ factory: code.slice(
96
+ startOf(node.arguments[1]),
97
+ endOf(node.arguments[1])
98
+ )
99
+ });
100
+ }
101
+ if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_COMPONENT) {
102
+ if (node.arguments.length !== 2) {
103
+ return this.error(
104
+ new Error(
105
+ `${HELPER_MOCK_COMPONENT}() should have exactly 2 arguments`
106
+ ),
107
+ startOf(node)
108
+ );
109
+ }
110
+ const componentName = node.arguments[0];
111
+ if (!isLiteral(componentName) || typeof componentName.value !== "string") {
112
+ return this.error(
113
+ new Error(
114
+ `The first argument of ${HELPER_MOCK_COMPONENT}() must be a string literal`
115
+ ),
116
+ startOf(componentName)
117
+ );
118
+ }
119
+ const pathOrName = componentName.value;
120
+ const component = ctx.components.find(
121
+ (_) => _.pascalName === pathOrName || _.kebabName === pathOrName
122
+ );
123
+ const path = component?.filePath || pathOrName;
124
+ s.overwrite(
125
+ isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[1]),
126
+ isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
127
+ ""
128
+ );
129
+ mocksComponent.push({
130
+ path,
131
+ factory: code.slice(
132
+ startOf(node.arguments[1]),
133
+ endOf(node.arguments[1])
134
+ )
135
+ });
136
+ }
137
+ }
138
+ });
139
+ if (mocksImport.length === 0 && mocksComponent.length === 0)
140
+ return;
141
+ const mockLines = [];
142
+ if (mocksImport.length) {
143
+ const mockImportMap = /* @__PURE__ */ new Map();
144
+ for (const mock of mocksImport) {
145
+ if (!mockImportMap.has(mock.import.from)) {
146
+ mockImportMap.set(mock.import.from, []);
147
+ }
148
+ mockImportMap.get(mock.import.from).push(mock);
149
+ }
150
+ mockLines.push(
151
+ ...Array.from(mockImportMap.entries()).flatMap(
152
+ ([from, mocks]) => {
153
+ importPathsList.add(from);
154
+ const lines = [
155
+ `vi.mock(${JSON.stringify(from)}, async (importOriginal) => {`,
156
+ ` const mocks = globalThis.${HELPER_MOCK_HOIST}`,
157
+ ` if (!mocks[${JSON.stringify(from)}]) {`,
158
+ ` mocks[${JSON.stringify(from)}] = { ...await importOriginal(${JSON.stringify(from)}) }`,
159
+ ` }`
160
+ ];
161
+ for (const mock of mocks) {
162
+ if (mock.import.name === "default") {
163
+ lines.push(
164
+ ` mocks[${JSON.stringify(from)}]["default"] = await (${mock.factory})();`
165
+ );
166
+ } else {
167
+ lines.push(
168
+ ` mocks[${JSON.stringify(from)}][${JSON.stringify(mock.name)}] = await (${mock.factory})();`
169
+ );
170
+ }
171
+ }
172
+ lines.push(` return mocks[${JSON.stringify(from)}] `);
173
+ lines.push(`});`);
174
+ return lines;
175
+ }
176
+ )
177
+ );
178
+ }
179
+ if (mocksComponent.length) {
180
+ mockLines.push(
181
+ ...mocksComponent.flatMap((mock) => {
182
+ return [
183
+ `vi.mock(${JSON.stringify(mock.path)}, async () => {`,
184
+ ` const factory = (${mock.factory});`,
185
+ ` const result = typeof factory === 'function' ? await factory() : await factory`,
186
+ ` return 'default' in result ? result : { default: result }`,
187
+ "});"
188
+ ];
189
+ })
190
+ );
191
+ }
192
+ if (!mockLines.length)
193
+ return;
194
+ s.prepend(`vi.hoisted(() => {
195
+ if(!globalThis.${HELPER_MOCK_HOIST}){
196
+ vi.stubGlobal(${JSON.stringify(HELPER_MOCK_HOIST)}, {})
197
+ }
198
+ });
199
+ `);
200
+ if (!hasViImport)
201
+ s.prepend(`import {vi} from "vitest";
202
+ `);
203
+ s.appendLeft(insertionPoint, mockLines.join("\n") + "\n");
204
+ if (shouldPrependMockHoist) {
205
+ importPathsList.forEach((p) => {
206
+ s.append(`
207
+ import ${JSON.stringify(p)};`);
208
+ });
209
+ }
210
+ return {
211
+ code: s.toString(),
212
+ map: s.generateMap()
213
+ };
214
+ }
215
+ return {
216
+ name: PLUGIN_NAME$1,
217
+ enforce: "post",
218
+ vite: {
219
+ transform,
220
+ // Place Vitest's mock plugin after all Nuxt plugins
221
+ async configResolved(config) {
222
+ const firstSetupFile = Array.isArray(config.test?.setupFiles) ? config.test.setupFiles.find((p) => !p.includes("runtime/entry")) : config.test?.setupFiles;
223
+ if (firstSetupFile) {
224
+ resolvedFirstSetupFile = await resolvePath(normalize(resolve(firstSetupFile)));
225
+ }
226
+ const plugins = config.plugins || [];
227
+ const vitestPlugins = plugins.filter((p) => p.name === "vite:mocks" || p.name.startsWith("vitest:"));
228
+ const lastNuxt = findLastIndex(
229
+ plugins,
230
+ (i) => i.name?.startsWith("nuxt:")
231
+ );
232
+ if (lastNuxt === -1)
233
+ return;
234
+ for (const plugin of vitestPlugins) {
235
+ const index = plugins.indexOf(plugin);
236
+ if (index < lastNuxt) {
237
+ plugins.splice(index, 1);
238
+ plugins.splice(lastNuxt, 0, plugin);
239
+ }
240
+ }
241
+ }
242
+ }
243
+ };
244
+ });
245
+ function findLastIndex(arr, predicate) {
246
+ for (let i = arr.length - 1; i >= 0; i--) {
247
+ if (predicate(arr[i]))
248
+ return i;
249
+ }
250
+ return -1;
251
+ }
252
+ function isImportDeclaration(node) {
253
+ return node.type === "ImportDeclaration";
254
+ }
255
+ function isImportSpecifier(node) {
256
+ return node.type === "ImportSpecifier";
257
+ }
258
+ function isCallExpression(node) {
259
+ return node.type === "CallExpression";
260
+ }
261
+ function isIdentifier(node) {
262
+ return node.type === "Identifier";
263
+ }
264
+ function isLiteral(node) {
265
+ return node.type === "Literal";
266
+ }
267
+ function isExpressionStatement(node) {
268
+ return node?.type === "ExpressionStatement";
269
+ }
270
+ function startOf(node) {
271
+ return "range" in node && node.range ? node.range[0] : node.start;
272
+ }
273
+ function endOf(node) {
274
+ return "range" in node && node.range ? node.range[1] : node.end;
275
+ }
276
+
277
+ function setupImportMocking() {
278
+ const nuxt = useNuxt();
279
+ const ctx = {
280
+ components: [],
281
+ imports: []
282
+ };
283
+ let importsCtx;
284
+ nuxt.hook("imports:context", async (ctx2) => {
285
+ importsCtx = ctx2;
286
+ });
287
+ nuxt.hook("ready", async () => {
288
+ ctx.imports = await importsCtx.getImports();
289
+ });
290
+ nuxt.hook("components:extend", (_) => {
291
+ ctx.components = _;
292
+ });
293
+ nuxt.options.ignore = nuxt.options.ignore.filter((i) => i !== "**/*.{spec,test}.{js,cts,mts,ts,jsx,tsx}");
294
+ if (nuxt._ignore) {
295
+ for (const pattern of resolveIgnorePatterns("**/*.{spec,test}.{js,cts,mts,ts,jsx,tsx}")) {
296
+ nuxt._ignore.add(`!${pattern}`);
297
+ }
298
+ }
299
+ addVitePlugin(createMockPlugin(ctx).vite());
300
+ }
301
+
302
+ const PLUGIN_NAME = "nuxt:vitest:nuxt-root-stub";
303
+ const NuxtRootStubPlugin = createUnplugin((options) => {
304
+ return {
305
+ name: PLUGIN_NAME,
306
+ enforce: "pre",
307
+ vite: {
308
+ async resolveId(id) {
309
+ if (id.endsWith("nuxt-vitest-app-entry")) {
310
+ return id;
311
+ }
312
+ },
313
+ async load(id) {
314
+ if (id.endsWith("nuxt-vitest-app-entry")) {
315
+ const entryContents = readFileSync(options.entry, "utf-8");
316
+ return entryContents.replace("#build/root-component.mjs", options.rootStubPath);
317
+ }
318
+ }
319
+ }
320
+ };
321
+ });
322
+
323
+ const vitePluginBlocklist = ["vite-plugin-vue-inspector", "vite-plugin-inspect"];
324
+ const module = defineNuxtModule({
325
+ meta: {
326
+ name: "@nuxt/test-utils",
327
+ configKey: "vitest"
328
+ },
329
+ defaults: {
330
+ startOnBoot: false,
331
+ logToConsole: false
332
+ },
333
+ async setup(options, nuxt) {
334
+ if (nuxt.options.test || nuxt.options.dev) {
335
+ setupImportMocking();
336
+ }
337
+ const resolver = createResolver(import.meta.url);
338
+ addVitePlugin(NuxtRootStubPlugin.vite({
339
+ entry: await resolvePath("#app/entry", { alias: nuxt.options.alias }),
340
+ rootStubPath: await resolvePath(resolver.resolve("./runtime/nuxt-root"))
341
+ }));
342
+ if (!nuxt.options.dev)
343
+ return;
344
+ if (nuxt.options.test && nuxt.options.app.rootId === "__nuxt") {
345
+ nuxt.options.app.rootId = "nuxt-test";
346
+ }
347
+ if (process.env.TEST || process.env.VITE_TEST)
348
+ return;
349
+ const rawViteConfigPromise = new Promise((resolve) => {
350
+ nuxt.hook("app:resolve", () => {
351
+ nuxt.hook("vite:configResolved", (config, { isClient }) => {
352
+ if (isClient)
353
+ resolve(config);
354
+ });
355
+ });
356
+ });
357
+ const PORT = await getPort({ port: 15555 });
358
+ const URL = `http://localhost:${PORT}/__vitest__/`;
359
+ let loaded = false;
360
+ let promise;
361
+ let ctx = void 0;
362
+ let testFiles = null;
363
+ const updateTabs = debounce(() => {
364
+ nuxt.callHook("devtools:customTabs:refresh");
365
+ }, 100);
366
+ async function start() {
367
+ const rawViteConfig = mergeConfig({}, await rawViteConfigPromise);
368
+ const viteConfig = await getVitestConfigFromNuxt({ nuxt, viteConfig: defu({ test: options.vitestConfig }, rawViteConfig) });
369
+ viteConfig.plugins = (viteConfig.plugins || []).filter((p) => {
370
+ return !vitePluginBlocklist.includes(p?.name);
371
+ });
372
+ process.env.__NUXT_VITEST_RESOLVED__ = "true";
373
+ const { startVitest } = await import(pathToFileURL(await resolvePath("vitest/node")).href);
374
+ const customReporter = {
375
+ onInit(_ctx) {
376
+ ctx = _ctx;
377
+ },
378
+ onTaskUpdate() {
379
+ testFiles = ctx.state.getFiles();
380
+ updateTabs();
381
+ },
382
+ onFinished() {
383
+ testFiles = ctx.state.getFiles();
384
+ updateTabs();
385
+ }
386
+ };
387
+ const watchMode = !process.env.NUXT_VITEST_DEV_TEST && !isCI;
388
+ const overrides = watchMode ? {
389
+ passWithNoTests: true,
390
+ reporters: options.logToConsole ? [
391
+ ...toArray(options.vitestConfig?.reporters ?? ["default"]),
392
+ customReporter
393
+ ] : [customReporter],
394
+ // do not report to console
395
+ watch: true,
396
+ ui: true,
397
+ open: false,
398
+ api: {
399
+ port: PORT
400
+ }
401
+ } : { watch: false };
402
+ const promise2 = startVitest("test", [], defu(overrides, viteConfig.test), viteConfig);
403
+ promise2.catch(() => process.exit(1));
404
+ if (watchMode) {
405
+ logger.info(`Vitest UI starting on ${URL}`);
406
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
407
+ } else {
408
+ promise2.then((v) => v?.close()).then(() => process.exit());
409
+ promise2.catch(() => process.exit(1));
410
+ }
411
+ loaded = true;
412
+ }
413
+ nuxt.hook("devtools:customTabs", (tabs) => {
414
+ const failedCount = testFiles?.filter((f) => f.result?.state === "fail").length ?? 0;
415
+ const passedCount = testFiles?.filter((f) => f.result?.state === "pass").length ?? 0;
416
+ const totalCount = testFiles?.length ?? 0;
417
+ tabs.push({
418
+ title: "Vitest",
419
+ name: "vitest",
420
+ icon: "logos-vitest",
421
+ view: loaded ? {
422
+ type: "iframe",
423
+ src: URL
424
+ } : {
425
+ type: "launch",
426
+ description: "Start tests along with Nuxt",
427
+ actions: [
428
+ {
429
+ label: promise ? "Starting..." : "Start Vitest",
430
+ pending: !!promise,
431
+ handle: () => {
432
+ promise = promise || start();
433
+ return promise;
434
+ }
435
+ }
436
+ ]
437
+ },
438
+ extraTabVNode: totalCount ? h("div", { style: { color: failedCount ? "orange" : "green" } }, [
439
+ h("span", {}, passedCount),
440
+ h("span", { style: { opacity: "0.5", fontSize: "0.9em" } }, "/"),
441
+ h(
442
+ "span",
443
+ { style: { opacity: "0.8", fontSize: "0.9em" } },
444
+ totalCount
445
+ )
446
+ ]) : void 0
447
+ });
448
+ });
449
+ if (options.startOnBoot) {
450
+ promise = promise || start();
451
+ promise.then(updateTabs);
452
+ }
453
+ }
454
+ });
455
+ function toArray(value) {
456
+ return Array.isArray(value) ? value : [value];
457
+ }
458
+
459
+ export { module as default };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ if (typeof window !== "undefined" && // @ts-expect-error undefined property
2
+ window.__NUXT_VITEST_ENVIRONMENT__) {
3
+ await import("#app/nuxt-vitest-app-entry").then((r) => r.default());
4
+ const nuxtApp = useNuxtApp();
5
+ await nuxtApp.callHook("page:finish");
6
+ useRouter().afterEach(() => nuxtApp.callHook("page:finish"));
7
+ }
8
+ export {};
@@ -0,0 +1,4 @@
1
+ declare const _default: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
2
+ [key: string]: any;
3
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
4
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import { Suspense, defineComponent, h, onErrorCaptured, provide } from "vue";
2
+ import { isNuxtError, useNuxtApp, useRoute } from "#imports";
3
+ import { PageRouteSymbol } from "#app/components/injections";
4
+ export default defineComponent({
5
+ setup(_options, { slots }) {
6
+ const nuxtApp = useNuxtApp();
7
+ provide(PageRouteSymbol, useRoute());
8
+ const done = nuxtApp.deferHydration();
9
+ const results = nuxtApp.hooks.callHookWith((hooks) => hooks.map((hook) => hook()), "vue:setup");
10
+ if (import.meta.dev && results && results.some((i) => i && "then" in i)) {
11
+ console.error("[nuxt] Error in `vue:setup`. Callbacks must be synchronous.");
12
+ }
13
+ onErrorCaptured((err, target, info) => {
14
+ nuxtApp.hooks.callHook("vue:error", err, target, info).catch((hookError) => console.error("[nuxt] Error in `vue:error` hook", hookError));
15
+ if (isNuxtError(err) && (err.fatal || err.unhandled)) {
16
+ return false;
17
+ }
18
+ });
19
+ return () => h(Suspense, { onResolve: done }, slots.default?.());
20
+ }
21
+ });
@@ -0,0 +1,150 @@
1
+ import { EventHandler, HTTPMethod } from 'h3';
2
+ import { SetupContext, RenderFunction, ComputedOptions, MethodOptions, ComponentOptionsMixin, EmitsOptions, ComponentInjectOptions, ComponentOptionsWithoutProps, ComponentOptionsWithArrayProps, ComponentPropsOptions, ComponentOptionsWithObjectProps } from 'vue';
3
+ import { mount, ComponentMountingOptions } from '@vue/test-utils';
4
+ import { RouteLocationRaw } from 'vue-router';
5
+ import * as _testing_library_vue from '@testing-library/vue';
6
+ import { RenderOptions as RenderOptions$1 } from '@testing-library/vue';
7
+
8
+ type Awaitable<T> = T | Promise<T>;
9
+ type OptionalFunction<T> = T | (() => Awaitable<T>);
10
+ /**
11
+ * `registerEndpoint` allows you create Nitro endpoint that returns mocked data. It can come in handy if you want to test a component that makes requests to API to display some data.
12
+ * @param url - endpoint name (e.g. `/test/`).
13
+ * @param options - factory function that returns the mocked data or an object containing both the `handler` and the `method` properties.
14
+ * @example
15
+ * ```ts
16
+ * import { registerEndpoint } from '@nuxt/test-utils/runtime-utils'
17
+ *
18
+ * registerEndpoint("/test/", () => {
19
+ * test: "test-field"
20
+ * })
21
+ * ```
22
+ * @see https://github.com/danielroe/nuxt-vitest#registerendpoint
23
+ */
24
+ declare function registerEndpoint(url: string, options: EventHandler | {
25
+ handler: EventHandler;
26
+ method: HTTPMethod;
27
+ }): void;
28
+ /**
29
+ * `mockNuxtImport` allows you to mock Nuxt's auto import functionality.
30
+ * @param _name - name of an import to mock.
31
+ * @param _factory - factory function that returns mocked import.
32
+ * @example
33
+ * ```ts
34
+ * import { mockNuxtImport } from '@nuxt/test-utils/runtime-utils'
35
+ *
36
+ * mockNuxtImport('useStorage', () => {
37
+ * return () => {
38
+ * return { value: 'mocked storage' }
39
+ * }
40
+ * })
41
+ * ```
42
+ * @see https://github.com/danielroe/nuxt-vitest#mocknuxtimport
43
+ */
44
+ declare function mockNuxtImport<T = any>(_name: string, _factory: () => T | Promise<T>): void;
45
+ /**
46
+ * `mockComponent` allows you to mock Nuxt's component.
47
+ * @param path - component name in PascalCase, or the relative path of the component.
48
+ * @param setup - factory function that returns the mocked component.
49
+ * @example
50
+ * ```ts
51
+ * import { mockComponent } from '@nuxt/test-utils/runtime-utils'
52
+ *
53
+ * mockComponent('MyComponent', {
54
+ * props: {
55
+ * value: String
56
+ * },
57
+ * setup(props) {
58
+ * // ...
59
+ * }
60
+ * })
61
+ *
62
+ * // relative path or alias also works
63
+ * mockComponent('~/components/my-component.vue', async () => {
64
+ * // or a factory function
65
+ * return {
66
+ * setup(props) {
67
+ * // ...
68
+ * }
69
+ * }
70
+ * })
71
+ *
72
+ * // or you can use SFC for redirecting to a mock component
73
+ * mockComponent('MyComponent', () => import('./MockComponent.vue'))
74
+ * ```
75
+ * @see https://github.com/danielroe/nuxt-vitest#mockcomponent
76
+ */
77
+ declare function mockComponent<Props, RawBindings = object>(path: string, setup: OptionalFunction<(props: Readonly<Props>, ctx: SetupContext) => RawBindings | RenderFunction>): void;
78
+ declare function mockComponent<Props = {}, RawBindings = {}, D = {}, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = {}, EE extends string = string, I extends ComponentInjectOptions = {}, II extends string = string>(path: string, options: OptionalFunction<ComponentOptionsWithoutProps<Props, RawBindings, D, C, M, Mixin, Extends, E, EE, I, II>>): void;
79
+ declare function mockComponent<PropNames extends string, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = {}, EE extends string = string, I extends ComponentInjectOptions = {}, II extends string = string>(path: string, options: OptionalFunction<ComponentOptionsWithArrayProps<PropNames, RawBindings, D, C, M, Mixin, Extends, E, EE, I, II>>): void;
80
+ declare function mockComponent<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = {}, EE extends string = string, I extends ComponentInjectOptions = {}, II extends string = string>(path: string, options: OptionalFunction<ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE, I, II>>): void;
81
+
82
+ type MountSuspendedOptions<T> = ComponentMountingOptions<T> & {
83
+ route?: RouteLocationRaw;
84
+ };
85
+ /**
86
+ * `mountSuspended` allows you to mount any vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins. For example:
87
+ *
88
+ * ```ts
89
+ * // tests/components/SomeComponents.nuxt.spec.ts
90
+ * it('can mount some component', async () => {
91
+ * const component = await mountSuspended(SomeComponent)
92
+ * expect(component.text()).toMatchInlineSnapshot(
93
+ * 'This is an auto-imported component'
94
+ * )
95
+ * })
96
+ *
97
+ * // tests/App.nuxt.spec.ts
98
+ * it('can also mount an app', async () => {
99
+ * const component = await mountSuspended(App, { route: '/test' })
100
+ * expect(component.html()).toMatchInlineSnapshot(`
101
+ * "<div>This is an auto-imported component</div>
102
+ * <div> I am a global component </div>
103
+ * <div>/</div>
104
+ * <a href=\\"/test\\"> Test link </a>"
105
+ * `)
106
+ * })
107
+ * ```
108
+ * @param component the component to be tested
109
+ * @param options optional options to set up your component
110
+ */
111
+ declare function mountSuspended<T>(component: T, options?: MountSuspendedOptions<T>): Promise<ReturnType<typeof mount<T>> & {
112
+ setupState: any;
113
+ }>;
114
+
115
+ type RenderOptions = RenderOptions$1 & {
116
+ route?: RouteLocationRaw;
117
+ };
118
+ /**
119
+ * `renderSuspended` allows you to mount any vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins.
120
+ *
121
+ * This is a wrapper around the `render` function from @testing-libary/vue, and should be used together with
122
+ * utilities from that package.
123
+ *
124
+ * ```ts
125
+ * // tests/components/SomeComponents.nuxt.spec.ts
126
+ * import { renderSuspended } from '@nuxt/test-utils/runtime-utils'
127
+ *
128
+ * it('can render some component', async () => {
129
+ * const { html } = await renderSuspended(SomeComponent)
130
+ * expect(html()).toMatchInlineSnapshot(
131
+ * 'This is an auto-imported component'
132
+ * )
133
+ *
134
+ * })
135
+ *
136
+ * // tests/App.nuxt.spec.ts
137
+ * import { renderSuspended } from '@nuxt/test-utils/runtime-utils'
138
+ * import { screen } from '@testing-library/vue'
139
+ *
140
+ * it('can also mount an app', async () => {
141
+ * const { html } = await renderSuspended(App, { route: '/test' })
142
+ * expect(screen.getByRole('link', { name: 'Test Link' })).toBeVisible()
143
+ * })
144
+ * ```
145
+ * @param component the component to be tested
146
+ * @param options optional options to set up your component
147
+ */
148
+ declare function renderSuspended<T>(component: T, options?: RenderOptions): Promise<_testing_library_vue.RenderResult>;
149
+
150
+ export { mockComponent, mockNuxtImport, mountSuspended, registerEndpoint, renderSuspended };