@nuxt/test-utils
Version:
Test utilities for Nuxt
213 lines (209 loc) • 6.34 kB
JavaScript
import { defineConfig } from 'vite';
import { setupDotenv } from 'c12';
import { defu } from 'defu';
import { createResolver } from '@nuxt/kit';
import destr from 'destr';
import { snakeCase } from 'scule';
function getEnv(key, opts) {
const env = opts.env ?? process.env;
const envKey = snakeCase(key).toUpperCase();
return destr(
env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]
);
}
function _isObject(input) {
return typeof input === "object" && !Array.isArray(input);
}
function applyEnv(obj, opts, parentKey = "") {
for (const key in obj) {
const subKey = parentKey ? `${parentKey}_${key}` : key;
const envValue = getEnv(subKey, opts);
if (_isObject(obj[key])) {
if (_isObject(envValue)) {
obj[key] = { ...obj[key], ...envValue };
applyEnv(obj[key], opts, subKey);
} else if (envValue === void 0) {
applyEnv(obj[key], opts, subKey);
} else {
obj[key] = envValue ?? obj[key];
}
} else {
obj[key] = envValue ?? obj[key];
}
}
return obj;
}
async function startNuxtAndGetViteConfig(rootDir = process.cwd(), options = {}) {
const { loadNuxt, buildNuxt } = await import('@nuxt/kit');
const nuxt = await loadNuxt({
cwd: rootDir,
dev: false,
dotenv: defu(options.dotenv, {
cwd: rootDir,
fileName: ".env.test"
}),
defaults: {
// suppress compatibility date warning for runtime environment tests
compatibilityDate: "2024-04-03"
},
overrides: defu(
{
appId: "nuxt-app",
buildId: "test",
ssr: false,
test: true,
modules: ["@nuxt/test-utils/module"]
},
options.overrides
)
});
if (!nuxt.options._installedModules.find((i) => i?.meta?.name === "@nuxt/test-utils")) {
throw new Error(
"Failed to load `@nuxt/test-utils/module`. You may need to add it to your nuxt.config."
);
}
const promise = new Promise((resolve, reject) => {
nuxt.hook("vite:configResolved", (viteConfig, { isClient }) => {
if (isClient) {
resolve({ nuxt, viteConfig });
throw new Error("_stop_");
}
});
buildNuxt(nuxt).catch((err) => {
if (!err.toString().includes("_stop_")) {
reject(err);
}
});
}).finally(() => nuxt.close());
return promise;
}
const excludedPlugins = [
"nuxt:import-protection",
"nuxt:import-conditions",
"vite-plugin-checker"
];
async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
const { rootDir = process.cwd(), ..._overrides } = loadNuxtOptions.overrides || {};
if (!options) {
options = await startNuxtAndGetViteConfig(rootDir, {
dotenv: loadNuxtOptions.dotenv,
overrides: {
test: true,
..._overrides
}
});
}
options.viteConfig.plugins = (options.viteConfig.plugins || []).filter((p) => !p || !("name" in p) || !excludedPlugins.includes(p.name));
const resolvedConfig = defu(
// overrides
{
define: {
["process.env.NODE_ENV"]: "process.env.NODE_ENV"
},
test: {
dir: process.cwd(),
environmentOptions: {
nuxtRuntimeConfig: applyEnv(structuredClone(options.nuxt.options.runtimeConfig), {
prefix: "NUXT_",
env: await setupDotenv(defu(loadNuxtOptions.dotenv, {
cwd: rootDir,
fileName: ".env.test"
}))
}),
nuxtRouteRules: defu(
{},
options.nuxt.options.routeRules,
options.nuxt.options.nitro?.routeRules
)
},
environmentMatchGlobs: [
["**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}", "nuxt"],
["{test,tests}/nuxt/**.*", "nuxt"]
],
server: {
deps: {
inline: [
// vite-node defaults
/\/node_modules\/(.*\/)?(nuxt|nuxt3|nuxt-nightly)\//,
/^#/,
// additional deps
"@nuxt/test-utils",
"@nuxt/test-utils-nightly",
"@nuxt/test-utils-edge",
"vitest-environment-nuxt",
...options.nuxt.options.build.transpile.filter(
(r) => typeof r === "string" || r instanceof RegExp
)
]
}
},
deps: {
optimizer: {
web: {
enabled: false
}
}
}
}
},
{
server: { middlewareMode: false },
plugins: [
{
name: "disable-auto-execute",
enforce: "pre",
transform(code, id) {
if (id.match(/nuxt(3|-nightly)?\/.*\/entry\./)) {
return code.replace(
/(? {
if (process.env.__NUXT_VITEST_RESOLVED__) return config;
const overrides = config.test?.environmentOptions?.nuxt?.overrides || {};
overrides.rootDir = config.test?.environmentOptions?.nuxt?.rootDir;
if (config.test?.setupFiles && !Array.isArray(config.test.setupFiles)) {
config.test.setupFiles = [config.test.setupFiles].filter(Boolean);
}
return defu(
config,
await getVitestConfigFromNuxt(void 0, {
dotenv: config.test?.environmentOptions?.nuxt?.dotenv,
overrides: structuredClone(overrides)
})
);
});
}
export { defineVitestConfig, getVitestConfigFromNuxt };