@nuxt/test-utils 3.19.0 → 3.19.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/dist/config.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import * as vitest_config_js from 'vitest/config.js';
1
+ import * as vite from 'vite';
2
+ import { UserConfig } from 'vite';
2
3
  import { NuxtConfig, Nuxt } from '@nuxt/schema';
3
4
  import { InlineConfig } from 'vitest/node';
4
5
  import { TestProjectInlineConfiguration } from 'vitest/config';
5
6
  import { DotenvOptions } from 'c12';
6
- import { UserConfig } from 'vite';
7
7
 
8
8
  interface GetVitestConfigOptions {
9
9
  nuxt: Nuxt;
@@ -19,7 +19,7 @@ declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, loadN
19
19
  declare function defineVitestProject(config: TestProjectInlineConfiguration): Promise<TestProjectInlineConfiguration>;
20
20
  declare function defineVitestConfig(config?: UserConfig & {
21
21
  test?: InlineConfig;
22
- }): vitest_config_js.UserConfigExport;
22
+ }): vite.UserConfigFnPromise;
23
23
  interface NuxtEnvironmentOptions {
24
24
  rootDir?: string;
25
25
  /**
package/dist/config.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import process$1 from 'node:process';
2
- import { defineConfig } from 'vitest/config';
2
+ import { defineConfig } from 'vite';
3
3
  import { setupDotenv } from 'c12';
4
4
  import { defu } from 'defu';
5
5
  import { createResolver, findPath, loadNuxt, buildNuxt } from '@nuxt/kit';
@@ -82,7 +82,11 @@ async function startNuxtAndGetViteConfig(rootDir = process$1.cwd(), options = {}
82
82
  const excludedPlugins = [
83
83
  "nuxt:import-protection",
84
84
  "nuxt:import-conditions",
85
- "vite-plugin-checker"
85
+ "nuxt:devtools:rpc",
86
+ "nuxt:devtools:config-retriever",
87
+ "vite-plugin-checker",
88
+ "vite-plugin-inspect",
89
+ "vite-plugin-vue-tracer"
86
90
  ];
87
91
  async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
88
92
  const { rootDir = process$1.cwd(), ..._overrides } = loadNuxtOptions.overrides || {};
@@ -96,12 +100,19 @@ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
96
100
  });
97
101
  }
98
102
  options.viteConfig.plugins = (options.viteConfig.plugins || []).filter((p) => !p || !("name" in p) || !excludedPlugins.includes(p.name));
103
+ const resolver = createResolver(import.meta.url);
99
104
  const resolvedConfig = defu(
100
105
  // overrides
101
106
  {
102
107
  define: {
103
108
  "process.env.NODE_ENV": '"test"'
104
109
  },
110
+ resolve: {
111
+ alias: {
112
+ "@vue/devtools-kit": resolver.resolve("./runtime/mocks/vue-devtools"),
113
+ "@vue/devtools-core": resolver.resolve("./runtime/mocks/vue-devtools")
114
+ }
115
+ },
105
116
  optimizeDeps: {
106
117
  noDiscovery: true
107
118
  },
@@ -198,7 +209,6 @@ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
198
209
  if (!Array.isArray(resolvedConfig.test.setupFiles)) {
199
210
  resolvedConfig.test.setupFiles = [resolvedConfig.test.setupFiles].filter(Boolean);
200
211
  }
201
- const resolver = createResolver(import.meta.url);
202
212
  const entryPath = resolver.resolve("./runtime/entry");
203
213
  resolvedConfig.test.setupFiles.unshift(await findPath(entryPath) ?? entryPath);
204
214
  return resolvedConfig;
@@ -216,15 +226,19 @@ function defineVitestConfig(config = {}) {
216
226
  if (resolvedConfig.test.browser?.enabled) {
217
227
  return resolvedConfig;
218
228
  }
219
- if ("workspace" in resolvedConfig.test) {
229
+ if ("workspace" in resolvedConfig.test || "projects" in resolvedConfig.test) {
220
230
  throw new Error(
221
- "The `workspace` option is not supported with `defineVitestConfig`. Instead, use `defineVitestProject` to define each workspace project that uses the Nuxt environment."
231
+ "The `projects` option is not supported with `defineVitestConfig`. Instead, use `defineVitestProject` to define each workspace project that uses the Nuxt environment."
222
232
  );
223
233
  }
224
234
  const defaultEnvironment = resolvedConfig.test.environment || "node";
225
235
  if (defaultEnvironment !== "nuxt") {
226
- resolvedConfig.test.workspace = [];
227
- resolvedConfig.test.workspace.push({
236
+ const key = "projects" in resolvedConfig.test ? "projects" : "workspace" in resolvedConfig.test ? "workspace" : await import('vitest/package.json', { with: { type: 'json' } }).then((r) => {
237
+ const [major, minor] = (r.default || r).version.split(".");
238
+ return Number.parseInt(major, 10) > 3 || Number.parseInt(major, 10) === 3 && Number.parseInt(minor, 10) >= 2;
239
+ }) ? "projects" : "workspace";
240
+ resolvedConfig.test[key] = [];
241
+ resolvedConfig.test[key].push({
228
242
  extends: true,
229
243
  test: {
230
244
  name: "nuxt",
@@ -235,6 +249,22 @@ function defineVitestConfig(config = {}) {
235
249
  ]
236
250
  }
237
251
  });
252
+ resolvedConfig.test[key].push({
253
+ extends: true,
254
+ test: {
255
+ name: defaultEnvironment,
256
+ environment: defaultEnvironment,
257
+ exclude: [
258
+ "**/node_modules/**",
259
+ "**/dist/**",
260
+ "**/cypress/**",
261
+ "**/.{idea,git,cache,output,temp}/**",
262
+ "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*",
263
+ "./**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
264
+ "./{test,tests}/nuxt/**.*"
265
+ ]
266
+ }
267
+ });
238
268
  }
239
269
  return resolvedConfig;
240
270
  });
package/dist/module.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { pathToFileURL } from 'node:url';
2
- import { useNuxt, resolveIgnorePatterns, addVitePlugin, defineNuxtModule, createResolver, resolvePath, logger } from '@nuxt/kit';
3
- import { mergeConfig } from 'vite';
2
+ import { useNuxt, resolveIgnorePatterns, addVitePlugin, defineNuxtModule, createResolver, resolvePath, importModule, logger } from '@nuxt/kit';
4
3
  import { getPort } from 'get-port-please';
5
4
  import { h } from 'vue';
6
5
  import { debounce } from 'perfect-debounce';
@@ -13,7 +12,7 @@ import { createUnplugin } from 'unplugin';
13
12
  import { readFileSync } from 'node:fs';
14
13
  import { extname, join, dirname } from 'pathe';
15
14
  import 'node:process';
16
- import 'vitest/config';
15
+ import 'vite';
17
16
  import 'c12';
18
17
  import 'destr';
19
18
  import 'scule';
@@ -218,7 +217,7 @@ vi.hoisted(() => {
218
217
  const vitestPlugins = plugins.filter((p) => (p.name === "vite:mocks" || p.name.startsWith("vitest:")) && (p.enforce || "order" in p && p.order) === "post");
219
218
  const lastNuxt = findLastIndex(
220
219
  plugins,
221
- (i) => i.name?.startsWith("nuxt:")
220
+ (i) => !!i?.name?.startsWith("nuxt:")
222
221
  );
223
222
  if (lastNuxt === -1) return;
224
223
  for (const plugin of vitestPlugins) {
@@ -361,6 +360,7 @@ const module = defineNuxtModule({
361
360
  }, 100);
362
361
  let URL;
363
362
  async function start() {
363
+ const { mergeConfig } = await importModule("vite", { paths: nuxt.options.modulesDir });
364
364
  const rawViteConfig = mergeConfig({}, await rawViteConfigPromise);
365
365
  const viteConfig = await getVitestConfigFromNuxt({ nuxt, viteConfig: defu({ test: options.vitestConfig }, rawViteConfig) });
366
366
  viteConfig.plugins = (viteConfig.plugins || []).filter((p) => {
@@ -0,0 +1,11 @@
1
+ export declare const functions: never[];
2
+ export declare function createRpcServer(): void;
3
+ export declare const devtools: {
4
+ init(): void;
5
+ };
6
+ export declare function addCustomCommand(): void;
7
+ export declare function addCustomTab(): void;
8
+ export declare function onDevToolsClientConnected(): void;
9
+ export declare function onDevToolsConnected(): void;
10
+ export declare function removeCustomCommand(): void;
11
+ export declare function setupDevToolsPlugin(): void;
@@ -0,0 +1,19 @@
1
+ export const functions = [];
2
+ export function createRpcServer() {
3
+ }
4
+ export const devtools = {
5
+ init() {
6
+ }
7
+ };
8
+ export function addCustomCommand() {
9
+ }
10
+ export function addCustomTab() {
11
+ }
12
+ export function onDevToolsClientConnected() {
13
+ }
14
+ export function onDevToolsConnected() {
15
+ }
16
+ export function removeCustomCommand() {
17
+ }
18
+ export function setupDevToolsPlugin() {
19
+ }
@@ -19,17 +19,17 @@ function registerEndpoint(url, options) {
19
19
  if (!hasBeenRegistered) {
20
20
  window.__registry.add(url);
21
21
  app.use("/_" + url, defineEventHandler((event) => {
22
- const latestHandler = [...endpointRegistry[url]].reverse().find((config2) => config2.method ? event.method === config2.method : true);
22
+ const latestHandler = [...endpointRegistry[url] || []].reverse().find((config2) => config2.method ? event.method === config2.method : true);
23
23
  return latestHandler?.handler(event);
24
24
  }), {
25
25
  match(_, event) {
26
- return endpointRegistry[url]?.some((config2) => config2.method ? event?.method === config2.method : true);
26
+ return endpointRegistry[url]?.some((config2) => config2.method ? event?.method === config2.method : true) ?? false;
27
27
  }
28
28
  });
29
29
  }
30
30
  return () => {
31
- endpointRegistry[url].splice(endpointRegistry[url].indexOf(config), 1);
32
- if (endpointRegistry[url].length === 0) {
31
+ endpointRegistry[url]?.splice(endpointRegistry[url].indexOf(config), 1);
32
+ if (endpointRegistry[url]?.length === 0) {
33
33
  window.__registry.delete(url);
34
34
  }
35
35
  };
@@ -130,17 +130,19 @@ async function mountSuspended(component, options) {
130
130
  async setup() {
131
131
  const router = useRouter();
132
132
  await router.replace(route);
133
+ let interceptedEmit = null;
133
134
  const clonedComponent = {
134
135
  name: "MountSuspendedComponent",
135
136
  ...component,
136
137
  render: render ? function(_ctx, ...args) {
137
138
  const currentInstance = getCurrentInstance();
138
- if (currentInstance) {
139
+ if (currentInstance && currentInstance.emit !== interceptedEmit) {
139
140
  const oldEmit = currentInstance.emit;
140
- currentInstance.emit = (event, ...args2) => {
141
+ interceptedEmit = (event, ...args2) => {
141
142
  oldEmit(event, ...args2);
142
143
  setupContext.emit(event, ...args2);
143
144
  };
145
+ currentInstance.emit = interceptedEmit;
144
146
  }
145
147
  if (data && typeof data === "function") {
146
148
  const dataObject = data();
@@ -170,13 +172,17 @@ async function mountSuspended(component, options) {
170
172
  propsContext[key] = passedProps[key];
171
173
  }
172
174
  if (methods && typeof methods === "object") {
173
- for (const key in methods) {
174
- renderContext[key] = methods[key].bind(renderContext);
175
+ for (const [key, value] of Object.entries(methods)) {
176
+ renderContext[key] = value.bind(renderContext);
175
177
  }
176
178
  }
177
179
  if (computed && typeof computed === "object") {
178
- for (const key in computed) {
179
- renderContext[key] = computed[key].call(renderContext);
180
+ for (const [key, value] of Object.entries(computed)) {
181
+ if ("get" in value) {
182
+ renderContext[key] = value.get.call(renderContext);
183
+ } else {
184
+ renderContext[key] = value.call(renderContext);
185
+ }
180
186
  }
181
187
  }
182
188
  return render.call(this, renderContext, ...args);
@@ -344,13 +350,17 @@ async function renderSuspended(component, options) {
344
350
  propsContext[key] = passedProps[key];
345
351
  }
346
352
  if (methods && typeof methods === "object") {
347
- for (const key in methods) {
348
- renderContext[key] = methods[key].bind(renderContext);
353
+ for (const [key, value] of Object.entries(methods)) {
354
+ renderContext[key] = value.bind(renderContext);
349
355
  }
350
356
  }
351
357
  if (computed && typeof computed === "object") {
352
- for (const key in computed) {
353
- renderContext[key] = computed[key].call(renderContext);
358
+ for (const [key, value] of Object.entries(computed)) {
359
+ if ("get" in value) {
360
+ renderContext[key] = value.get.call(renderContext);
361
+ } else {
362
+ renderContext[key] = value.call(renderContext);
363
+ }
354
364
  }
355
365
  }
356
366
  return render.call(this, renderContext, ...args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/test-utils",
3
- "version": "3.19.0",
3
+ "version": "3.19.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/test-utils.git"
@@ -57,15 +57,17 @@
57
57
  "lint": "eslint .",
58
58
  "lint:fix": "eslint . --fix",
59
59
  "test:examples": "pnpm --filter '!example-app-cucumber' --filter '!example-app-jest' -r test && pnpm --filter example-app-cucumber -r test",
60
+ "test:knip": "knip",
61
+ "test:engines": "pnpm installed-check --no-workspaces --ignore-dev",
60
62
  "test:types": "vue-tsc --noEmit",
61
63
  "test:unit": "vitest test/unit --run",
64
+ "build": "unbuild",
62
65
  "prepack": "unbuild",
63
- "dev:prepare": "nuxi prepare && unbuild --stub && pnpm -r dev:prepare"
66
+ "dev:prepare": "nuxt prepare && unbuild --stub && pnpm -r dev:prepare"
64
67
  },
65
68
  "dependencies": {
66
- "@nuxt/kit": "^3.17.3",
67
- "@nuxt/schema": "^3.17.3",
68
- "c12": "^3.0.3",
69
+ "@nuxt/kit": "^3.17.5",
70
+ "c12": "^3.0.4",
69
71
  "consola": "^3.4.2",
70
72
  "defu": "^6.1.4",
71
73
  "destr": "^2.0.5",
@@ -76,7 +78,7 @@
76
78
  "local-pkg": "^1.1.1",
77
79
  "magic-string": "^0.30.17",
78
80
  "node-fetch-native": "^1.6.5",
79
- "node-mock-http": "^1.0.0",
81
+ "node-mock-http": "^1.0.1",
80
82
  "ofetch": "^1.4.1",
81
83
  "pathe": "^2.0.3",
82
84
  "perfect-debounce": "^1.0.0",
@@ -85,52 +87,53 @@
85
87
  "std-env": "^3.9.0",
86
88
  "tinyexec": "^1.0.1",
87
89
  "ufo": "^1.6.1",
88
- "unplugin": "^2.3.3",
89
- "vite": "^6.3.5",
90
+ "unplugin": "^2.3.5",
90
91
  "vitest-environment-nuxt": "^1.0.1",
91
- "vue": "^3.5.13"
92
+ "vue": "^3.5.17"
92
93
  },
93
94
  "devDependencies": {
94
- "@cucumber/cucumber": "11.2.0",
95
- "@jest/globals": "29.7.0",
96
- "@nuxt/devtools-kit": "2.4.0",
97
- "@nuxt/eslint-config": "1.3.1",
98
- "@playwright/test": "1.52.0",
95
+ "@cucumber/cucumber": "11.3.0",
96
+ "@jest/globals": "30.0.3",
97
+ "@nuxt/devtools-kit": "2.6.0",
98
+ "@nuxt/eslint-config": "1.4.1",
99
+ "@nuxt/schema": "3.17.5",
100
+ "@playwright/test": "1.53.2",
99
101
  "@testing-library/vue": "8.1.0",
100
- "@types/bun": "1.2.13",
101
- "@types/estree": "1.0.7",
102
+ "@types/bun": "1.2.17",
103
+ "@types/estree": "1.0.8",
102
104
  "@types/jsdom": "21.1.7",
103
- "@types/node": "22.15.17",
105
+ "@types/node": "latest",
104
106
  "@types/semver": "7.7.0",
105
107
  "@vue/test-utils": "2.4.6",
106
108
  "changelogen": "0.6.1",
107
109
  "compatx": "0.2.0",
108
- "eslint": "9.26.0",
110
+ "eslint": "9.30.0",
109
111
  "installed-check": "9.3.0",
110
- "knip": "5.55.1",
111
- "nitropack": "2.11.11",
112
- "nuxt": "3.17.3",
113
- "pkg-pr-new": "0.0.44",
114
- "playwright-core": "1.52.0",
115
- "rollup": "4.40.2",
112
+ "knip": "5.61.3",
113
+ "nitropack": "2.11.13",
114
+ "nuxt": "3.17.5",
115
+ "pkg-pr-new": "0.0.54",
116
+ "playwright-core": "1.53.2",
117
+ "rollup": "4.44.1",
116
118
  "semver": "7.7.2",
117
119
  "typescript": "5.8.3",
118
120
  "unbuild": "latest",
119
- "unimport": "5.0.1",
120
- "vitest": "3.1.3",
121
+ "unimport": "5.1.0",
122
+ "vite": "7.0.0",
123
+ "vitest": "3.2.4",
121
124
  "vue-router": "4.5.1",
122
125
  "vue-tsc": "2.2.10"
123
126
  },
124
127
  "peerDependencies": {
125
128
  "@cucumber/cucumber": "^10.3.1 || ^11.0.0",
126
- "@jest/globals": "^29.5.0",
129
+ "@jest/globals": "^29.5.0 || ^30.0.0",
127
130
  "@playwright/test": "^1.43.1",
128
131
  "@testing-library/vue": "^7.0.0 || ^8.0.1",
129
132
  "@vue/test-utils": "^2.4.2",
130
- "happy-dom": "^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0",
133
+ "happy-dom": "^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
131
134
  "jsdom": "^22.0.0 || ^23.0.0 || ^24.0.0 || ^25.0.0 || ^26.0.0",
132
135
  "playwright-core": "^1.43.1",
133
- "vitest": "^0.34.6 || ^1.0.0 || ^2.0.0 || ^3.0.0"
136
+ "vitest": "^3.2.0"
134
137
  },
135
138
  "peerDependenciesMeta": {
136
139
  "@cucumber/cucumber": {
@@ -165,21 +168,21 @@
165
168
  }
166
169
  },
167
170
  "resolutions": {
168
- "@cucumber/cucumber": "11.2.0",
169
- "@nuxt/devtools": "1.0.8",
170
- "@nuxt/kit": "^3.17.3",
171
- "@nuxt/schema": "^3.17.3",
171
+ "@cucumber/cucumber": "11.3.0",
172
+ "@nuxt/kit": "^3.17.5",
173
+ "@nuxt/schema": "^3.17.5",
172
174
  "@nuxt/test-utils": "workspace:*",
173
- "rollup": "4.40.2",
174
- "vite": "^6.3.5",
175
- "vite-node": "3.1.3",
176
- "vitest": "3.1.3",
177
- "vue": "^3.5.13"
175
+ "@types/node": "22.15.34",
176
+ "rollup": "4.44.1",
177
+ "vite": "7.0.0",
178
+ "vite-node": "3.2.4",
179
+ "vitest": "3.2.4",
180
+ "vue": "^3.5.17"
178
181
  },
179
182
  "engines": {
180
- "node": "^18.20.5 || ^20.9.0 || ^22.0.0 || >=23.0.0"
183
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
181
184
  },
182
- "packageManager": "pnpm@10.10.0",
185
+ "packageManager": "pnpm@10.12.4",
183
186
  "pnpm": {
184
187
  "onlyBuiltDependencies": [
185
188
  "better-sqlite3"