fix: resolve remaining test failures after main sync

- Fix min/max_outer_loops → pytest_min/max_loops in Java test_run_and_parse
- Update test_replacement.py for new replace_function_definitions_for_language API
- Update JavaSupport.discover_functions signature to match protocol
- Migrate _get_java_sources_root/_fix_java_test_paths to JavaFunctionOptimizer
- Fix test_java_tests_project_rootdir to use set_current_language
This commit is contained in:
Kevin Turcios 2026-03-02 15:47:23 -05:00
parent e7687f2448
commit f7fd593de3
7 changed files with 249 additions and 83 deletions

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import hashlib
import re
from collections import defaultdict
from pathlib import Path
from typing import TYPE_CHECKING, Any
@ -141,6 +142,155 @@ class JavaFunctionOptimizer(FunctionOptimizer):
preexisting_objects=set(),
)
def _get_java_sources_root(self) -> Path:
"""Get the Java sources root directory for test files.
For Java projects, tests_root might include the package path
(e.g., test/src/com/aerospike/test). We need to find the base directory
that should contain the package directories, not the tests_root itself.
This method looks for standard Java package prefixes (com, org, net, io, edu, gov)
in the tests_root path and returns everything before that prefix.
Returns:
Path to the Java sources root directory.
"""
tests_root = self.test_cfg.tests_root
parts = tests_root.parts
if tests_root.name == "src":
return tests_root
if len(parts) >= 3 and parts[-3:] == ("src", "test", "java"):
return tests_root
src_subdir = tests_root / "src"
if src_subdir.exists() and src_subdir.is_dir():
return src_subdir
maven_test_dir = tests_root / "src" / "test" / "java"
if maven_test_dir.exists() and maven_test_dir.is_dir():
return maven_test_dir
standard_package_prefixes = ("com", "org", "net", "io", "edu", "gov")
for i, part in enumerate(parts):
if part in standard_package_prefixes:
if i > 0:
return Path(*parts[:i])
for i, part in enumerate(parts):
if part == "java" and i > 0:
return Path(*parts[: i + 1])
return tests_root
def _fix_java_test_paths(
self, behavior_source: str, perf_source: str, used_paths: set[Path]
) -> tuple[Path, Path, str, str]:
"""Fix Java test file paths to match package structure.
Java requires test files to be in directories matching their package.
This method extracts the package and class from the generated tests
and returns correct paths. If the path would conflict with an already
used path, it renames the class by adding an index suffix.
Args:
behavior_source: Source code of the behavior test.
perf_source: Source code of the performance test.
used_paths: Set of already used behavior file paths.
Returns:
Tuple of (behavior_path, perf_path, modified_behavior_source, modified_perf_source)
with correct package structure and unique class names.
"""
package_match = re.search(r"^\s*package\s+([\w.]+)\s*;", behavior_source, re.MULTILINE)
package_name = package_match.group(1) if package_match else ""
# JPMS: If a test module-info.java exists, remap the package to the
# test module namespace to avoid split-package errors.
test_dir = self._get_java_sources_root()
test_module_info = test_dir / "module-info.java"
if package_name and test_module_info.exists():
mi_content = test_module_info.read_text(encoding="utf-8")
mi_match = re.search(r"module\s+([\w.]+)", mi_content)
if mi_match:
test_module_name = mi_match.group(1)
main_dir = test_dir.parent.parent / "main" / "java"
main_module_info = main_dir / "module-info.java"
if main_module_info.exists():
main_content = main_module_info.read_text(encoding="utf-8")
main_match = re.search(r"module\s+([\w.]+)", main_content)
if main_match:
main_module_name = main_match.group(1)
if package_name.startswith(main_module_name):
suffix = package_name[len(main_module_name) :]
new_package = test_module_name + suffix
old_decl = f"package {package_name};"
new_decl = f"package {new_package};"
behavior_source = behavior_source.replace(old_decl, new_decl, 1)
perf_source = perf_source.replace(old_decl, new_decl, 1)
package_name = new_package
logger.debug(f"[JPMS] Remapped package: {old_decl} -> {new_decl}")
class_match = re.search(r"^(?:public\s+)?class\s+(\w+)", behavior_source, re.MULTILINE)
behavior_class = class_match.group(1) if class_match else "GeneratedTest"
perf_class_match = re.search(r"^(?:public\s+)?class\s+(\w+)", perf_source, re.MULTILINE)
perf_class = perf_class_match.group(1) if perf_class_match else "GeneratedPerfTest"
test_dir = self._get_java_sources_root()
if package_name:
package_path = package_name.replace(".", "/")
behavior_path = test_dir / package_path / f"{behavior_class}.java"
perf_path = test_dir / package_path / f"{perf_class}.java"
else:
package_path = ""
behavior_path = test_dir / f"{behavior_class}.java"
perf_path = test_dir / f"{perf_class}.java"
modified_behavior_source = behavior_source
modified_perf_source = perf_source
if behavior_path in used_paths:
index = 2
while True:
new_behavior_class = f"{behavior_class}_{index}"
new_perf_class = f"{perf_class}_{index}"
if package_path:
new_behavior_path = test_dir / package_path / f"{new_behavior_class}.java"
new_perf_path = test_dir / package_path / f"{new_perf_class}.java"
else:
new_behavior_path = test_dir / f"{new_behavior_class}.java"
new_perf_path = test_dir / f"{new_perf_class}.java"
if new_behavior_path not in used_paths:
behavior_path = new_behavior_path
perf_path = new_perf_path
modified_behavior_source = re.sub(
rf"^((?:public\s+)?class\s+){re.escape(behavior_class)}(\b)",
rf"\g<1>{new_behavior_class}\g<2>",
behavior_source,
count=1,
flags=re.MULTILINE,
)
modified_perf_source = re.sub(
rf"^((?:public\s+)?class\s+){re.escape(perf_class)}(\b)",
rf"\g<1>{new_perf_class}\g<2>",
perf_source,
count=1,
flags=re.MULTILINE,
)
logger.debug(f"[JAVA] Renamed duplicate test class from {behavior_class} to {new_behavior_class}")
break
index += 1
behavior_path.parent.mkdir(parents=True, exist_ok=True)
perf_path.parent.mkdir(parents=True, exist_ok=True)
logger.debug(f"[JAVA] Fixed paths: behavior={behavior_path}, perf={perf_path}")
return behavior_path, perf_path, modified_behavior_source, modified_perf_source
def compare_candidate_results(
self,
baseline_results: OriginalCodeBaseline,

View file

@ -15,7 +15,7 @@ from codeflash.languages.java.comparator import compare_test_results as _compare
from codeflash.languages.java.concurrency_analyzer import analyze_function_concurrency
from codeflash.languages.java.config import detect_java_project
from codeflash.languages.java.context import extract_code_context, find_helper_functions
from codeflash.languages.java.discovery import discover_functions, discover_functions_from_source
from codeflash.languages.java.discovery import discover_functions_from_source
from codeflash.languages.java.formatter import format_java_code, normalize_java_code
from codeflash.languages.java.instrumentation import (
instrument_existing_test,
@ -151,10 +151,10 @@ class JavaSupport(LanguageSupport):
# === Discovery ===
def discover_functions(
self, file_path: Path, filter_criteria: FunctionFilterCriteria | None = None
self, source: str, file_path: Path, filter_criteria: FunctionFilterCriteria | None = None
) -> list[FunctionToOptimize]:
"""Find all optimizable functions in a Java file."""
return discover_functions(file_path, filter_criteria, self._analyzer)
"""Find all optimizable functions in Java source code."""
return discover_functions_from_source(source, file_path, filter_criteria, self._analyzer)
def discover_functions_from_source(
self, source: str, file_path: Path | None = None, filter_criteria: FunctionFilterCriteria | None = None

View file

@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch
from codeflash.discovery.discover_unit_tests import discover_unit_tests
from codeflash.languages.base import Language
from codeflash.languages.current import set_current_language
from codeflash.languages.current import reset_current_language, set_current_language
from codeflash.verification.verification_utils import TestConfig
@ -32,15 +32,18 @@ def test_java_tests_project_rootdir_set_to_tests_root(tmp_path):
mock_java_function.language = "java"
file_to_funcs = {Path("dummy.java"): [mock_java_function]}
# Mock is_python() to return False and is_java() to return True
# These are imported from codeflash.languages
with patch("codeflash.languages.is_python", return_value=False), \
patch("codeflash.languages.is_java", return_value=True), \
patch("codeflash.discovery.discover_unit_tests.discover_tests_for_language") as mock_discover:
mock_discover.return_value = ({}, 0, 0)
# Set current language to Java so is_python() returns False and
# current_language_support() returns JavaSupport with its
# adjust_test_config_for_discovery implementation
set_current_language(Language.JAVA)
try:
with patch("codeflash.discovery.discover_unit_tests.discover_tests_for_language") as mock_discover:
mock_discover.return_value = ({}, 0, 0)
# Call discover_unit_tests
discover_unit_tests(test_cfg, file_to_funcs_to_optimize=file_to_funcs)
# Call discover_unit_tests
discover_unit_tests(test_cfg, file_to_funcs_to_optimize=file_to_funcs)
finally:
reset_current_language()
# Verify that tests_project_rootdir was updated to tests_root
assert test_cfg.tests_project_rootdir == tests_root, (

View file

@ -1,14 +1,9 @@
"""Tests for Java test path handling in FunctionOptimizer."""
from pathlib import Path
from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock
import pytest
from codeflash.languages.java.test_runner import (
_extract_source_dirs_from_pom,
_path_to_class_name,
)
from codeflash.languages.java.test_runner import _extract_source_dirs_from_pom, _path_to_class_name
class TestGetJavaSourcesRoot:
@ -16,15 +11,15 @@ class TestGetJavaSourcesRoot:
def _create_mock_optimizer(self, tests_root: str):
"""Create a mock FunctionOptimizer with the given tests_root."""
from codeflash.optimization.function_optimizer import FunctionOptimizer
from codeflash.languages.java.function_optimizer import JavaFunctionOptimizer
# Create a minimal mock
mock_optimizer = MagicMock(spec=FunctionOptimizer)
mock_optimizer = MagicMock(spec=JavaFunctionOptimizer)
mock_optimizer.test_cfg = MagicMock()
mock_optimizer.test_cfg.tests_root = Path(tests_root)
# Bind the actual method to the mock
mock_optimizer._get_java_sources_root = lambda: FunctionOptimizer._get_java_sources_root(mock_optimizer)
mock_optimizer._get_java_sources_root = lambda: JavaFunctionOptimizer._get_java_sources_root(mock_optimizer)
return mock_optimizer
@ -97,15 +92,15 @@ class TestFixJavaTestPathsIntegration:
def _create_mock_optimizer(self, tests_root: str):
"""Create a mock FunctionOptimizer with the given tests_root."""
from codeflash.optimization.function_optimizer import FunctionOptimizer
from codeflash.languages.java.function_optimizer import JavaFunctionOptimizer
mock_optimizer = MagicMock(spec=FunctionOptimizer)
mock_optimizer = MagicMock(spec=JavaFunctionOptimizer)
mock_optimizer.test_cfg = MagicMock()
mock_optimizer.test_cfg.tests_root = Path(tests_root)
# Bind the actual methods
mock_optimizer._get_java_sources_root = lambda: FunctionOptimizer._get_java_sources_root(mock_optimizer)
mock_optimizer._fix_java_test_paths = lambda behavior_source, perf_source, used_paths: FunctionOptimizer._fix_java_test_paths(mock_optimizer, behavior_source, perf_source, used_paths)
mock_optimizer._get_java_sources_root = lambda: JavaFunctionOptimizer._get_java_sources_root(mock_optimizer)
mock_optimizer._fix_java_test_paths = lambda behavior_source, perf_source, used_paths: JavaFunctionOptimizer._fix_java_test_paths(mock_optimizer, behavior_source, perf_source, used_paths)
return mock_optimizer

View file

@ -10,26 +10,19 @@ from pathlib import Path
import pytest
from codeflash.languages.code_replacer import replace_function_definitions_for_language
from codeflash.languages.python.static_analysis.code_replacer import replace_function_definitions_in_module
from codeflash.models.function_types import FunctionParent
from codeflash.languages.base import Language
from codeflash.languages import current as language_current
from codeflash.languages.java.support import JavaSupport
from codeflash.models.models import CodeStringsMarkdown
@pytest.fixture
def java_language_context():
"""Set the current language to Java for the duration of the test."""
original_language = language_current._current_language
language_current._current_language = Language.JAVA
yield
language_current._current_language = original_language
def java_support():
return JavaSupport()
class TestReplaceFunctionDefinitionsInModule:
"""Tests for replace_function_definitions_in_module with Java."""
"""Tests for replace_function_definitions_for_language with Java (basic cases)."""
def test_replace_simple_method(self, tmp_path: Path, java_language_context):
def test_replace_simple_method(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a simple method in a Java class."""
java_file = tmp_path / "Calculator.java"
original_code = """public class Calculator {
@ -50,12 +43,12 @@ public class Calculator {{
optimized_code = CodeStringsMarkdown.parse_markdown_code(optimized_markdown, expected_language="java")
result = replace_function_definitions_in_module(
result = replace_function_definitions_for_language(
function_names=["add"],
optimized_code=optimized_code,
module_abspath=java_file,
preexisting_objects=set(),
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -68,7 +61,7 @@ public class Calculator {{
"""
assert new_code == expected
def test_replace_method_preserves_other_methods(self, tmp_path: Path, java_language_context):
def test_replace_method_preserves_other_methods(self, tmp_path: Path, java_support: JavaSupport):
"""Test that replacing one method preserves other methods."""
java_file = tmp_path / "Calculator.java"
original_code = """public class Calculator {
@ -105,12 +98,12 @@ public class Calculator {{
optimized_code = CodeStringsMarkdown.parse_markdown_code(optimized_markdown, expected_language="java")
result = replace_function_definitions_in_module(
result = replace_function_definitions_for_language(
function_names=["add"],
optimized_code=optimized_code,
module_abspath=java_file,
preexisting_objects=set(),
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -131,7 +124,7 @@ public class Calculator {{
"""
assert new_code == expected
def test_replace_method_with_javadoc(self, tmp_path: Path, java_language_context):
def test_replace_method_with_javadoc(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method that has Javadoc comments."""
java_file = tmp_path / "MathUtils.java"
original_code = """public class MathUtils {
@ -172,12 +165,12 @@ public class MathUtils {{
optimized_code = CodeStringsMarkdown.parse_markdown_code(optimized_markdown, expected_language="java")
result = replace_function_definitions_in_module(
result = replace_function_definitions_for_language(
function_names=["factorial"],
optimized_code=optimized_code,
module_abspath=java_file,
preexisting_objects=set(),
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -200,7 +193,7 @@ public class MathUtils {{
"""
assert new_code == expected
def test_no_change_when_code_identical(self, tmp_path: Path, java_language_context):
def test_no_change_when_code_identical(self, tmp_path: Path, java_support: JavaSupport):
"""Test that no change is made when optimized code is identical."""
java_file = tmp_path / "Identity.java"
original_code = """public class Identity {
@ -221,12 +214,12 @@ public class Identity {{
optimized_code = CodeStringsMarkdown.parse_markdown_code(optimized_markdown, expected_language="java")
result = replace_function_definitions_in_module(
result = replace_function_definitions_for_language(
function_names=["getValue"],
optimized_code=optimized_code,
module_abspath=java_file,
preexisting_objects=set(),
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is False
@ -237,7 +230,7 @@ public class Identity {{
class TestReplaceFunctionDefinitionsForLanguage:
"""Tests for replace_function_definitions_for_language with Java."""
def test_replace_static_method(self, tmp_path: Path):
def test_replace_static_method(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a static method."""
java_file = tmp_path / "Utils.java"
original_code = """public class Utils {
@ -263,6 +256,7 @@ public class Utils {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -275,7 +269,7 @@ public class Utils {{
"""
assert new_code == expected
def test_replace_method_with_annotations(self, tmp_path: Path):
def test_replace_method_with_annotations(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method with annotations."""
java_file = tmp_path / "Service.java"
original_code = """public class Service {
@ -303,6 +297,7 @@ public class Service {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -316,7 +311,7 @@ public class Service {{
"""
assert new_code == expected
def test_replace_method_in_interface(self, tmp_path: Path):
def test_replace_method_in_interface(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a default method in an interface."""
java_file = tmp_path / "Processor.java"
original_code = """public interface Processor {
@ -342,6 +337,7 @@ public interface Processor {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -354,7 +350,7 @@ public interface Processor {{
"""
assert new_code == expected
def test_replace_method_in_enum(self, tmp_path: Path):
def test_replace_method_in_enum(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method in an enum."""
java_file = tmp_path / "Color.java"
original_code = """public enum Color {
@ -384,6 +380,7 @@ public enum Color {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -398,7 +395,7 @@ public enum Color {{
"""
assert new_code == expected
def test_replace_generic_method(self, tmp_path: Path):
def test_replace_generic_method(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method with generics."""
java_file = tmp_path / "Container.java"
original_code = """import java.util.List;
@ -438,6 +435,7 @@ public class Container<T> {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -455,7 +453,7 @@ public class Container<T> {
"""
assert new_code == expected
def test_replace_method_with_throws(self, tmp_path: Path):
def test_replace_method_with_throws(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method with throws clause."""
java_file = tmp_path / "FileReader.java"
original_code = """import java.io.IOException;
@ -489,6 +487,7 @@ public class FileReader {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -509,7 +508,7 @@ public class FileReader {
class TestRealWorldOptimizationScenarios:
"""Real-world optimization scenarios with complete valid Java code."""
def test_optimize_string_concatenation(self, tmp_path: Path):
def test_optimize_string_concatenation(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimizing string concatenation to StringBuilder."""
java_file = tmp_path / "StringJoiner.java"
original_code = """public class StringJoiner {
@ -543,6 +542,7 @@ public class StringJoiner {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -559,7 +559,7 @@ public class StringJoiner {{
"""
assert new_code == expected
def test_optimize_list_iteration(self, tmp_path: Path):
def test_optimize_list_iteration(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimizing list iteration with streams."""
java_file = tmp_path / "ListProcessor.java"
original_code = """import java.util.List;
@ -593,6 +593,7 @@ public class ListProcessor {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -607,7 +608,7 @@ public class ListProcessor {
"""
assert new_code == expected
def test_optimize_null_checks(self, tmp_path: Path):
def test_optimize_null_checks(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimizing null checks with Objects utility."""
java_file = tmp_path / "NullChecker.java"
original_code = """public class NullChecker {
@ -641,6 +642,7 @@ public class NullChecker {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -653,7 +655,7 @@ public class NullChecker {{
"""
assert new_code == expected
def test_optimize_collection_creation(self, tmp_path: Path):
def test_optimize_collection_creation(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimizing collection creation with factory methods."""
java_file = tmp_path / "CollectionFactory.java"
original_code = """import java.util.ArrayList;
@ -689,6 +691,7 @@ public class CollectionFactory {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -708,7 +711,7 @@ public class CollectionFactory {
class TestMultipleClassesAndMethods:
"""Tests for files with multiple classes or multiple methods being optimized."""
def test_replace_method_in_first_class(self, tmp_path: Path):
def test_replace_method_in_first_class(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method in the first class when multiple classes exist."""
java_file = tmp_path / "MultiClass.java"
original_code = """public class Calculator {
@ -746,6 +749,7 @@ class Helper {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -764,7 +768,7 @@ class Helper {
"""
assert new_code == expected
def test_replace_multiple_methods(self, tmp_path: Path):
def test_replace_multiple_methods(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing multiple methods in the same class."""
java_file = tmp_path / "MathOps.java"
original_code = """public class MathOps {
@ -806,6 +810,7 @@ public class MathOps {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -830,7 +835,7 @@ public class MathOps {{
class TestNestedClasses:
"""Tests for nested class scenarios."""
def test_replace_method_in_nested_class(self, tmp_path: Path):
def test_replace_method_in_nested_class(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a method in a nested class."""
java_file = tmp_path / "Outer.java"
original_code = """public class Outer {
@ -868,6 +873,7 @@ public class Outer {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -890,7 +896,7 @@ public class Outer {{
class TestPreservesStructure:
"""Tests that verify code structure is preserved during replacement."""
def test_preserves_fields_and_constructors(self, tmp_path: Path):
def test_preserves_fields_and_constructors(self, tmp_path: Path, java_support: JavaSupport):
"""Test that fields and constructors are preserved."""
java_file = tmp_path / "Counter.java"
original_code = """public class Counter {
@ -935,6 +941,7 @@ public class Counter {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -959,7 +966,7 @@ public class Counter {{
class TestEdgeCases:
"""Edge cases and error handling tests."""
def test_empty_optimized_code_returns_false(self, tmp_path: Path):
def test_empty_optimized_code_returns_false(self, tmp_path: Path, java_support: JavaSupport):
"""Test that empty optimized code returns False."""
java_file = tmp_path / "Empty.java"
original_code = """public class Empty {
@ -980,13 +987,14 @@ class TestEdgeCases:
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is False
new_code = java_file.read_text(encoding="utf-8")
assert new_code == original_code
def test_function_not_found_returns_false(self, tmp_path: Path):
def test_function_not_found_returns_false(self, tmp_path: Path, java_support: JavaSupport):
"""Test that function not found returns False."""
java_file = tmp_path / "NotFound.java"
original_code = """public class NotFound {
@ -1012,11 +1020,12 @@ public class NotFound {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is False
def test_unicode_in_code(self, tmp_path: Path):
def test_unicode_in_code(self, tmp_path: Path, java_support: JavaSupport):
"""Test handling of unicode characters in code."""
java_file = tmp_path / "Unicode.java"
original_code = """public class Unicode {
@ -1042,6 +1051,7 @@ public class Unicode {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1058,7 +1068,7 @@ public class Unicode {{
class TestOptimizationWithStaticFields:
"""Tests for optimizations that add new static fields to the class."""
def test_add_static_lookup_table(self, tmp_path: Path):
def test_add_static_lookup_table(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimization that adds a static lookup table."""
java_file = tmp_path / "Buffer.java"
original_code = """public class Buffer {
@ -1097,6 +1107,7 @@ public class Buffer {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1117,7 +1128,7 @@ public class Buffer {{
"""
assert new_code == expected
def test_add_precomputed_array(self, tmp_path: Path):
def test_add_precomputed_array(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimization that adds a precomputed static array."""
java_file = tmp_path / "Encoder.java"
original_code = """public class Encoder {
@ -1154,6 +1165,7 @@ public class Encoder {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1176,7 +1188,7 @@ public class Encoder {{
"""
assert new_code == expected
def test_preserve_existing_fields(self, tmp_path: Path):
def test_preserve_existing_fields(self, tmp_path: Path, java_support: JavaSupport):
"""Test that existing fields are preserved when adding new ones."""
java_file = tmp_path / "Calculator.java"
original_code = """public class Calculator {
@ -1227,6 +1239,7 @@ public class Calculator {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1261,7 +1274,7 @@ public class Calculator {{
class TestOptimizationWithHelperMethods:
"""Tests for optimizations that add new helper methods."""
def test_add_private_helper_method(self, tmp_path: Path):
def test_add_private_helper_method(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimization that adds a private helper method."""
java_file = tmp_path / "StringUtils.java"
original_code = """public class StringUtils {
@ -1308,6 +1321,7 @@ public class StringUtils {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1330,7 +1344,7 @@ public class StringUtils {{
"""
assert new_code == expected
def test_add_multiple_helpers(self, tmp_path: Path):
def test_add_multiple_helpers(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimization that adds multiple helper methods."""
java_file = tmp_path / "MathUtils.java"
original_code = """public class MathUtils {
@ -1370,6 +1384,7 @@ public class MathUtils {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1394,7 +1409,7 @@ public class MathUtils {{
class TestOptimizationWithFieldsAndHelpers:
"""Tests for optimizations that add both static fields and helper methods."""
def test_add_field_and_helper_together(self, tmp_path: Path):
def test_add_field_and_helper_together(self, tmp_path: Path, java_support: JavaSupport):
"""Test optimization that adds both a static field and helper method."""
java_file = tmp_path / "Fibonacci.java"
original_code = """public class Fibonacci {
@ -1436,6 +1451,7 @@ public class Fibonacci {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1462,7 +1478,7 @@ public class Fibonacci {{
"""
assert new_code == expected
def test_real_world_bytes_to_hex_optimization(self, tmp_path: Path):
def test_real_world_bytes_to_hex_optimization(self, tmp_path: Path, java_support: JavaSupport):
"""Test the actual bytesToHexString optimization pattern from aerospike."""
java_file = tmp_path / "Buffer.java"
original_code = """package com.example;
@ -1521,6 +1537,7 @@ public final class Buffer {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
)
assert result is True
@ -1558,7 +1575,7 @@ public final class Buffer {
class TestOverloadedMethods:
"""Tests for handling overloaded methods (same name, different signatures)."""
def test_replace_specific_overload_by_line_number(self, tmp_path: Path):
def test_replace_specific_overload_by_line_number(self, tmp_path: Path, java_support: JavaSupport):
"""Test replacing a specific overload when multiple exist."""
java_file = tmp_path / "Buffer.java"
original_code = """public final class Buffer {
@ -1604,7 +1621,7 @@ public final class Buffer {{
optimized_code = CodeStringsMarkdown.parse_markdown_code(optimized_markdown, expected_language="java")
# Create FunctionToOptimize with line info for the 3-arg version (lines 13-18)
from codeflash.discovery.functions_to_optimize import FunctionToOptimize, FunctionParent
from codeflash.discovery.functions_to_optimize import FunctionParent, FunctionToOptimize
function_to_optimize = FunctionToOptimize(
function_name="bytesToHexString",
@ -1621,6 +1638,7 @@ public final class Buffer {{
optimized_code=optimized_code,
module_abspath=java_file,
project_root_path=tmp_path,
lang_support=java_support,
function_to_optimize=function_to_optimize,
)

View file

@ -278,8 +278,8 @@ class TestJavaRunAndParseBehavior:
test_env=test_env,
test_files=func_optimizer.test_files,
optimization_iteration=0,
min_outer_loops=1,
max_outer_loops=2,
pytest_min_loops=1,
pytest_max_loops=2,
testing_time=0.1,
)
@ -358,8 +358,8 @@ public class AdderMultiTest {
test_env=test_env,
test_files=func_optimizer.test_files,
optimization_iteration=0,
min_outer_loops=1,
max_outer_loops=2,
pytest_min_loops=1,
pytest_max_loops=2,
testing_time=0.1,
)
@ -480,8 +480,8 @@ public class PreciseWaiterTest {
test_env=test_env,
test_files=func_optimizer.test_files,
optimization_iteration=0,
min_outer_loops=2,
max_outer_loops=2,
pytest_min_loops=2,
pytest_max_loops=2,
inner_iterations=inner_iterations,
testing_time=0.0,
)

View file

@ -5,7 +5,7 @@ from pathlib import Path
import pytest
from codeflash.languages.base import Language, LanguageSupport
from codeflash.languages.java.support import JavaSupport, get_java_support
from codeflash.languages.java.support import get_java_support
class TestJavaSupportProtocol: