codeflash/tests/test_code_replacer_matching.py
Mohamed Ashraf fa9d32f1c4 Merge branch 'main' into omni-java
Resolve 7 merge conflicts from main's modular refactoring + JS improvements:

- aiservice.py: combine multi-language metadata (omni-java) with main's structure
- cmd_init.py: adopt main's modular split (init_config, init_auth, github_workflow) + add Java import
- code_replacer.py: main's clean early-return style + omni-java's non-Python single-block fallback
- version.py, test_support_dispatch.py, test_javascript_test_runner.py: take main's versions
- uv.lock: regenerated

Port Java into main's modular structure:
- Fix init_java.py lazy imports to point to new modules (init_config, init_auth, github_workflow)
- Add Java workflow support to github_workflow.py (detection, template, customization)
- Fix broken Java imports (function_optimizer, line_profiler) after main's module moves

Add safety tests for merge-critical functions:
- test_add_language_metadata.py: 10 tests covering per-language payload correctness
- test_code_replacer_matching.py: 8 tests covering fallback chain

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:15:19 +00:00

84 lines
3.9 KiB
Python

"""Safety tests for get_optimized_code_for_module() fallback chain.
These tests verify the matching logic that maps AI-generated code blocks
to the correct source file, including all fallback strategies.
"""
from __future__ import annotations
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from codeflash.languages.code_replacer import get_optimized_code_for_module
def _make_optimized_code(file_to_code: dict[str, str]) -> MagicMock:
"""Create a mock CodeStringsMarkdown with a given file_to_path mapping."""
mock = MagicMock()
mock.file_to_path.return_value = file_to_code
return mock
class TestGetOptimizedCodeForModule:
"""Test the fallback chain in get_optimized_code_for_module."""
def test_exact_path_match(self) -> None:
"""When the relative path matches exactly, return that code."""
code = _make_optimized_code({"src/main/java/com/example/Foo.java": "class Foo {}"})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
assert result == "class Foo {}"
def test_none_key_fallback(self) -> None:
"""When there's a single code block with 'None' key, use it."""
code = _make_optimized_code({"None": "class Foo { optimized }"})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
assert result == "class Foo { optimized }"
def test_basename_match(self) -> None:
"""When the AI returns just 'Algorithms.java', match by basename."""
code = _make_optimized_code({"Algorithms.java": "class Algorithms { fast }"})
result = get_optimized_code_for_module(
Path("src/main/java/com/example/Algorithms.java"), code
)
assert result == "class Algorithms { fast }"
def test_basename_match_with_different_prefix(self) -> None:
"""Basename match should work even with a different directory prefix."""
code = _make_optimized_code({"com/other/Foo.java": "class Foo { v2 }"})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
assert result == "class Foo { v2 }"
@patch("codeflash.languages.current.is_python", return_value=False)
def test_single_block_fallback_non_python(self, _mock: object) -> None:
"""For non-Python, a single code block with wrong path should still match."""
code = _make_optimized_code({"wrong/path/Bar.java": "class Bar { fast }"})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
assert result == "class Bar { fast }"
@patch("codeflash.languages.current.is_python", return_value=True)
def test_single_block_fallback_python_does_not_match(self, _mock: object) -> None:
"""For Python, a single code block with wrong path should NOT match."""
code = _make_optimized_code({"wrong/path/bar.py": "def bar(): pass"})
result = get_optimized_code_for_module(Path("src/foo.py"), code)
assert result == ""
def test_no_match_returns_empty(self) -> None:
"""When multiple blocks exist and none match, return empty string."""
code = _make_optimized_code({
"other/File1.java": "class File1 {}",
"other/File2.java": "class File2 {}",
})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
assert result == ""
def test_none_key_with_multiple_blocks_no_match(self) -> None:
"""When there are multiple blocks including 'None', don't use None fallback."""
code = _make_optimized_code({
"None": "class Default {}",
"other/File.java": "class File {}",
})
result = get_optimized_code_for_module(Path("src/main/java/com/example/Foo.java"), code)
# With multiple blocks, the None-key fallback should NOT trigger
assert result == ""