diff --git a/codeflash/verification/verifier.py b/codeflash/verification/verifier.py index c43bf500d..9751ebc11 100644 --- a/codeflash/verification/verifier.py +++ b/codeflash/verification/verifier.py @@ -34,9 +34,20 @@ def generate_tests( # TODO: Sometimes this recreates the original Class definition. This overrides and messes up the original # class import. Remove the recreation of the class definition start_time = time.perf_counter() - # Use traverse_up=True to handle co-located __tests__ directories that may be outside - # the configured tests_root (e.g., src/gateway/__tests__/ when tests_root is test/) - test_module_path = Path(module_name_from_file_path(test_path, test_cfg.tests_project_rootdir, traverse_up=True)) + + # Compute test module path - handle case where test file is outside tests_project_rootdir + # (e.g., JavaScript/TypeScript tests generated in __tests__ subdirectories adjacent to source files) + # Similar to javascript/parse.py:330-333 fallback pattern + try: + # Use traverse_up=True to handle co-located __tests__ directories that may be outside + # the configured tests_root (e.g., src/gateway/__tests__/ when tests_root is test/) + test_module_path = Path(module_name_from_file_path(test_path, test_cfg.tests_project_rootdir, traverse_up=True)) + except ValueError: + # Test file is not within tests_project_rootdir - use just the filename + # This can happen for JavaScript/TypeScript when get_test_dir_for_source() + # places tests adjacent to source files (e.g., in src/foo/__tests__/) + # instead of within the configured tests_root + test_module_path = Path(test_path.name) # Detect module system via language support (non-None for JS/TS, None for Python) lang_support = current_language_support() diff --git a/tests/verification/test_verifier_path_handling.py b/tests/verification/test_verifier_path_handling.py new file mode 100644 index 000000000..2b5ffb772 --- /dev/null +++ b/tests/verification/test_verifier_path_handling.py @@ -0,0 +1,55 @@ +"""Test that verifier.py handles test files outside tests_project_rootdir gracefully. + +This tests the fix for the bug where JavaScript/TypeScript test files generated +in __tests__ subdirectories (adjacent to source files) caused ValueError when +verifier.py tried to compute their module path relative to tests_project_rootdir. + +Trace ID: 84f5467f-8acf-427f-b468-02cb3342097e +""" + +from pathlib import Path + +import pytest + +from codeflash.code_utils.code_utils import module_name_from_file_path + + +class TestVerifierPathHandling: + """Test path handling in verifier.py for test files outside tests_root.""" + + def test_module_name_from_file_path_raises_valueerror_when_outside_root(self) -> None: + """Verify that module_name_from_file_path raises ValueError when file is outside root. + + This is the current behavior that causes the bug in verifier.py line 37. + + Scenario: + - JavaScript support generates test at: /workspace/target/src/gateway/server/__tests__/codeflash-generated/test_foo.test.ts + - tests_project_rootdir is: /workspace/target/test + - Test file is NOT within tests_root, so relative_to() fails + """ + test_path = Path("/workspace/target/src/gateway/server/__tests__/codeflash-generated/test_foo.test.ts") + tests_root = Path("/workspace/target/test") + + # This should raise ValueError before the fix + with pytest.raises(ValueError, match="is not within the project root"): + module_name_from_file_path(test_path, tests_root) + + def test_module_name_from_file_path_with_fallback_succeeds(self) -> None: + """Test that adding a fallback (try-except) allows graceful handling. + + This is the pattern used in javascript/parse.py:330-333 that should + also be applied to verifier.py:37. + """ + test_path = Path("/workspace/target/src/gateway/server/__tests__/codeflash-generated/test_foo.test.ts") + tests_root = Path("/workspace/target/test") + + # Simulate the fix: try-except with fallback to filename + try: + test_module_path = module_name_from_file_path(test_path, tests_root) + except ValueError: + # Fallback: use just the filename (or relative path from parent) + # This is what javascript/parse.py does + test_module_path = test_path.name + + # After fallback, we should have a valid path + assert test_module_path == "test_foo.test.ts"