Skip to content

Commit 0116a1f

Browse files
Fix Vitest setupFiles path resolution and workspace detection
**Problem:** 1. Vitest tests were failing with 'Cannot find module .../test/setup.ts' when testing functions in nested directories (e.g., extensions/discord/). 2. Root cause had two parts: - _is_vitest_workspace() was doing substring search for 'workspace', matching it even in comments, causing false positives - Custom vitest config wasn't overriding setupFiles, leaving relative paths from original config that resolved incorrectly **Solution:** 1. Improved workspace detection (vitest_runner.py:172-191): - Use regex to match actual workspace config patterns - Match defineWorkspace( function calls - Match workspace: [ property assignments - Ignore 'workspace' in comments 2. Override setupFiles in custom config (vitest_runner.py:235-242): - Set setupFiles: [] to disable project setup files - Prevents relative path resolution issues - Safe since Codeflash tests are self-contained **Testing:** Added test_vitest_setupfiles_fix.py with 2 test cases: - Verifies setupFiles is overridden in generated config - Verifies configs without setupFiles still work **Trace ID:** 161e21be-9306-4a4d-a9dc-978f65a1af7a Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 8d51e2d commit 0116a1f

2 files changed

Lines changed: 120 additions & 2 deletions

File tree

codeflash/languages/javascript/vitest_runner.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,24 @@ def _is_vitest_workspace(project_root: Path) -> bool:
170170

171171
try:
172172
content = vitest_config.read_text()
173-
# Check for workspace indicators
174-
return "workspace" in content.lower() or "defineWorkspace" in content
173+
# Check for actual workspace configuration patterns (not just the word "workspace" in comments)
174+
# Valid indicators:
175+
# - defineWorkspace() function call
176+
# - workspace: [ array config
177+
# - separate vitest.workspace.ts/js file
178+
import re
179+
# Match defineWorkspace calls or workspace: property assignments
180+
workspace_pattern = re.compile(
181+
r'(?:^|[^a-zA-Z_])defineWorkspace\s*\(|' # defineWorkspace( function call
182+
r'(?:^|[^a-zA-Z_])workspace\s*:\s*\[', # workspace: [ array
183+
re.MULTILINE
184+
)
185+
if workspace_pattern.search(content):
186+
return True
187+
# Also check for separate workspace config file
188+
if (project_root / "vitest.workspace.ts").exists() or (project_root / "vitest.workspace.js").exists():
189+
return True
190+
return False
175191
except Exception:
176192
return False
177193

@@ -238,6 +254,11 @@ def _ensure_codeflash_vitest_config(project_root: Path) -> Path | None:
238254
include: ['**/*.test.ts', '**/*.test.js', '**/*.test.tsx', '**/*.test.jsx'],
239255
// Use forks pool so timing markers from process.stdout.write flow to parent stdout
240256
pool: 'forks',
257+
// Disable setupFiles to prevent relative path resolution issues in nested directories.
258+
// Project setupFiles often use relative paths (e.g., "test/setup.ts") which resolve
259+
// incorrectly when tests are in subdirectories (e.g., extensions/discord/test/).
260+
// Codeflash-generated tests are self-contained and don't require project setup files.
261+
setupFiles: [],
241262
}},
242263
}});
243264
"""
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""Test that Codeflash Vitest config properly handles setupFiles from project config.
2+
3+
This test verifies that when creating a custom Vitest config, setupFiles paths
4+
are converted to absolute paths or cleared to prevent resolution issues in nested directories.
5+
"""
6+
7+
from pathlib import Path
8+
import tempfile
9+
import pytest
10+
11+
12+
def test_codeflash_vitest_config_overrides_setupfiles():
13+
"""Test that generated config overrides setupFiles to prevent path resolution issues.
14+
15+
When a project has setupFiles with relative paths, and Codeflash generates tests
16+
for functions in nested directories, those relative paths will resolve incorrectly.
17+
18+
The fix: Convert setupFiles paths to absolute, or disable them for generated tests.
19+
"""
20+
from codeflash.languages.javascript.vitest_runner import _ensure_codeflash_vitest_config
21+
22+
with tempfile.TemporaryDirectory() as tmpdir:
23+
project_root = Path(tmpdir)
24+
25+
# Create a project with setup file
26+
(project_root / "test").mkdir()
27+
setup_file = project_root / "test" / "setup.ts"
28+
setup_file.write_text("// Setup file\n")
29+
30+
# Create vitest config with relative setupFiles path
31+
vitest_config = """import { defineConfig } from 'vitest/config';
32+
33+
export default defineConfig({
34+
test: {
35+
setupFiles: ["test/setup.ts"], // Relative path - will cause issues
36+
include: ["src/**/*.test.ts"],
37+
},
38+
});
39+
"""
40+
(project_root / "vitest.config.ts").write_text(vitest_config)
41+
42+
# Call the function to create Codeflash config
43+
codeflash_config_path = _ensure_codeflash_vitest_config(project_root)
44+
45+
# Verify the config was created
46+
assert codeflash_config_path is not None
47+
assert codeflash_config_path.exists()
48+
49+
# Read the generated config
50+
config_content = codeflash_config_path.read_text()
51+
52+
# The config should either:
53+
# 1. Set setupFiles to an empty array (disable setup files for generated tests)
54+
# 2. OR convert the path to absolute using project root resolution
55+
56+
# Check that setupFiles is mentioned and handled in the merge
57+
assert "setupFiles" in config_content, (
58+
"Generated config must explicitly handle setupFiles to prevent "
59+
"relative path resolution issues. Current config:\n" + config_content
60+
)
61+
62+
# The config should set setupFiles to [] or to absolute paths
63+
# This prevents the relative path from being resolved incorrectly
64+
assert ("setupFiles: []" in config_content or
65+
"setupFiles:" in config_content), (
66+
"setupFiles must be explicitly set in the merged config"
67+
)
68+
69+
70+
def test_codeflash_vitest_config_without_setupfiles():
71+
"""Test that configs without setupFiles still work correctly."""
72+
from codeflash.languages.javascript.vitest_runner import _ensure_codeflash_vitest_config
73+
74+
with tempfile.TemporaryDirectory() as tmpdir:
75+
project_root = Path(tmpdir)
76+
77+
# Create vitest config WITHOUT setupFiles
78+
vitest_config = """import { defineConfig } from 'vitest/config';
79+
80+
export default defineConfig({
81+
test: {
82+
include: ["src/**/*.test.ts"],
83+
},
84+
});
85+
"""
86+
(project_root / "vitest.config.ts").write_text(vitest_config)
87+
88+
# Call the function to create Codeflash config
89+
codeflash_config_path = _ensure_codeflash_vitest_config(project_root)
90+
91+
# Verify the config was created
92+
assert codeflash_config_path is not None
93+
assert codeflash_config_path.exists()
94+
95+
# Config should be created successfully
96+
config_content = codeflash_config_path.read_text()
97+
assert "mergeConfig" in config_content or "defineConfig" in config_content

0 commit comments

Comments
 (0)