22
33import json
44from pathlib import Path
5+ from unittest .mock import patch
56
67import tomlkit
78
8- from codeflash .code_utils .config_parser import LanguageConfig , find_all_config_files
9+ from codeflash .code_utils .config_parser import find_all_config_files
910from codeflash .languages .language_enum import Language
1011
1112
@@ -22,19 +23,29 @@ def test_finds_pyproject_toml_with_codeflash_section(self, tmp_path: Path, monke
2223 assert result [0 ].language == Language .PYTHON
2324 assert result [0 ].config_path == tmp_path / "pyproject.toml"
2425
25- def test_finds_codeflash_toml (self , tmp_path : Path , monkeypatch ) -> None :
26- write_toml (tmp_path / "codeflash.toml" , {"tool" : {"codeflash" : {"module-root" : "src/main/java" }}})
26+ def test_finds_java_via_build_tool_detection (self , tmp_path : Path , monkeypatch ) -> None :
27+ java_config = {"language" : "java" , "module_root" : str (tmp_path / "src/main/java" )}
28+ (tmp_path / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
2729 monkeypatch .chdir (tmp_path )
28- result = find_all_config_files ()
30+ with patch (
31+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
32+ return_value = java_config ,
33+ ):
34+ result = find_all_config_files ()
2935 assert len (result ) == 1
3036 assert result [0 ].language == Language .JAVA
31- assert result [0 ].config_path == tmp_path / "codeflash.toml"
37+ assert result [0 ].config_path == tmp_path
3238
33- def test_finds_multiple_configs (self , tmp_path : Path , monkeypatch ) -> None :
39+ def test_finds_multiple_configs_python_and_java (self , tmp_path : Path , monkeypatch ) -> None :
3440 write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
35- write_toml (tmp_path / "codeflash.toml" , {"tool" : {"codeflash" : {"module-root" : "src/main/java" }}})
41+ java_config = {"language" : "java" , "module_root" : str (tmp_path / "src/main/java" )}
42+ (tmp_path / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
3643 monkeypatch .chdir (tmp_path )
37- result = find_all_config_files ()
44+ with patch (
45+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
46+ return_value = java_config ,
47+ ):
48+ result = find_all_config_files ()
3849 assert len (result ) == 2
3950 languages = {r .language for r in result }
4051 assert languages == {Language .PYTHON , Language .JAVA }
@@ -49,9 +60,14 @@ def test_finds_config_in_parent_directory(self, tmp_path: Path, monkeypatch) ->
4960 write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
5061 subdir = tmp_path / "subproject"
5162 subdir .mkdir ()
52- write_toml (subdir / "codeflash.toml" , {"tool" : {"codeflash" : {"module-root" : "src/main/java" }}})
63+ java_config = {"language" : "java" , "module_root" : str (subdir / "src/main/java" )}
64+ (subdir / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
5365 monkeypatch .chdir (subdir )
54- result = find_all_config_files ()
66+ with patch (
67+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
68+ return_value = java_config ,
69+ ):
70+ result = find_all_config_files ()
5571 assert len (result ) == 2
5672 languages = {r .language for r in result }
5773 assert languages == {Language .PYTHON , Language .JAVA }
@@ -78,27 +94,111 @@ def test_finds_package_json_with_codeflash_section(self, tmp_path: Path, monkeyp
7894
7995 def test_finds_all_three_config_types (self , tmp_path : Path , monkeypatch ) -> None :
8096 write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
81- write_toml (tmp_path / "codeflash.toml" , {"tool" : {"codeflash" : {"module-root" : "src/main/java" }}})
8297 pkg = {"codeflash" : {"moduleRoot" : "src" }}
8398 (tmp_path / "package.json" ).write_text (json .dumps (pkg ), encoding = "utf-8" )
99+ java_config = {"language" : "java" , "module_root" : str (tmp_path / "src/main/java" )}
100+ (tmp_path / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
84101 monkeypatch .chdir (tmp_path )
85- result = find_all_config_files ()
102+ with patch (
103+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
104+ return_value = java_config ,
105+ ):
106+ result = find_all_config_files ()
86107 assert len (result ) == 3
87108 languages = {r .language for r in result }
88109 assert languages == {Language .PYTHON , Language .JAVA , Language .JAVASCRIPT }
89110
90- def test_malformed_toml_skipped (self , tmp_path : Path , monkeypatch ) -> None :
91- (tmp_path / "codeflash.toml" ).write_text ("not valid [toml" , encoding = "utf-8" )
111+ def test_no_java_when_no_build_file_exists (self , tmp_path : Path , monkeypatch ) -> None :
92112 monkeypatch .chdir (tmp_path )
93113 result = find_all_config_files ()
94114 assert len (result ) == 0
95115
96116 def test_missing_codeflash_section_skipped (self , tmp_path : Path , monkeypatch ) -> None :
97- write_toml (tmp_path / "codeflash.toml" , {"tool" : {"other" : {"key" : "value" }}})
117+ write_toml (tmp_path / "pyproject.toml" , {"tool" : {"other" : {"key" : "value" }}})
118+ monkeypatch .chdir (tmp_path )
119+ result = find_all_config_files ()
120+ assert len (result ) == 0
121+
122+ def test_finds_java_in_subdirectory (self , tmp_path : Path , monkeypatch ) -> None :
123+ """Monorepo: Java project in a subdirectory is discovered from the repo root."""
124+ write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
125+ java_dir = tmp_path / "java"
126+ java_dir .mkdir ()
127+ (java_dir / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
128+ java_config = {"language" : "java" , "module_root" : str (java_dir / "src/main/java" )}
129+ monkeypatch .chdir (tmp_path )
130+ with patch (
131+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
132+ return_value = java_config ,
133+ ):
134+ result = find_all_config_files ()
135+ assert len (result ) == 2
136+ languages = {r .language for r in result }
137+ assert languages == {Language .PYTHON , Language .JAVA }
138+ java_result = next (r for r in result if r .language == Language .JAVA )
139+ assert java_result .config_path == java_dir
140+
141+ def test_finds_js_in_subdirectory (self , tmp_path : Path , monkeypatch ) -> None :
142+ """Monorepo: JS project in a subdirectory is discovered from the repo root."""
143+ write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
144+ js_dir = tmp_path / "js"
145+ js_dir .mkdir ()
146+ pkg = {"codeflash" : {"moduleRoot" : "src" }}
147+ (js_dir / "package.json" ).write_text (json .dumps (pkg ), encoding = "utf-8" )
148+ monkeypatch .chdir (tmp_path )
149+ result = find_all_config_files ()
150+ assert len (result ) == 2
151+ languages = {r .language for r in result }
152+ assert languages == {Language .PYTHON , Language .JAVASCRIPT }
153+
154+ def test_finds_all_three_in_monorepo_subdirs (self , tmp_path : Path , monkeypatch ) -> None :
155+ """Monorepo: Python at root, Java and JS in subdirectories."""
156+ write_toml (tmp_path / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "src" }}})
157+ java_dir = tmp_path / "java"
158+ java_dir .mkdir ()
159+ (java_dir / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
160+ java_config = {"language" : "java" , "module_root" : str (java_dir / "src/main/java" )}
161+ js_dir = tmp_path / "js"
162+ js_dir .mkdir ()
163+ pkg = {"codeflash" : {"moduleRoot" : "src" }}
164+ (js_dir / "package.json" ).write_text (json .dumps (pkg ), encoding = "utf-8" )
165+ monkeypatch .chdir (tmp_path )
166+ with patch (
167+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
168+ return_value = java_config ,
169+ ):
170+ result = find_all_config_files ()
171+ assert len (result ) == 3
172+ languages = {r .language for r in result }
173+ assert languages == {Language .PYTHON , Language .JAVA , Language .JAVASCRIPT }
174+
175+ def test_skips_hidden_and_build_subdirs (self , tmp_path : Path , monkeypatch ) -> None :
176+ """Subdirectory scan skips .git, node_modules, target, etc."""
177+ for name in [".git" , "node_modules" , "target" , "build" , "__pycache__" ]:
178+ d = tmp_path / name
179+ d .mkdir ()
180+ write_toml (d / "pyproject.toml" , {"tool" : {"codeflash" : {"module-root" : "." }}})
98181 monkeypatch .chdir (tmp_path )
99182 result = find_all_config_files ()
100183 assert len (result ) == 0
101184
185+ def test_root_config_wins_over_subdir (self , tmp_path : Path , monkeypatch ) -> None :
186+ """Config at CWD (found during upward walk) takes precedence over subdirectory."""
187+ (tmp_path / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
188+ java_dir = tmp_path / "java"
189+ java_dir .mkdir ()
190+ (java_dir / "pom.xml" ).write_text ("<project/>" , encoding = "utf-8" )
191+ java_config = {"language" : "java" , "module_root" : str (tmp_path / "src/main/java" )}
192+ monkeypatch .chdir (tmp_path )
193+ with patch (
194+ "codeflash.code_utils.config_parser._parse_java_config_for_dir" ,
195+ return_value = java_config ,
196+ ):
197+ result = find_all_config_files ()
198+ java_results = [r for r in result if r .language == Language .JAVA ]
199+ assert len (java_results ) == 1
200+ assert java_results [0 ].config_path == tmp_path
201+
102202
103203def test_find_all_functions_uses_registry_not_singleton () -> None :
104204 """DISC-04: Verify find_all_functions_in_file uses per-file registry lookup."""
0 commit comments