mirror of
https://github.com/codeflash-ai/codeflash.git
synced 2026-05-04 18:25:17 +00:00
# Conflicts: # .claude/rules/architecture.md # .claude/rules/code-style.md # .github/workflows/claude.yml # .github/workflows/duplicate-code-detector.yml # codeflash/api/aiservice.py # codeflash/cli_cmds/console.py # codeflash/cli_cmds/logging_config.py # codeflash/code_utils/deduplicate_code.py # codeflash/discovery/discover_unit_tests.py # codeflash/languages/base.py # codeflash/languages/code_replacer.py # codeflash/languages/javascript/mocha_runner.py # codeflash/languages/javascript/support.py # codeflash/languages/python/support.py # codeflash/optimization/function_optimizer.py # codeflash/verification/parse_test_output.py # codeflash/verification/verification_utils.py # codeflash/verification/verifier.py # packages/codeflash/package-lock.json # packages/codeflash/package.json # tests/languages/javascript/test_support_dispatch.py # tests/test_codeflash_capture.py # tests/test_languages/test_javascript_test_runner.py # tests/test_multi_file_code_replacement.py
310 lines
12 KiB
Python
310 lines
12 KiB
Python
"""End-to-end integration tests for Vitest pipeline.
|
|
|
|
Tests the full optimization pipeline for Vitest projects:
|
|
- Function discovery
|
|
- Code context extraction
|
|
- Test discovery
|
|
- Test framework detection
|
|
|
|
Note: These tests require JS/TS language support to be registered.
|
|
They will be skipped in environments where only Python is supported.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from codeflash.code_utils.config_js import detect_test_runner, get_package_json_data
|
|
|
|
|
|
def skip_if_js_not_supported():
|
|
"""Skip test if JavaScript/TypeScript languages are not supported."""
|
|
try:
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
|
|
get_language_support(Language.JAVASCRIPT)
|
|
except Exception as e:
|
|
pytest.skip(f"JavaScript/TypeScript language support not available: {e}")
|
|
|
|
|
|
class TestVitestProjectDiscovery:
|
|
"""Tests for function discovery in a Vitest project."""
|
|
|
|
@pytest.fixture
|
|
def vitest_project_dir(self):
|
|
"""Get the Vitest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
vitest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_vitest"
|
|
if not vitest_dir.exists():
|
|
pytest.skip("code_to_optimize_vitest directory not found")
|
|
return vitest_dir
|
|
|
|
def test_detects_vitest_as_test_runner(self, vitest_project_dir):
|
|
"""Test that Vitest is detected as the test runner."""
|
|
package_json = vitest_project_dir / "package.json"
|
|
package_data = get_package_json_data(package_json)
|
|
|
|
assert package_data is not None
|
|
runner = detect_test_runner(vitest_project_dir, package_data)
|
|
|
|
assert runner == "vitest"
|
|
|
|
def test_discover_functions_in_fibonacci(self, vitest_project_dir):
|
|
"""Test discovering functions in fibonacci.ts."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.discovery.functions_to_optimize import find_all_functions_in_file
|
|
|
|
fib_file = vitest_project_dir / "fibonacci.ts"
|
|
if not fib_file.exists():
|
|
pytest.skip("fibonacci.ts not found")
|
|
|
|
functions = find_all_functions_in_file(fib_file)
|
|
|
|
assert fib_file in functions
|
|
func_list = functions[fib_file]
|
|
|
|
func_names = {f.function_name for f in func_list}
|
|
assert func_names == {"fibonacci", "isFibonacci", "isPerfectSquare", "fibonacciSequence"}
|
|
|
|
for func in func_list:
|
|
assert func.language == "typescript"
|
|
|
|
def test_discover_functions_in_string_utils(self, vitest_project_dir):
|
|
"""Test discovering functions in string_utils.ts."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.discovery.functions_to_optimize import find_all_functions_in_file
|
|
|
|
utils_file = vitest_project_dir / "string_utils.ts"
|
|
if not utils_file.exists():
|
|
pytest.skip("string_utils.ts not found")
|
|
|
|
functions = find_all_functions_in_file(utils_file)
|
|
|
|
assert utils_file in functions
|
|
func_list = functions[utils_file]
|
|
|
|
func_names = {f.function_name for f in func_list}
|
|
assert func_names == {"reverseString", "isPalindrome", "countVowels", "uniqueWords"}
|
|
|
|
def test_get_typescript_files(self, vitest_project_dir):
|
|
"""Test getting TypeScript files from Vitest project directory."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.discovery.functions_to_optimize import get_files_for_language
|
|
from codeflash.languages.base import Language
|
|
|
|
files = get_files_for_language(vitest_project_dir, Language.TYPESCRIPT)
|
|
|
|
ts_files = [f for f in files if f.suffix == ".ts" and "test" not in f.name]
|
|
assert len(ts_files) >= 2
|
|
|
|
root_files = [f for f in ts_files if f.parent == vitest_project_dir]
|
|
assert len(root_files) >= 2
|
|
|
|
|
|
class TestVitestCodeContext:
|
|
"""Tests for code context extraction in Vitest project."""
|
|
|
|
@pytest.fixture
|
|
def vitest_project_dir(self):
|
|
"""Get the Vitest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
vitest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_vitest"
|
|
if not vitest_dir.exists():
|
|
pytest.skip("code_to_optimize_vitest directory not found")
|
|
return vitest_dir
|
|
|
|
def test_extract_code_context_for_typescript(self, vitest_project_dir):
|
|
"""Test extracting code context for a TypeScript function."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.discovery.functions_to_optimize import find_all_functions_in_file
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
from codeflash.languages.javascript.function_optimizer import JavaScriptFunctionOptimizer
|
|
|
|
fib_file = vitest_project_dir / "fibonacci.ts"
|
|
if not fib_file.exists():
|
|
pytest.skip("fibonacci.ts not found")
|
|
|
|
functions = find_all_functions_in_file(fib_file)
|
|
func_list = functions[fib_file]
|
|
|
|
fib_func = next((f for f in func_list if f.function_name == "fibonacci"), None)
|
|
assert fib_func is not None
|
|
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
code_context = ts_support.extract_code_context(fib_func, vitest_project_dir, vitest_project_dir)
|
|
context = JavaScriptFunctionOptimizer._build_optimization_context(
|
|
code_context, fib_file, "typescript", vitest_project_dir
|
|
)
|
|
|
|
assert context.read_writable_code is not None
|
|
assert context.read_writable_code.language == "typescript"
|
|
assert len(context.read_writable_code.code_strings) > 0
|
|
|
|
code = context.read_writable_code.code_strings[0].code
|
|
expected_code = """export function fibonacci(n: number): number {
|
|
if (n <= 1) {
|
|
return n;
|
|
}
|
|
return fibonacci(n - 1) + fibonacci(n - 2);
|
|
}
|
|
"""
|
|
assert code == expected_code
|
|
|
|
|
|
class TestVitestTestDiscovery:
|
|
"""Tests for Vitest test discovery."""
|
|
|
|
@pytest.fixture
|
|
def vitest_project_dir(self):
|
|
"""Get the Vitest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
vitest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_vitest"
|
|
if not vitest_dir.exists():
|
|
pytest.skip("code_to_optimize_vitest directory not found")
|
|
return vitest_dir
|
|
|
|
def test_discover_vitest_tests(self, vitest_project_dir):
|
|
"""Test discovering Vitest tests for TypeScript functions."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import FunctionInfo, Language
|
|
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
test_root = vitest_project_dir / "tests"
|
|
|
|
if not test_root.exists():
|
|
pytest.skip("tests directory not found")
|
|
|
|
fib_file = vitest_project_dir / "fibonacci.ts"
|
|
func_info = FunctionInfo(
|
|
function_name="fibonacci", file_path=fib_file, starting_line=11, ending_line=16, language="typescript"
|
|
)
|
|
|
|
tests = ts_support.discover_tests(test_root, [func_info])
|
|
|
|
assert func_info.qualified_name in tests or len(tests) > 0
|
|
|
|
|
|
class TestVitestRunnerDispatch:
|
|
"""Tests for Vitest runner dispatch in support.py."""
|
|
|
|
@pytest.fixture
|
|
def vitest_project_dir(self):
|
|
"""Get the Vitest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
vitest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_vitest"
|
|
if not vitest_dir.exists():
|
|
pytest.skip("code_to_optimize_vitest directory not found")
|
|
return vitest_dir
|
|
|
|
def test_language_support_has_test_framework_property(self):
|
|
"""Test that JavaScriptSupport has test_framework property."""
|
|
skip_if_js_not_supported()
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
|
|
js_support = get_language_support(Language.JAVASCRIPT)
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
|
|
assert js_support.test_framework == "jest"
|
|
assert ts_support.test_framework == "jest"
|
|
|
|
def test_behavioral_tests_accepts_test_framework(self):
|
|
"""Test that run_behavioral_tests accepts test_framework parameter."""
|
|
skip_if_js_not_supported()
|
|
import inspect
|
|
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
|
|
sig = inspect.signature(ts_support.run_behavioral_tests)
|
|
params = list(sig.parameters.keys())
|
|
assert "test_framework" in params
|
|
|
|
def test_benchmarking_tests_accepts_test_framework(self):
|
|
"""Test that run_benchmarking_tests accepts test_framework parameter."""
|
|
skip_if_js_not_supported()
|
|
import inspect
|
|
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
|
|
sig = inspect.signature(ts_support.run_benchmarking_tests)
|
|
params = list(sig.parameters.keys())
|
|
assert "test_framework" in params
|
|
|
|
def test_line_profile_tests_accepts_test_framework(self):
|
|
"""Test that run_line_profile_tests accepts test_framework parameter."""
|
|
skip_if_js_not_supported()
|
|
import inspect
|
|
|
|
from codeflash.languages import get_language_support
|
|
from codeflash.languages.base import Language
|
|
|
|
ts_support = get_language_support(Language.TYPESCRIPT)
|
|
|
|
sig = inspect.signature(ts_support.run_line_profile_tests)
|
|
params = list(sig.parameters.keys())
|
|
assert "test_framework" in params
|
|
|
|
|
|
class TestVitestVsJestDetection:
|
|
"""Tests comparing Vitest and Jest project detection."""
|
|
|
|
@pytest.fixture
|
|
def jest_project_dir(self):
|
|
"""Get the Jest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
jest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_ts"
|
|
if not jest_dir.exists():
|
|
pytest.skip("code_to_optimize_ts directory not found")
|
|
return jest_dir
|
|
|
|
@pytest.fixture
|
|
def vitest_project_dir(self):
|
|
"""Get the Vitest sample project directory."""
|
|
project_root = Path(__file__).parent.parent.parent
|
|
vitest_dir = project_root / "code_to_optimize" / "js" / "code_to_optimize_vitest"
|
|
if not vitest_dir.exists():
|
|
pytest.skip("code_to_optimize_vitest directory not found")
|
|
return vitest_dir
|
|
|
|
def test_jest_detected_in_jest_project(self, jest_project_dir):
|
|
"""Test that Jest is detected in the Jest project."""
|
|
package_json = jest_project_dir / "package.json"
|
|
package_data = get_package_json_data(package_json)
|
|
|
|
assert package_data is not None
|
|
runner = detect_test_runner(jest_project_dir, package_data)
|
|
|
|
assert runner == "jest"
|
|
|
|
def test_vitest_detected_in_vitest_project(self, vitest_project_dir):
|
|
"""Test that Vitest is detected in the Vitest project."""
|
|
package_json = vitest_project_dir / "package.json"
|
|
package_data = get_package_json_data(package_json)
|
|
|
|
assert package_data is not None
|
|
runner = detect_test_runner(vitest_project_dir, package_data)
|
|
|
|
assert runner == "vitest"
|
|
|
|
def test_vitest_prioritized_over_jest(self, tmp_path):
|
|
"""Test that Vitest is prioritized when both are present."""
|
|
import json
|
|
|
|
package_json = tmp_path / "package.json"
|
|
package_json.write_text(
|
|
json.dumps({"name": "test", "devDependencies": {"vitest": "^2.0.0", "jest": "^29.0.0"}})
|
|
)
|
|
package_data = get_package_json_data(package_json)
|
|
|
|
runner = detect_test_runner(tmp_path, package_data)
|
|
|
|
assert runner == "vitest"
|