feat(vitest-environment): support @vitest-environment-options#1673
feat(vitest-environment): support @vitest-environment-options#1673yamachi4416 wants to merge 1 commit intonuxt:mainfrom
@vitest-environment-options#1673Conversation
commit: |
d80da26 to
acf91a9
Compare
📝 WalkthroughWalkthroughMerges per-test Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/runtime/shared/environment.ts (1)
79-83: Redundant optional chaining on required parameter.
environmentOptionsis now required (non-optional) per the newSetupWindowNuxtEnvironmentOptionssignature, so theenvironmentOptions?.optional chain on Line 80–81 is dead. The inner?.nuxtRuntimeConfig?.app?.baseURLchain is still needed sincenuxtRuntimeConfigis optional.♻️ Proposed tweak
const manifestOutputPath = joinURL( - environmentOptions?.nuxtRuntimeConfig?.app?.baseURL || '/', - environmentOptions?.nuxtRuntimeConfig?.app?.buildAssetsDir || '_nuxt', + environmentOptions.nuxtRuntimeConfig?.app?.baseURL || '/', + environmentOptions.nuxtRuntimeConfig?.app?.buildAssetsDir || '_nuxt', 'builds', )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/runtime/shared/environment.ts` around lines 79 - 83, The manifestOutputPath computation uses redundant optional chaining on the now-required parameter environmentOptions; change the references from environmentOptions?.nuxtRuntimeConfig to environmentOptions.nuxtRuntimeConfig (keep the remaining ?.nuxtRuntimeConfig?.app?.baseURL and ?.app?.buildAssetsDir chains intact) so that only the unnecessary leading ?. is removed; update the expression that constructs manifestOutputPath (the joinURL call where manifestOutputPath is declared) to reference environmentOptions directly while preserving the inner optional chains.src/module/plugins/options.ts (1)
22-28: DoubleJSON.stringifyis correct here, but add a brief comment.
definevalues must be JavaScript source expressions, so the payload needs to be a string literal whose runtime value is the JSON text.JSON.stringify(serializedOptions)achieves exactly that (turning{"a":1}into"\"{\\\"a\\\":1}\""), which is thenJSON.parse'd insrc/environments/vitest/index.ts. This looks odd at first glance and is easy to "simplify" incorrectly — a one-line comment would prevent future regressions.♻️ Suggested comment
config() { return { define: { + // Double-stringify: `define` values must be source expressions, so we need a JS string literal + // whose runtime value is the JSON text (consumed via JSON.parse in the Vitest env setup). 'process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__': JSON.stringify(serializedOptions), }, } },Also worth confirming the
defineactually reaches the Vitest environment module (src/environments/vitest/index.ts) at runtime — this depends on that file being transformed by Vite.@nuxt/test-utilsis inserver.deps.inlineso this should hold, but it's worth a manual spot-check (e.g., log the raw env value from inside the environment) given a silent failure here would degrade to the exact bug#1541describes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/module/plugins/options.ts` around lines 22 - 28, Add a one-line inline comment above the define entry in the config() method (referencing define and serializedOptions) that explains why we call JSON.stringify(serializedOptions) twice so future readers don't remove the extra stringification (i.e., define expects a JS source expression string which will be parsed at runtime in src/environments/vitest/index.ts). After adding the comment, perform a quick runtime spot-check by logging the raw process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ value from src/environments/vitest/index.ts to confirm the define is being transformed and the JSON text is present at runtime.examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.ts (1)
1-17: Coverage looks good, but consider assertingjsdom-specific global to avoid UA-string false positives.
navigator.userAgentcontaining"jsdom"is a reasonable signal today, but a stronger assertion is the presence of a jsdom-only global/marker (e.g.,window._virtualConsoleor checking that happy-dom's signature is absent) to protect against happy-dom one day including the substring in its UA. Optional.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.ts` around lines 1 - 17, Update the test "can override domEnvironment via `@vitest-environment-options`" to assert a jsdom-specific global in addition to the navigator check: keep the existing navigator.userAgent assertion and add a second assertion that a jsdom-only marker (for example window._virtualConsole is defined or another jsdom-specific property) exists so the test doesn't rely solely on UA-string content; modify the test body that references navigator.userAgent and add the additional expectation against window._virtualConsole (or another jsdom-only global) to strengthen the environment check.src/config.ts (1)
373-399: Docs accurately reflect the new scope.Calling out the
@vitest-environment-optionsoverride on exactly the two supported fields (url,domEnvironment) is appropriate. Consider also noting in the interface doc (or README) that othernuxt.*options inside an annotation are currently ignored, so users don't get surprised when setting e.g.rootIdvia annotation has no effect.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/config.ts` around lines 373 - 399, Update the interface/doc comment around the Nuxt test environment options (the properties url and domEnvironment) to explicitly state that only these two fields are read from the `@vitest-environment-options` annotation and that other nuxt.* options (for example rootId or values under overrides/dotenv) present in the annotation will be ignored; mention this behavior in the comment block near the url, domEnvironment and rootId declarations so users aren’t surprised when setting other options via the annotation has no effect.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/environments/vitest/index.ts`:
- Around line 70-90: mergeSetupWindowEnvironmentOptions currently only keeps
nuxt.url and nuxt.domEnvironment and silently drops any other keys under nuxt,
and also blindly spreads all top-level environmentOptions which lets unintended
top-level keys override base config; update mergeSetupWindowEnvironmentOptions
to (1) detect any keys present on the incoming environmentOptions.nuxt other
than "url" and "domEnvironment" and emit a single console.warn per unknown key
(include the key name and that it's ignored) to aid debugging, and (2) replace
the broad "...environmentOptions" spread with a narrow allowlist of safe
top-level keys (e.g., happyDom, jsdom, nuxtRuntimeConfig, nuxtRouteRules —
whatever the project deems safe) so only those top-level annotation keys can
override base config; reference the mergeSetupWindowEnvironmentOptions function
and the nuxt property when making these changes.
---
Nitpick comments:
In `@examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.ts`:
- Around line 1-17: Update the test "can override domEnvironment via
`@vitest-environment-options`" to assert a jsdom-specific global in addition to
the navigator check: keep the existing navigator.userAgent assertion and add a
second assertion that a jsdom-only marker (for example window._virtualConsole is
defined or another jsdom-specific property) exists so the test doesn't rely
solely on UA-string content; modify the test body that references
navigator.userAgent and add the additional expectation against
window._virtualConsole (or another jsdom-only global) to strengthen the
environment check.
In `@src/config.ts`:
- Around line 373-399: Update the interface/doc comment around the Nuxt test
environment options (the properties url and domEnvironment) to explicitly state
that only these two fields are read from the `@vitest-environment-options`
annotation and that other nuxt.* options (for example rootId or values under
overrides/dotenv) present in the annotation will be ignored; mention this
behavior in the comment block near the url, domEnvironment and rootId
declarations so users aren’t surprised when setting other options via the
annotation has no effect.
In `@src/module/plugins/options.ts`:
- Around line 22-28: Add a one-line inline comment above the define entry in the
config() method (referencing define and serializedOptions) that explains why we
call JSON.stringify(serializedOptions) twice so future readers don't remove the
extra stringification (i.e., define expects a JS source expression string which
will be parsed at runtime in src/environments/vitest/index.ts). After adding the
comment, perform a quick runtime spot-check by logging the raw
process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ value from
src/environments/vitest/index.ts to confirm the define is being transformed and
the JSON text is present at runtime.
In `@src/runtime/shared/environment.ts`:
- Around line 79-83: The manifestOutputPath computation uses redundant optional
chaining on the now-required parameter environmentOptions; change the references
from environmentOptions?.nuxtRuntimeConfig to
environmentOptions.nuxtRuntimeConfig (keep the remaining
?.nuxtRuntimeConfig?.app?.baseURL and ?.app?.buildAssetsDir chains intact) so
that only the unnecessary leading ?. is removed; update the expression that
constructs manifestOutputPath (the joinURL call where manifestOutputPath is
declared) to reference environmentOptions directly while preserving the inner
optional chains.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 30713eed-6c4a-4211-9f04-49d66ebcbf86
📒 Files selected for processing (7)
examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.tsexamples/app-vitest-full/tests/nuxt/vitest-environment-options-2.spec.tsexamples/app-vitest-full/tests/resolved-files.spec.tssrc/config.tssrc/environments/vitest/index.tssrc/module/plugins/options.tssrc/runtime/shared/environment.ts
acf91a9 to
773442d
Compare
773442d to
f00a8e1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/environments/vitest/index.ts`:
- Around line 70-87: The mergeSetupWindowEnvironmentOptions function currently
falls back to an empty object when
process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ is missing, which loses
incoming options; change the fallback to use the already-parsed
nuxtEnvironmentOptions (from the local variable nuxtEnvironmentOptions) as the
base for defu instead of '{}', ensuring you JSON.parse the env var when present
and pass nuxt: { url, domEnvironment, ... } merged with
JSON.parse(process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ ||
JSON.stringify({ nuxt: nuxtEnvironmentOptions })) so properties like
nuxt.rootId, nuxt.mock, nuxt.h3Version, nuxtRuntimeConfig, and nuxtRouteRules
are preserved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8ad164f9-5977-44e7-993c-de3ba0c329ad
📒 Files selected for processing (7)
examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.tsexamples/app-vitest-full/tests/nuxt/vitest-environment-options-2.spec.tsexamples/app-vitest-full/tests/resolved-files.spec.tssrc/config.tssrc/environments/vitest/index.tssrc/module/plugins/options.tssrc/runtime/shared/environment.ts
✅ Files skipped from review due to trivial changes (3)
- examples/app-vitest-full/tests/resolved-files.spec.ts
- examples/app-vitest-full/tests/nuxt/vitest-environment-options-1.spec.ts
- src/config.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/module/plugins/options.ts
- examples/app-vitest-full/tests/nuxt/vitest-environment-options-2.spec.ts
- src/runtime/shared/environment.ts
| // Manually merge with base config because `@vitest-environment-options` doesn't merge by default | ||
| function mergeSetupWindowEnvironmentOptions( | ||
| environmentOptions: Record<string, unknown>, | ||
| ): SetupWindowNuxtEnvironmentOptions { | ||
| const { | ||
| nuxt: nuxtEnvironmentOptions = {}, | ||
| } = environmentOptions as unknown as SetupWindowNuxtEnvironmentOptions | ||
|
|
||
| return defu( | ||
| { | ||
| nuxt: { | ||
| url: nuxtEnvironmentOptions.url, | ||
| domEnvironment: nuxtEnvironmentOptions.domEnvironment, | ||
| }, | ||
| }, | ||
| JSON.parse(process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ || '{}'), | ||
| ) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Inspect Nuxt Vitest environment/plugin wiring and direct environment usages.
# Expected: every supported `environment: 'nuxt'` path should also install the options plugin;
# otherwise the helper should preserve incoming environmentOptions when the injected env var is absent.
rg -n -C3 'NuxtVitestEnvironmentOptionsPlugin|__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__|environment:\s*["'\'']nuxt["'\'']|@vitest-environment\s+nuxt'Repository: nuxt/test-utils
Length of output: 13107
🏁 Script executed:
# Check if simple fixtures use defineVitestConfig or are standalone
cat test/fixtures/simple/env-nuxt/vitest.config.tsRepository: nuxt/test-utils
Length of output: 199
🏁 Script executed:
# Check the vitest environment setup code to see when mergeSetupWindowEnvironmentOptions is called
cat -n src/environments/vitest/index.ts | head -100Repository: nuxt/test-utils
Length of output: 4011
🏁 Script executed:
# Look for other environment initialization patterns
rg -n "mergeSetupWindowEnvironmentOptions|setupWindowEnvironmentOptions" src/Repository: nuxt/test-utils
Length of output: 262
🏁 Script executed:
# Check src/config.ts to understand the plugin registration
cat -n src/config.ts | sed -n '290,360p'Repository: nuxt/test-utils
Length of output: 2961
🏁 Script executed:
# Check for any direct environment: 'nuxt' usage that might not go through defineVitestConfig
rg "environment.*nuxt" -A 2 -B 2 | grep -v "defineVitestConfig\|snapshots\|fixtures\|examples" | head -40Repository: nuxt/test-utils
Length of output: 1881
🏁 Script executed:
# Check the fixture with `@vitest-environment` comment
cat test/fixtures/simple/env-other-include/vitest.config.ts
cat test/fixtures/simple/env-other-include/test/test3.spec.tsRepository: nuxt/test-utils
Length of output: 452
🏁 Script executed:
# Check if the fixture with `@vitest-environment` nuxt is actually supposed to work
# Look at the test runner to see if env-other-include is tested
rg "env-other-include|env-other" test/ --type ts --type js | grep -v ".snap\|snapshot"Repository: nuxt/test-utils
Length of output: 392
🏁 Script executed:
# Check the resolve-config.spec.ts to understand what this test is verifying
cat -n test/unit/resolve-config.spec.ts | sed -n '1,50p'Repository: nuxt/test-utils
Length of output: 1731
🏁 Script executed:
# Look for the specific test case for env-other-include
rg -A 20 "describe.*env-other-include" test/unit/resolve-config.spec.tsRepository: nuxt/test-utils
Length of output: 599
🏁 Script executed:
# Search for any documentation or comments about per-file environment overrides
rg -C 5 "@vitest-environment" test/fixtures/ --type tsRepository: nuxt/test-utils
Length of output: 1123
🏁 Script executed:
# Let me check what happens with environmentOptions when using per-file environment overrides
# Search for how Vitest passes environmentOptions for per-file overrides
rg -C 3 "environmentOptions" src/config.ts | head -60Repository: nuxt/test-utils
Length of output: 1516
🏁 Script executed:
# Check the SetupWindowNuxtEnvironmentOptions type to see what properties might be lost
cat -n src/runtime/shared/environment.ts | head -80Repository: nuxt/test-utils
Length of output: 3286
🏁 Script executed:
# Check if there's any documentation or examples of using nuxt environment without defineVitestConfig
rg -C 3 "vitest-environment-nuxt\|environment.*nuxt" docs/ examples/ README.md 2>/dev/null | head -40Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Search for how Vitest passes environmentOptions to per-file environment overrides
# Check if there's any test that validates per-file environment behavior
rg "test3.spec.ts" test/unit/ -A 10 -B 5Repository: nuxt/test-utils
Length of output: 1921
🏁 Script executed:
# Check the NuxtVitestEnvironmentOptionsPlugin to understand how it injects the env var
cat -n src/module/plugins/options.tsRepository: nuxt/test-utils
Length of output: 1085
🏁 Script executed:
# Look for Vitest documentation or behavior about per-file environment overrides and environmentOptions
# Check if environmentOptions are passed when using per-file overrides
rg -C 5 "environmentOptions.*nuxt\|nuxt.*environmentOptions" test/fixtures/simple/env-other-include/Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if the nuxt environment can be used as a standalone package without defineVitestConfig
# Look at the vitest-environment-nuxt stub to see how it's exported
cat stubs/vitest-environment-nuxt/package.jsonRepository: nuxt/test-utils
Length of output: 439
🏁 Script executed:
# Look for any tests that actually verify per-file environment overrides with nuxt
rg "test3" test/unit/resolve-config.spec.ts -A 30 | head -50Repository: nuxt/test-utils
Length of output: 1259
🏁 Script executed:
# Check if there are integration tests that run the per-file override tests
rg -C 5 "env-other-include\|test3.spec.ts" test/unit/ --type tsRepository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check stubs/vitest-environment-nuxt/index.mjs to see if it's a standalone environment
cat stubs/vitest-environment-nuxt/index.mjsRepository: nuxt/test-utils
Length of output: 120
🏁 Script executed:
# Verify when NuxtVitestEnvironmentOptionsPlugin is called - is it guaranteed for all nuxt environment uses?
# Check if defineVitestConfig is the only entry point
rg "export.*defineVitestConfig\|NuxtVitestEnvironmentOptionsPlugin" src/ --type ts | grep -v snapRepository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if there are any code paths that use environment: 'nuxt' without going through defineVitestConfig
rg "environment.*nuxt" src/ --type ts -C 2 | grep -v snapRepository: nuxt/test-utils
Length of output: 5497
🏁 Script executed:
# Check what happens when per-file environment override is used - does Vitest pass environmentOptions?
# Look at how Vitest handles per-file environment overrides
rg -C 10 "test3" test/fixtures/simple/env-other-include/ --type tsRepository: nuxt/test-utils
Length of output: 674
🏁 Script executed:
# Verify the actual behavior: when a test uses `@vitest-environment` nuxt override,
# what environmentOptions are passed to the environment setup?
# Check if there's any code that handles per-file environmentOptions
rg "environmentOptions.*undefined\|_environmentOptions" src/environments/ -C 3Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if there are any integration tests that actually execute test3.spec.ts to verify it works
rg "test3\|env-other" test/ --type ts -C 5 | grep -v snap | head -60Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Search for any direct vitest config without defineVitestConfig that uses nuxt environment
find . -name "vitest.config.ts" -o -name "vitest.config.js" | xargs grep -l "environment.*nuxt" | head -10Repository: nuxt/test-utils
Length of output: 452
🏁 Script executed:
# Check if per-file overrides actually work - run a simple test to see the behavior
cat test/fixtures/simple/env-other-include/vitest.config.ts
cat test/fixtures/simple/env-other/vitest.config.tsRepository: nuxt/test-utils
Length of output: 383
🏁 Script executed:
# Let me check if there are any tests that actually verify the per-file environment behavior
# Look for test runs that execute env-other or env-other-include
rg "globTestSpecifications\|vitest run" test/unit/resolve-config.spec.ts -C 5 | head -40Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if there are actual runtime tests that execute the per-file override tests
find test/unit -name "*.spec.ts" | xargs grep -l "env-other\|test3"Repository: nuxt/test-utils
Length of output: 91
🏁 Script executed:
# Look for any documented examples or warnings about per-file environment behavior
rg "per-file\|per file\|@vitest-environment" . --type md --type mdx 2>/dev/nullRepository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if the NuxtVitestEnvironmentOptionsPlugin is ALWAYS run before environment setup
# Search for all places where the plugin might not be registered
rg "plugins.*push\|NuxtVitestEnvironmentOptionsPlugin" src/ --type ts -C 2Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check if per-file environment overrides receive environmentOptions from config
# Vitest documentation suggests per-file overrides don't pass config-level environmentOptions
# Let me verify the actual test behavior
cat test/unit/resolve-config.spec.ts | grep -A 20 "globTestSpecifications.*function"Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Check what globTestSpecifications actually does - does it run the tests?
rg -B 10 "async function globTestSpecifications" test/unit/resolve-config.spec.tsRepository: nuxt/test-utils
Length of output: 337
🏁 Script executed:
# Understand the actual issue: check if vitest-environment-nuxt can be used standalone
# without defineVitestConfig
cat src/config.ts | grep -A 5 "defineVitestConfig\|export.*function"Repository: nuxt/test-utils
Length of output: 1169
🏁 Script executed:
# Check if someone can install vitest-environment-nuxt and use it directly
# without the plugin being registered
rg "defineVitestConfig.*export\|export.*defineVitestConfig" src/config.ts -A 3Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# The key question: what if a user configures vitest manually like:
# { test: { environment: 'vitest-environment-nuxt', environmentOptions: {...} } }
# without using defineVitestConfig?
# Let's see if the plugin registration is guaranteed
cat -n src/config.ts | sed -n '200,250p'Repository: nuxt/test-utils
Length of output: 2120
🏁 Script executed:
# Check if vitest-environment-nuxt can be used without `@nuxt/test-utils`
# Is it published as a separate package?
rg "vitest-environment-nuxt" src/config.ts -C 3Repository: nuxt/test-utils
Length of output: 388
🏁 Script executed:
# Check if there's any documentation or examples of using vitest-environment-nuxt directly
cat stubs/vitest-environment-nuxt/package.json | grep -A 10 "exports\|main"Repository: nuxt/test-utils
Length of output: 190
🏁 Script executed:
# The critical question: Can the nuxt environment be used without defineVitestConfig?
# Look for any code that might bypass the plugin registration
rg "resolveConfig\|NuxtVitestEnvironmentOptionsPlugin" src/config.ts -C 2 | head -80Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Final verification: Is there ANY supported code path where vitest-environment-nuxt
# is used without NuxtVitestEnvironmentOptionsPlugin being registered?
# Check all the exports and entry points
cat src/config.ts | grep "^export"Repository: nuxt/test-utils
Length of output: 385
🏁 Script executed:
# Search for any documentation that might describe unsupported usage
rg "vitest-environment-nuxt\|NuxtVitestEnvironmentOptionsPlugin" README.md docs/ examples/ 2>/dev/null | head -20Repository: nuxt/test-utils
Length of output: 41
🏁 Script executed:
# Verify: When the per-file override test (test3.spec.ts) runs,
# does it actually have access to the global env var set by the plugin?
# This determines if the issue is real or theoretical
# The plugin sets: process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__
# This should be available globally during the test run
# Check if there are any actual failing tests or warnings about this
rg "test3\|env-other" test/ --type ts -A 5 | grep -i "fail\|error\|warn"Repository: nuxt/test-utils
Length of output: 41
Preserve incoming options as fallback when the serialized base config is unavailable.
Line 85 falls back to {} when process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ is unavailable. In that path, properties from _environmentOptions like nuxt.rootId, nuxt.mock, nuxt.h3Version, nuxtRuntimeConfig, and nuxtRouteRules are lost. The incoming options should be used as the fallback base instead.
While all documented entry points (defineVitestConfig and defineVitestProject) register NuxtVitestEnvironmentOptionsPlugin to inject the env var at build time, this fallback should be defensive against scenarios where the var is unavailable.
Suggested fix
function mergeSetupWindowEnvironmentOptions(
- environmentOptions: Record<string, unknown>,
+ environmentOptions: Record<string, unknown> = {},
): SetupWindowNuxtEnvironmentOptions {
const {
nuxt: nuxtEnvironmentOptions = {},
} = environmentOptions as unknown as SetupWindowNuxtEnvironmentOptions
+
+ const serializedResolvedOptions = process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__
+ const baseEnvironmentOptions = serializedResolvedOptions
+ ? JSON.parse(serializedResolvedOptions)
+ : environmentOptions
return defu(
{
nuxt: {
url: nuxtEnvironmentOptions.url,
domEnvironment: nuxtEnvironmentOptions.domEnvironment,
},
},
- JSON.parse(process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ || '{}'),
+ baseEnvironmentOptions,
)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Manually merge with base config because `@vitest-environment-options` doesn't merge by default | |
| function mergeSetupWindowEnvironmentOptions( | |
| environmentOptions: Record<string, unknown>, | |
| ): SetupWindowNuxtEnvironmentOptions { | |
| const { | |
| nuxt: nuxtEnvironmentOptions = {}, | |
| } = environmentOptions as unknown as SetupWindowNuxtEnvironmentOptions | |
| return defu( | |
| { | |
| nuxt: { | |
| url: nuxtEnvironmentOptions.url, | |
| domEnvironment: nuxtEnvironmentOptions.domEnvironment, | |
| }, | |
| }, | |
| JSON.parse(process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ || '{}'), | |
| ) | |
| } | |
| // Manually merge with base config because `@vitest-environment-options` doesn't merge by default | |
| function mergeSetupWindowEnvironmentOptions( | |
| environmentOptions: Record<string, unknown> = {}, | |
| ): SetupWindowNuxtEnvironmentOptions { | |
| const { | |
| nuxt: nuxtEnvironmentOptions = {}, | |
| } = environmentOptions as unknown as SetupWindowNuxtEnvironmentOptions | |
| const serializedResolvedOptions = process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ | |
| const baseEnvironmentOptions = serializedResolvedOptions | |
| ? JSON.parse(serializedResolvedOptions) | |
| : environmentOptions | |
| return defu( | |
| { | |
| nuxt: { | |
| url: nuxtEnvironmentOptions.url, | |
| domEnvironment: nuxtEnvironmentOptions.domEnvironment, | |
| }, | |
| }, | |
| baseEnvironmentOptions, | |
| ) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/environments/vitest/index.ts` around lines 70 - 87, The
mergeSetupWindowEnvironmentOptions function currently falls back to an empty
object when process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ is missing,
which loses incoming options; change the fallback to use the already-parsed
nuxtEnvironmentOptions (from the local variable nuxtEnvironmentOptions) as the
base for defu instead of '{}', ensuring you JSON.parse the env var when present
and pass nuxt: { url, domEnvironment, ... } merged with
JSON.parse(process.env.__NUXT_VITEST_ENVIRONMENT_RESOLVED_OPTIONS__ ||
JSON.stringify({ nuxt: nuxtEnvironmentOptions })) so properties like
nuxt.rootId, nuxt.mock, nuxt.h3Version, nuxtRuntimeConfig, and nuxtRouteRules
are preserved.
🔗 Linked issue
resolves #1541
📚 Description
Added support for
@vitest-environment-options, initially limited tourlanddomEnvironmentas they are safe to change per test file.