Skip to content

Commit 91cf6ea

Browse files
committed
fix: update tests for consolidated CST discovery behavior
Nested functions are now skipped by FunctionVisitor, and discover_functions no longer swallows parse/IO errors — callers handle them. Update test expectations accordingly.
1 parent 47f4202 commit 91cf6ea

3 files changed

Lines changed: 27 additions & 55 deletions

File tree

codeflash/discovery/functions_to_optimize.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ def _find_all_functions_via_language_support(file_path: Path) -> dict[Path, list
243243
try:
244244
lang_support = get_language_support(file_path)
245245
criteria = FunctionFilterCriteria(require_return=True)
246-
# discover_functions already returns FunctionToOptimize objects
247246
functions[file_path] = lang_support.discover_functions(file_path, criteria)
248247
except Exception as e:
249248
logger.debug(f"Failed to discover functions in {file_path}: {e}")

tests/test_languages/test_language_parity.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -440,32 +440,23 @@ def test_async_functions_discovery(self, python_support, js_support):
440440
assert js_sync.is_async is False, "JavaScript sync function should have is_async=False"
441441

442442
def test_nested_functions_discovery(self, python_support, js_support):
443-
"""Both should discover nested functions with parent info."""
443+
"""Python skips nested functions; JavaScript discovers them with parent info."""
444444
py_file = write_temp_file(NESTED_FUNCTIONS.python, ".py")
445445
js_file = write_temp_file(NESTED_FUNCTIONS.javascript, ".js")
446446

447447
py_funcs = python_support.discover_functions(py_file)
448448
js_funcs = js_support.discover_functions(js_file)
449449

450-
# Both should find 2 functions (outer and inner)
451-
assert len(py_funcs) == 2, f"Python found {len(py_funcs)}, expected 2"
452-
assert len(js_funcs) == 2, f"JavaScript found {len(js_funcs)}, expected 2"
450+
# Python skips nested functions — only outer is discovered
451+
assert len(py_funcs) == 1, f"Python found {len(py_funcs)}, expected 1"
452+
assert py_funcs[0].function_name == "outer"
453453

454-
# Check names
455-
py_names = {f.function_name for f in py_funcs}
454+
# JavaScript discovers both
455+
assert len(js_funcs) == 2, f"JavaScript found {len(js_funcs)}, expected 2"
456456
js_names = {f.function_name for f in js_funcs}
457-
458-
assert py_names == {"outer", "inner"}, f"Python found {py_names}"
459457
assert js_names == {"outer", "inner"}, f"JavaScript found {js_names}"
460458

461-
# Check parent info for inner function
462-
py_inner = next(f for f in py_funcs if f.function_name == "inner")
463459
js_inner = next(f for f in js_funcs if f.function_name == "inner")
464-
465-
assert len(py_inner.parents) >= 1, "Python inner should have parent info"
466-
assert py_inner.parents[0].name == "outer", "Python inner's parent should be outer"
467-
468-
# JavaScript nested function parent check
469460
assert len(js_inner.parents) >= 1, "JavaScript inner should have parent info"
470461
assert js_inner.parents[0].name == "outer", "JavaScript inner's parent should be outer"
471462

@@ -554,11 +545,11 @@ def test_filter_exclude_methods(self, python_support, js_support):
554545
assert js_funcs[0].function_name == "standalone"
555546

556547
def test_nonexistent_file_returns_empty(self, python_support, js_support):
557-
"""Both should return empty list for nonexistent files."""
558-
py_funcs = python_support.discover_functions(Path("/nonexistent/file.py"))
559-
js_funcs = js_support.discover_functions(Path("/nonexistent/file.js"))
548+
"""Python raises on nonexistent files; JavaScript returns empty list."""
549+
with pytest.raises(FileNotFoundError):
550+
python_support.discover_functions(Path("/nonexistent/file.py"))
560551

561-
assert py_funcs == []
552+
js_funcs = js_support.discover_functions(Path("/nonexistent/file.js"))
562553
assert js_funcs == []
563554

564555
def test_line_numbers_captured(self, python_support, js_support):

tests/test_languages/test_python_support.py

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def sync_function():
137137
assert sync_func.is_async is False
138138

139139
def test_discover_nested_functions(self, python_support):
140-
"""Test discovering nested functions."""
140+
"""Test that nested functions are excluded — only top-level and class-level functions are discovered."""
141141
with tempfile.NamedTemporaryFile(suffix=".py", mode="w", delete=False) as f:
142142
f.write("""
143143
def outer():
@@ -149,16 +149,9 @@ def inner():
149149

150150
functions = python_support.discover_functions(Path(f.name))
151151

152-
# Both outer and inner should be discovered
153-
assert len(functions) == 2
154-
names = {func.function_name for func in functions}
155-
assert names == {"outer", "inner"}
156-
157-
# Inner should have outer as parent
158-
inner = next(f for f in functions if f.function_name == "inner")
159-
assert len(inner.parents) == 1
160-
assert inner.parents[0].name == "outer"
161-
assert inner.parents[0].type == "FunctionDef"
152+
# Only outer should be discovered; inner is nested and skipped
153+
assert len(functions) == 1
154+
assert functions[0].function_name == "outer"
162155

163156
def test_discover_static_method(self, python_support):
164157
"""Test discovering static methods."""
@@ -237,19 +230,21 @@ def func2():
237230
assert func2.starting_line == 4
238231
assert func2.ending_line == 7
239232

240-
def test_discover_invalid_file_returns_empty(self, python_support):
241-
"""Test that invalid Python file returns empty list."""
233+
def test_discover_invalid_file_raises(self, python_support):
234+
"""Test that invalid Python file raises a parse error."""
235+
from libcst._exceptions import ParserSyntaxError
236+
242237
with tempfile.NamedTemporaryFile(suffix=".py", mode="w", delete=False) as f:
243238
f.write("this is not valid python {{{{")
244239
f.flush()
245240

246-
functions = python_support.discover_functions(Path(f.name))
247-
assert functions == []
241+
with pytest.raises(ParserSyntaxError):
242+
python_support.discover_functions(Path(f.name))
248243

249-
def test_discover_nonexistent_file_returns_empty(self, python_support):
250-
"""Test that nonexistent file returns empty list."""
251-
functions = python_support.discover_functions(Path("/nonexistent/file.py"))
252-
assert functions == []
244+
def test_discover_nonexistent_file_raises(self, python_support):
245+
"""Test that nonexistent file raises FileNotFoundError."""
246+
with pytest.raises(FileNotFoundError):
247+
python_support.discover_functions(Path("/nonexistent/file.py"))
253248

254249

255250
class TestReplaceFunction:
@@ -584,12 +579,7 @@ def process(value):
584579
return helper_function(value) + 1
585580
""")
586581

587-
func = FunctionToOptimize(
588-
function_name="helper_function",
589-
file_path=source_file,
590-
starting_line=1,
591-
ending_line=2,
592-
)
582+
func = FunctionToOptimize(function_name="helper_function", file_path=source_file, starting_line=1, ending_line=2)
593583

594584
refs = python_support.find_references(func, project_root=tmp_path)
595585

@@ -646,12 +636,7 @@ def test_find_references_no_references(python_support, tmp_path):
646636
return 42
647637
""")
648638

649-
func = FunctionToOptimize(
650-
function_name="isolated_function",
651-
file_path=source_file,
652-
starting_line=1,
653-
ending_line=2,
654-
)
639+
func = FunctionToOptimize(function_name="isolated_function", file_path=source_file, starting_line=1, ending_line=2)
655640

656641
refs = python_support.find_references(func, project_root=tmp_path)
657642

@@ -668,10 +653,7 @@ def test_find_references_nonexistent_function(python_support, tmp_path):
668653
""")
669654

670655
func = FunctionToOptimize(
671-
function_name="nonexistent_function",
672-
file_path=source_file,
673-
starting_line=1,
674-
ending_line=2,
656+
function_name="nonexistent_function", file_path=source_file, starting_line=1, ending_line=2
675657
)
676658

677659
refs = python_support.find_references(func, project_root=tmp_path)

0 commit comments

Comments
 (0)