Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions codeflash/languages/javascript/vitest_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,24 @@ def _is_vitest_workspace(project_root: Path) -> bool:

try:
content = vitest_config.read_text()
# Check for workspace indicators
return "workspace" in content.lower() or "defineWorkspace" in content
# Check for actual workspace configuration patterns (not just the word "workspace" in comments)
# Valid indicators:
# - defineWorkspace() function call
# - workspace: [ array config
# - separate vitest.workspace.ts/js file
import re
# Match defineWorkspace calls or workspace: property assignments
workspace_pattern = re.compile(
r'(?:^|[^a-zA-Z_])defineWorkspace\s*\(|' # defineWorkspace( function call
r'(?:^|[^a-zA-Z_])workspace\s*:\s*\[', # workspace: [ array
re.MULTILINE
)
if workspace_pattern.search(content):
return True
# Also check for separate workspace config file
if (project_root / "vitest.workspace.ts").exists() or (project_root / "vitest.workspace.js").exists():
return True
return False
except Exception:
return False

Expand Down Expand Up @@ -238,6 +254,11 @@ def _ensure_codeflash_vitest_config(project_root: Path) -> Path | None:
include: ['**/*.test.ts', '**/*.test.js', '**/*.test.tsx', '**/*.test.jsx'],
// Use forks pool so timing markers from process.stdout.write flow to parent stdout
pool: 'forks',
// Disable setupFiles to prevent relative path resolution issues in nested directories.
// Project setupFiles often use relative paths (e.g., "test/setup.ts") which resolve
// incorrectly when tests are in subdirectories (e.g., extensions/discord/test/).
// Codeflash-generated tests are self-contained and don't require project setup files.
setupFiles: [],
}},
}});
"""
Expand Down
97 changes: 97 additions & 0 deletions tests/languages/javascript/test_vitest_setupfiles_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""Test that Codeflash Vitest config properly handles setupFiles from project config.

This test verifies that when creating a custom Vitest config, setupFiles paths
are converted to absolute paths or cleared to prevent resolution issues in nested directories.
"""

from pathlib import Path
import tempfile
import pytest


def test_codeflash_vitest_config_overrides_setupfiles():
"""Test that generated config overrides setupFiles to prevent path resolution issues.

When a project has setupFiles with relative paths, and Codeflash generates tests
for functions in nested directories, those relative paths will resolve incorrectly.

The fix: Convert setupFiles paths to absolute, or disable them for generated tests.
"""
from codeflash.languages.javascript.vitest_runner import _ensure_codeflash_vitest_config

with tempfile.TemporaryDirectory() as tmpdir:
project_root = Path(tmpdir)

# Create a project with setup file
(project_root / "test").mkdir()
setup_file = project_root / "test" / "setup.ts"
setup_file.write_text("// Setup file\n")

# Create vitest config with relative setupFiles path
vitest_config = """import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
setupFiles: ["test/setup.ts"], // Relative path - will cause issues
include: ["src/**/*.test.ts"],
},
});
"""
(project_root / "vitest.config.ts").write_text(vitest_config)

# Call the function to create Codeflash config
codeflash_config_path = _ensure_codeflash_vitest_config(project_root)

# Verify the config was created
assert codeflash_config_path is not None
assert codeflash_config_path.exists()

# Read the generated config
config_content = codeflash_config_path.read_text()

# The config should either:
# 1. Set setupFiles to an empty array (disable setup files for generated tests)
# 2. OR convert the path to absolute using project root resolution

# Check that setupFiles is mentioned and handled in the merge
assert "setupFiles" in config_content, (
"Generated config must explicitly handle setupFiles to prevent "
"relative path resolution issues. Current config:\n" + config_content
)

# The config should set setupFiles to [] or to absolute paths
# This prevents the relative path from being resolved incorrectly
assert ("setupFiles: []" in config_content or
"setupFiles:" in config_content), (
"setupFiles must be explicitly set in the merged config"
)


def test_codeflash_vitest_config_without_setupfiles():
"""Test that configs without setupFiles still work correctly."""
from codeflash.languages.javascript.vitest_runner import _ensure_codeflash_vitest_config

with tempfile.TemporaryDirectory() as tmpdir:
project_root = Path(tmpdir)

# Create vitest config WITHOUT setupFiles
vitest_config = """import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
include: ["src/**/*.test.ts"],
},
});
"""
(project_root / "vitest.config.ts").write_text(vitest_config)

# Call the function to create Codeflash config
codeflash_config_path = _ensure_codeflash_vitest_config(project_root)

# Verify the config was created
assert codeflash_config_path is not None
assert codeflash_config_path.exists()

# Config should be created successfully
config_content = codeflash_config_path.read_text()
assert "mergeConfig" in config_content or "defineConfig" in config_content
Loading