Skip to content

Commit 973ebc2

Browse files
authored
Merge pull request #1979 from codeflash-ai/fix/colocated-test-path-resolution
fix: handle co-located test directories with traverse_up
2 parents 0f2c50c + eef9ff9 commit 973ebc2

2 files changed

Lines changed: 88 additions & 1 deletion

File tree

codeflash/verification/verifier.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ def generate_tests(
3434
# TODO: Sometimes this recreates the original Class definition. This overrides and messes up the original
3535
# class import. Remove the recreation of the class definition
3636
start_time = time.perf_counter()
37-
test_module_path = Path(module_name_from_file_path(test_path, test_cfg.tests_project_rootdir))
37+
# Use traverse_up=True to handle co-located __tests__ directories that may be outside
38+
# the configured tests_root (e.g., src/gateway/__tests__/ when tests_root is test/)
39+
test_module_path = Path(module_name_from_file_path(test_path, test_cfg.tests_project_rootdir, traverse_up=True))
3840

3941
# Detect module system via language support (non-None for JS/TS, None for Python)
4042
lang_support = current_language_support()
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Tests for module_name_from_file_path with co-located test directories."""
2+
3+
import pytest
4+
from pathlib import Path
5+
from codeflash.code_utils.code_utils import module_name_from_file_path
6+
7+
8+
class TestModuleNameFromFilePath:
9+
"""Test module name resolution for various directory structures."""
10+
11+
def test_file_inside_project_root(self, tmp_path: Path) -> None:
12+
"""Test normal case where file is inside project root."""
13+
project_root = tmp_path / "project"
14+
project_root.mkdir()
15+
16+
test_file = project_root / "test" / "test_foo.py"
17+
test_file.parent.mkdir()
18+
test_file.touch()
19+
20+
result = module_name_from_file_path(test_file, project_root)
21+
assert result == "test.test_foo"
22+
23+
def test_file_outside_project_root_without_traverse_up(self, tmp_path: Path) -> None:
24+
"""Test that file outside project root raises ValueError by default."""
25+
project_root = tmp_path / "project" / "test"
26+
project_root.mkdir(parents=True)
27+
28+
# File is in a sibling directory, not under project_root
29+
test_file = tmp_path / "project" / "src" / "__tests__" / "test_foo.py"
30+
test_file.parent.mkdir(parents=True)
31+
test_file.touch()
32+
33+
with pytest.raises(ValueError, match="is not within the project root"):
34+
module_name_from_file_path(test_file, project_root)
35+
36+
def test_file_outside_project_root_with_traverse_up(self, tmp_path: Path) -> None:
37+
"""Test that traverse_up=True handles files outside project root."""
38+
project_root = tmp_path / "project" / "test"
39+
project_root.mkdir(parents=True)
40+
41+
# File is in a sibling directory, not under project_root
42+
test_file = tmp_path / "project" / "src" / "__tests__" / "codeflash-generated" / "test_foo.py"
43+
test_file.parent.mkdir(parents=True)
44+
test_file.touch()
45+
46+
# With traverse_up=True, it should find a common ancestor
47+
result = module_name_from_file_path(test_file, project_root, traverse_up=True)
48+
49+
# Should return a relative path from some ancestor directory
50+
assert "test_foo" in result
51+
assert not result.startswith(".")
52+
53+
def test_colocated_test_directory_structure(self, tmp_path: Path) -> None:
54+
"""Test real-world scenario with co-located __tests__ directory.
55+
56+
This reproduces the bug from trace 7b97ddba-6ecd-42fd-b572-d40658746836:
57+
- Source: /workspace/target/src/gateway/server/ws-connection/connect-policy.ts
58+
- Tests root: /workspace/target/test
59+
- Generated test: /workspace/target/src/gateway/server/__tests__/codeflash-generated/test_xxx.test.ts
60+
61+
Without traverse_up=True, this should fail.
62+
"""
63+
project_root = tmp_path / "target"
64+
project_root.mkdir()
65+
66+
tests_root = project_root / "test"
67+
tests_root.mkdir()
68+
69+
# Source file location
70+
source_file = project_root / "src" / "gateway" / "server" / "ws-connection" / "connect-policy.ts"
71+
source_file.parent.mkdir(parents=True)
72+
source_file.touch()
73+
74+
# Generated test in co-located __tests__ directory
75+
test_file = project_root / "src" / "gateway" / "server" / "__tests__" / "codeflash-generated" / "test_resolveControlUiAuthPolicy.test.ts"
76+
test_file.parent.mkdir(parents=True)
77+
test_file.touch()
78+
79+
# This should fail WITHOUT traverse_up
80+
with pytest.raises(ValueError, match="is not within the project root"):
81+
module_name_from_file_path(test_file, tests_root)
82+
83+
# This should succeed WITH traverse_up
84+
result = module_name_from_file_path(test_file, tests_root, traverse_up=True)
85+
assert "test_resolveControlUiAuthPolicy" in result

0 commit comments

Comments
 (0)