@nuxt/test-utils 3.9.0-alpha.1 → 3.9.0-alpha.3

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
@@ -2,12 +2,17 @@ import * as vite from 'vite';
2
2
  import { InlineConfig } from 'vite';
3
3
  import { NuxtConfig, Nuxt } from '@nuxt/schema';
4
4
  import { InlineConfig as InlineConfig$1 } from 'vitest';
5
+ import { DotenvOptions } from 'c12';
5
6
 
6
7
  interface GetVitestConfigOptions {
7
8
  nuxt: Nuxt;
8
9
  viteConfig: InlineConfig;
9
10
  }
10
- declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, overrides?: NuxtConfig): Promise<InlineConfig & {
11
+ interface LoadNuxtOptions {
12
+ dotenv?: Partial<DotenvOptions>;
13
+ overrides?: Partial<NuxtConfig>;
14
+ }
15
+ declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, loadNuxtOptions?: LoadNuxtOptions): Promise<InlineConfig & {
11
16
  test: InlineConfig$1;
12
17
  }>;
13
18
  declare function defineVitestConfig(config?: InlineConfig & {
@@ -22,6 +27,13 @@ declare module 'vitest' {
22
27
  * @default {http://localhost:3000}
23
28
  */
24
29
  url?: string;
30
+ /**
31
+ * You can define how environment options are read when loading the Nuxt configuration.
32
+ */
33
+ dotenv?: Partial<DotenvOptions>;
34
+ /**
35
+ * Configuration that will override the values in your `nuxt.config` file.
36
+ */
25
37
  overrides?: NuxtConfig;
26
38
  /**
27
39
  * The id of the root div to which the app should be mounted. You should also set `app.rootId` to the same value.
package/dist/config.d.ts CHANGED
@@ -2,12 +2,17 @@ import * as vite from 'vite';
2
2
  import { InlineConfig } from 'vite';
3
3
  import { NuxtConfig, Nuxt } from '@nuxt/schema';
4
4
  import { InlineConfig as InlineConfig$1 } from 'vitest';
5
+ import { DotenvOptions } from 'c12';
5
6
 
6
7
  interface GetVitestConfigOptions {
7
8
  nuxt: Nuxt;
8
9
  viteConfig: InlineConfig;
9
10
  }
10
- declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, overrides?: NuxtConfig): Promise<InlineConfig & {
11
+ interface LoadNuxtOptions {
12
+ dotenv?: Partial<DotenvOptions>;
13
+ overrides?: Partial<NuxtConfig>;
14
+ }
15
+ declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, loadNuxtOptions?: LoadNuxtOptions): Promise<InlineConfig & {
11
16
  test: InlineConfig$1;
12
17
  }>;
13
18
  declare function defineVitestConfig(config?: InlineConfig & {
@@ -22,6 +27,13 @@ declare module 'vitest' {
22
27
  * @default {http://localhost:3000}
23
28
  */
24
29
  url?: string;
30
+ /**
31
+ * You can define how environment options are read when loading the Nuxt configuration.
32
+ */
33
+ dotenv?: Partial<DotenvOptions>;
34
+ /**
35
+ * Configuration that will override the values in your `nuxt.config` file.
36
+ */
25
37
  overrides?: NuxtConfig;
26
38
  /**
27
39
  * The id of the root div to which the app should be mounted. You should also set `app.rootId` to the same value.
package/dist/config.mjs CHANGED
@@ -1,19 +1,56 @@
1
1
  import { defineConfig } from 'vite';
2
+ import { setupDotenv } from 'c12';
2
3
  import { defu } from 'defu';
3
4
  import { createResolver } from '@nuxt/kit';
5
+ import destr from 'destr';
6
+ import { snakeCase } from 'scule';
4
7
 
5
- async function startNuxtAndGetViteConfig(rootDir = process.cwd(), overrides) {
8
+ function getEnv(key, opts) {
9
+ const env = opts.env ?? process.env;
10
+ const envKey = snakeCase(key).toUpperCase();
11
+ return destr(
12
+ env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]
13
+ );
14
+ }
15
+ function _isObject(input) {
16
+ return typeof input === "object" && !Array.isArray(input);
17
+ }
18
+ function applyEnv(obj, opts, parentKey = "") {
19
+ for (const key in obj) {
20
+ const subKey = parentKey ? `${parentKey}_${key}` : key;
21
+ const envValue = getEnv(subKey, opts);
22
+ if (_isObject(obj[key])) {
23
+ if (_isObject(envValue)) {
24
+ obj[key] = { ...obj[key], ...envValue };
25
+ applyEnv(obj[key], opts, subKey);
26
+ } else if (envValue === void 0) {
27
+ applyEnv(obj[key], opts, subKey);
28
+ } else {
29
+ obj[key] = envValue ?? obj[key];
30
+ }
31
+ } else {
32
+ obj[key] = envValue ?? obj[key];
33
+ }
34
+ }
35
+ return obj;
36
+ }
37
+
38
+ async function startNuxtAndGetViteConfig(rootDir = process.cwd(), options = {}) {
6
39
  const { loadNuxt, buildNuxt } = await import('@nuxt/kit');
7
40
  const nuxt = await loadNuxt({
8
41
  cwd: rootDir,
9
42
  dev: false,
43
+ dotenv: defu(options.dotenv, {
44
+ cwd: rootDir,
45
+ fileName: ".env.test"
46
+ }),
10
47
  overrides: defu(
11
48
  {
12
49
  ssr: false,
13
50
  test: true,
14
51
  modules: ["@nuxt/test-utils/module"]
15
52
  },
16
- overrides
53
+ options.overrides
17
54
  )
18
55
  });
19
56
  if (!nuxt.options._installedModules.find((i) => i?.meta?.name === "@nuxt/test-utils")) {
@@ -40,12 +77,15 @@ const excludedPlugins = [
40
77
  "nuxt:import-protection",
41
78
  "vite-plugin-checker"
42
79
  ];
43
- async function getVitestConfigFromNuxt(options, overrides) {
44
- const { rootDir = process.cwd(), ..._overrides } = overrides || {};
80
+ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
81
+ const { rootDir = process.cwd(), ..._overrides } = loadNuxtOptions.overrides || {};
45
82
  if (!options) {
46
83
  options = await startNuxtAndGetViteConfig(rootDir, {
47
- test: true,
48
- ..._overrides
84
+ dotenv: loadNuxtOptions.dotenv,
85
+ overrides: {
86
+ test: true,
87
+ ..._overrides
88
+ }
49
89
  });
50
90
  }
51
91
  options.viteConfig.plugins = (options.viteConfig.plugins || []).filter((p) => !excludedPlugins.includes(p?.name));
@@ -58,7 +98,13 @@ async function getVitestConfigFromNuxt(options, overrides) {
58
98
  test: {
59
99
  dir: process.cwd(),
60
100
  environmentOptions: {
61
- nuxtRuntimeConfig: options.nuxt.options.runtimeConfig,
101
+ nuxtRuntimeConfig: applyEnv(structuredClone(options.nuxt.options.runtimeConfig), {
102
+ prefix: "NUXT_",
103
+ env: await setupDotenv(defu(loadNuxtOptions.dotenv, {
104
+ cwd: rootDir,
105
+ fileName: ".env.test"
106
+ }))
107
+ }),
62
108
  nuxtRouteRules: defu(
63
109
  {},
64
110
  options.nuxt.options.routeRules,
@@ -69,21 +115,24 @@ async function getVitestConfigFromNuxt(options, overrides) {
69
115
  ["**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}", "nuxt"],
70
116
  ["{test,tests}/nuxt/**.*", "nuxt"]
71
117
  ],
118
+ server: {
119
+ deps: {
120
+ inline: [
121
+ // vite-node defaults
122
+ /\/node_modules\/(.*\/)?(nuxt|nuxt3|nuxt-nightly)\//,
123
+ /^#/,
124
+ // additional deps
125
+ "@nuxt/test-utils",
126
+ "@nuxt/test-utils-nightly",
127
+ "@nuxt/test-utils-edge",
128
+ "vitest-environment-nuxt",
129
+ ...options.nuxt.options.build.transpile.filter(
130
+ (r) => typeof r === "string" || r instanceof RegExp
131
+ )
132
+ ]
133
+ }
134
+ },
72
135
  deps: {
73
- // TODO: move to server.deps.inline when we update to vite v1
74
- inline: [
75
- // vite-node defaults
76
- /\/node_modules\/(.*\/)?(nuxt|nuxt3|nuxt-nightly)\//,
77
- /^#/,
78
- // additional deps
79
- "@nuxt/test-utils",
80
- "@nuxt/test-utils-nightly",
81
- "@nuxt/test-utils-edge",
82
- "vitest-environment-nuxt",
83
- ...options.nuxt.options.build.transpile.filter(
84
- (r) => typeof r === "string" || r instanceof RegExp
85
- )
86
- ],
87
136
  optimizer: {
88
137
  web: {
89
138
  enabled: false
@@ -101,8 +150,8 @@ async function getVitestConfigFromNuxt(options, overrides) {
101
150
  transform(code, id) {
102
151
  if (id.match(/nuxt(3|-nightly)?\/.*\/entry\./)) {
103
152
  return code.replace(
104
- /(?<!vueAppPromise = )entry\(\)\.catch/,
105
- "Promise.resolve().catch"
153
+ /(?<!vueAppPromise = )entry\(\)/,
154
+ "Promise.resolve()"
106
155
  );
107
156
  }
108
157
  }
@@ -140,9 +189,15 @@ function defineVitestConfig(config = {}) {
140
189
  return config;
141
190
  const overrides = config.test?.environmentOptions?.nuxt?.overrides || {};
142
191
  overrides.rootDir = config.test?.environmentOptions?.nuxt?.rootDir;
192
+ if (config.test?.setupFiles && !Array.isArray(config.test.setupFiles)) {
193
+ config.test.setupFiles = [config.test.setupFiles].filter(Boolean);
194
+ }
143
195
  return defu(
144
196
  config,
145
- await getVitestConfigFromNuxt(void 0, structuredClone(overrides))
197
+ await getVitestConfigFromNuxt(void 0, {
198
+ dotenv: config.test?.environmentOptions?.nuxt?.dotenv,
199
+ overrides: structuredClone(overrides)
200
+ })
146
201
  );
147
202
  });
148
203
  }
package/dist/e2e.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { u as useTestContext, a as url, c as createTestContext, s as setTestContext, b as stopServer, d as startServer } from './shared/test-utils.ddf5bsCK.mjs';
2
- export { $ as $fetch, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv } from './shared/test-utils.ddf5bsCK.mjs';
1
+ import { u as useTestContext, a as url, c as createTestContext, s as setTestContext, b as stopServer, d as startServer } from './shared/test-utils.B1uaYm8K.mjs';
2
+ export { $ as $fetch, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv } from './shared/test-utils.B1uaYm8K.mjs';
3
3
  import { consola } from 'consola';
4
4
  import { existsSync, promises } from 'node:fs';
5
5
  import { resolve } from 'node:path';
@@ -1,6 +1,6 @@
1
1
  import { resolve } from 'pathe';
2
2
  import { stringifyQuery } from 'ufo';
3
- import { $ as $fetch, u as useTestContext } from './shared/test-utils.ddf5bsCK.mjs';
3
+ import { $ as $fetch, u as useTestContext } from './shared/test-utils.B1uaYm8K.mjs';
4
4
  import 'execa';
5
5
  import 'get-port-please';
6
6
  import 'ofetch';
package/dist/module.mjs CHANGED
@@ -13,6 +13,9 @@ import { normalize, resolve } from 'node:path';
13
13
  import { createUnplugin } from 'unplugin';
14
14
  import { readFileSync } from 'node:fs';
15
15
  import { extname, join, dirname } from 'pathe';
16
+ import 'c12';
17
+ import 'destr';
18
+ import 'scule';
16
19
 
17
20
  const PLUGIN_NAME$1 = "nuxt:vitest:mock-transform";
18
21
  const HELPER_MOCK_IMPORT = "mockNuxtImport";
@@ -405,10 +408,10 @@ const module = defineNuxtModule({
405
408
  promise2.catch(() => process.exit(1));
406
409
  if (watchMode) {
407
410
  logger.info(`Vitest UI starting on ${URL}`);
411
+ nuxt.hook("close", () => promise2.then((v) => v?.close()));
408
412
  await new Promise((resolve) => setTimeout(resolve, 1e3));
409
413
  } else {
410
- promise2.then((v) => v?.close()).then(() => process.exit());
411
- promise2.catch(() => process.exit(1));
414
+ promise2.then((v) => nuxt.close().then(() => v?.close()).then(() => process.exit()));
412
415
  }
413
416
  loaded = true;
414
417
  }
@@ -1,6 +1,6 @@
1
1
  import { defineEventHandler } from 'h3';
2
2
  import { mount } from '@vue/test-utils';
3
- import { h as h$1, Suspense, nextTick } from 'vue';
3
+ import { reactive, h as h$1, Suspense, nextTick, isReadonly, unref } from 'vue';
4
4
  import { defu } from 'defu';
5
5
  import { defineComponent, useRouter, h } from '#imports';
6
6
  import NuxtRoot from '#build/root-component.mjs';
@@ -74,7 +74,10 @@ async function mountSuspended(component, options) {
74
74
  const { render, setup } = component;
75
75
  let setupContext;
76
76
  let setupState;
77
+ const setProps = reactive({});
78
+ let passedProps;
77
79
  const wrappedSetup = async (props2, setupContext2) => {
80
+ passedProps = props2;
78
81
  if (setup) {
79
82
  setupState = await setup(props2, setupContext2);
80
83
  return setupState;
@@ -97,6 +100,9 @@ async function mountSuspended(component, options) {
97
100
  {
98
101
  onResolve: () => nextTick().then(() => {
99
102
  vm.setupState = setupState;
103
+ vm.__setProps = (props2) => {
104
+ Object.assign(setProps, props2);
105
+ };
100
106
  resolve(vm);
101
107
  })
102
108
  },
@@ -110,17 +116,20 @@ async function mountSuspended(component, options) {
110
116
  name: "MountSuspendedComponent",
111
117
  ...component,
112
118
  render: render ? function(_ctx, ...args) {
119
+ for (const key in setupState || {}) {
120
+ renderContext[key] = isReadonly(setupState[key]) ? unref(setupState[key]) : setupState[key];
121
+ }
113
122
  for (const key in props || {}) {
114
123
  renderContext[key] = _ctx[key];
115
124
  }
116
- for (const key in setupState || {}) {
117
- renderContext[key] = setupState[key];
125
+ for (const key in passedProps || {}) {
126
+ renderContext[key] = passedProps[key];
118
127
  }
119
128
  return render.call(this, renderContext, ...args);
120
129
  } : void 0,
121
130
  setup: setup ? (props2) => wrappedSetup(props2, setupContext) : void 0
122
131
  };
123
- return () => h$1(clonedComponent, { ...props, ...attrs }, slots);
132
+ return () => h$1(clonedComponent, { ...defu(setProps, props), ...attrs }, slots);
124
133
  }
125
134
  })
126
135
  }
@@ -18,8 +18,7 @@ function createTestContext(options) {
18
18
  server: true,
19
19
  build: options.browser !== false || options.server !== false,
20
20
  nuxtConfig: {},
21
- // TODO: auto detect based on process.env
22
- runner: "vitest",
21
+ runner: process.env.VITEST === "true" ? "vitest" : "jest",
23
22
  browserOptions: {
24
23
  type: "chromium"
25
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/test-utils",
3
- "version": "3.9.0-alpha.1",
3
+ "version": "3.9.0-alpha.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/test-utils.git"
@@ -30,8 +30,10 @@
30
30
  "dependencies": {
31
31
  "@nuxt/kit": "^3.8.2",
32
32
  "@nuxt/schema": "^3.8.2",
33
+ "c12": "^1.5.1",
33
34
  "consola": "^3.2.3",
34
35
  "defu": "^6.1.3",
36
+ "destr": "^2.0.2",
35
37
  "estree-walker": "^3.0.3",
36
38
  "execa": "^8.0.1",
37
39
  "fake-indexeddb": "^5.0.1",
@@ -43,6 +45,7 @@
43
45
  "pathe": "^1.1.1",
44
46
  "perfect-debounce": "^1.0.0",
45
47
  "radix3": "^1.1.0",
48
+ "scule": "^1.1.1",
46
49
  "std-env": "^3.6.0",
47
50
  "ufo": "^1.3.2",
48
51
  "unenv": "^1.8.0",
@@ -51,7 +54,7 @@
51
54
  },
52
55
  "devDependencies": {
53
56
  "@jest/globals": "29.7.0",
54
- "@nuxt/devtools": "1.0.5",
57
+ "@nuxt/devtools": "1.0.6",
55
58
  "@nuxt/eslint-config": "0.2.0",
56
59
  "@nuxt/module-builder": "0.5.4",
57
60
  "@testing-library/vue": "8.0.1",
@@ -61,35 +64,35 @@
61
64
  "@vitest/ui": "1.0.4",
62
65
  "@vue/test-utils": "2.4.3",
63
66
  "changelogen": "0.5.5",
64
- "eslint": "8.55.0",
65
- "eslint-plugin-import": "2.29.0",
66
- "eslint-plugin-jsdoc": "46.9.0",
67
+ "eslint": "8.56.0",
68
+ "eslint-plugin-import": "2.29.1",
69
+ "eslint-plugin-jsdoc": "46.9.1",
67
70
  "eslint-plugin-no-only-tests": "3.1.0",
68
71
  "eslint-plugin-unicorn": "49.0.0",
69
72
  "h3": "1.9.0",
70
73
  "jiti": "1.21.0",
71
74
  "nuxt": "3.8.2",
72
75
  "playwright-core": "1.40.1",
73
- "rollup": "4.8.0",
76
+ "rollup": "4.9.1",
74
77
  "semver": "7.5.4",
75
78
  "unbuild": "latest",
76
79
  "unimport": "3.6.1",
77
- "vite": "5.0.7",
78
- "vitest": "1.0.4",
80
+ "vite": "5.0.10",
81
+ "vitest": "latest",
79
82
  "vue-router": "4.2.5",
80
83
  "vue-tsc": "1.8.25"
81
84
  },
82
85
  "peerDependencies": {
83
86
  "@jest/globals": "^29.5.0",
84
87
  "@testing-library/vue": "^7.0.0 || ^8.0.1",
85
- "@vitest/ui": "^0.33.0 || ^0.34.6 || ^1.0.0",
88
+ "@vitest/ui": "^0.34.6 || ^1.0.0",
86
89
  "@vue/test-utils": "^2.4.2",
87
90
  "h3": "*",
88
91
  "happy-dom": "^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0",
89
92
  "jsdom": "^22.0.0 || ^23.0.0",
90
93
  "playwright-core": "^1.34.3",
91
94
  "vite": "*",
92
- "vitest": "^0.24.5 || ^0.26.0 || ^0.27.0 || ^0.28.0 || ^0.29.0 || ^0.30.0 || ^0.33.0 || ^0.34.6 || ^1.0.0",
95
+ "vitest": "^0.34.6 || ^1.0.0",
93
96
  "vue": "^3.3.4",
94
97
  "vue-router": "^4.0.0"
95
98
  },
@@ -121,13 +124,13 @@
121
124
  },
122
125
  "resolutions": {
123
126
  "@nuxt/test-utils": "workspace:*",
124
- "rollup": "4.8.0",
125
- "vite": "5.0.7"
127
+ "rollup": "4.9.1",
128
+ "vite": "5.0.10"
126
129
  },
127
130
  "engines": {
128
131
  "node": "^14.18.0 || >=16.10.0"
129
132
  },
130
- "packageManager": "pnpm@8.12.0",
133
+ "packageManager": "pnpm@8.12.1",
131
134
  "scripts": {
132
135
  "lint": "eslint --ext .vue,.ts,.js,.mjs .",
133
136
  "lint:fix": "eslint --ext .vue,.ts,.js,.mjs . --fix",
@@ -135,6 +138,6 @@
135
138
  "test:types": "vue-tsc --noEmit",
136
139
  "test:unit": "vitest test/unit --run",
137
140
  "dev:prepare": "nuxi prepare && unbuild --stub && pnpm -r dev:prepare",
138
- "release": "pnpm test:examples && pnpm build && changelogen --release --push && pnpm publish"
141
+ "release": "pnpm test:examples && pnpm prepack && changelogen --release --push && pnpm publish"
139
142
  }
140
143
  }