mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
249 lines
9.6 KiB
Python
249 lines
9.6 KiB
Python
"""Tests for the language registry and language implementations."""
|
|
|
|
import pytest
|
|
|
|
from languages import (
|
|
UnsupportedLanguageError,
|
|
get_language,
|
|
get_supported_languages,
|
|
is_language_supported,
|
|
)
|
|
from languages.base import CodeValidator, LanguageSupport
|
|
|
|
|
|
class TestLanguageRegistry:
|
|
"""Tests for the language registry."""
|
|
|
|
def test_get_supported_languages_returns_all_registered(self):
|
|
"""Test that all registered languages are returned."""
|
|
languages = get_supported_languages()
|
|
assert "python" in languages
|
|
assert "javascript" in languages
|
|
assert "typescript" in languages
|
|
|
|
def test_is_language_supported_for_registered_languages(self):
|
|
"""Test is_language_supported for registered languages."""
|
|
assert is_language_supported("python")
|
|
assert is_language_supported("javascript")
|
|
assert is_language_supported("typescript")
|
|
|
|
def test_is_language_supported_for_aliases(self):
|
|
"""Test is_language_supported for language aliases."""
|
|
assert is_language_supported("js")
|
|
assert is_language_supported("ts")
|
|
|
|
def test_is_language_supported_false_for_unknown(self):
|
|
"""Test is_language_supported returns False for unknown languages."""
|
|
assert not is_language_supported("ruby")
|
|
assert not is_language_supported("go")
|
|
|
|
def test_get_language_returns_instance(self):
|
|
"""Test get_language returns an instance of the language class."""
|
|
py = get_language("python")
|
|
assert py is not None
|
|
assert py.language == "python"
|
|
|
|
def test_get_language_with_alias(self):
|
|
"""Test get_language works with aliases."""
|
|
js = get_language("js")
|
|
assert js.language == "javascript"
|
|
|
|
ts = get_language("ts")
|
|
assert ts.language == "typescript"
|
|
|
|
def test_get_language_case_insensitive(self):
|
|
"""Test get_language is case insensitive."""
|
|
py1 = get_language("Python")
|
|
py2 = get_language("PYTHON")
|
|
py3 = get_language("python")
|
|
assert py1.language == py2.language == py3.language == "python"
|
|
|
|
def test_get_language_raises_for_unknown(self):
|
|
"""Test get_language raises UnsupportedLanguageError for unknown languages."""
|
|
with pytest.raises(UnsupportedLanguageError) as exc_info:
|
|
get_language("ruby")
|
|
assert "ruby" in str(exc_info.value)
|
|
assert "Unsupported language" in str(exc_info.value)
|
|
|
|
|
|
class TestPythonLanguage:
|
|
"""Tests for the Python language implementation."""
|
|
|
|
@pytest.fixture
|
|
def python_lang(self):
|
|
"""Get Python language instance."""
|
|
return get_language("python")
|
|
|
|
def test_language_property(self, python_lang):
|
|
"""Test language property returns 'python'."""
|
|
assert python_lang.language == "python"
|
|
|
|
def test_get_code_block_tag(self, python_lang):
|
|
"""Test get_code_block_tag returns 'python'."""
|
|
assert python_lang.get_code_block_tag() == "python"
|
|
|
|
def test_get_validator_returns_validator(self, python_lang):
|
|
"""Test get_validator returns a CodeValidator."""
|
|
validator = python_lang.get_validator()
|
|
assert isinstance(validator, CodeValidator)
|
|
|
|
def test_validator_valid_python(self, python_lang):
|
|
"""Test validator accepts valid Python code."""
|
|
validator = python_lang.get_validator()
|
|
is_valid, error = validator.validate_syntax("def foo():\n return 42")
|
|
assert is_valid is True
|
|
assert error is None
|
|
|
|
def test_validator_invalid_python(self, python_lang):
|
|
"""Test validator rejects invalid Python code."""
|
|
validator = python_lang.get_validator()
|
|
is_valid, error = validator.validate_syntax("def foo( return 42")
|
|
assert is_valid is False
|
|
assert error is not None
|
|
|
|
def test_is_multi_context_false_for_plain_code(self, python_lang):
|
|
"""Test is_multi_context returns False for plain Python code."""
|
|
assert not python_lang.is_multi_context("def foo(): pass")
|
|
assert not python_lang.is_multi_context("```python\ndef foo(): pass\n```")
|
|
|
|
def test_is_multi_context_true_for_markdown_with_path(self, python_lang):
|
|
"""Test is_multi_context returns True for markdown with filepath."""
|
|
code = "```python:test.py\ndef foo(): pass\n```"
|
|
assert python_lang.is_multi_context(code)
|
|
|
|
def test_split_markdown_code(self, python_lang):
|
|
"""Test split_markdown_code parses markdown correctly."""
|
|
markdown = """```python:file1.py
|
|
def foo():
|
|
pass
|
|
```
|
|
|
|
```python:file2.py
|
|
def bar():
|
|
pass
|
|
```"""
|
|
result = python_lang.split_markdown_code(markdown)
|
|
assert "file1.py" in result
|
|
assert "file2.py" in result
|
|
assert "def foo():" in result["file1.py"]
|
|
assert "def bar():" in result["file2.py"]
|
|
|
|
def test_group_code(self, python_lang):
|
|
"""Test group_code formats code correctly."""
|
|
file_to_code = {
|
|
"file1.py": "def foo():\n pass",
|
|
"file2.py": "def bar():\n pass",
|
|
}
|
|
result = python_lang.group_code(file_to_code)
|
|
assert "```python:file1.py" in result
|
|
assert "```python:file2.py" in result
|
|
assert "def foo():" in result
|
|
assert "def bar():" in result
|
|
|
|
|
|
class TestJavaScriptLanguage:
|
|
"""Tests for the JavaScript language implementation."""
|
|
|
|
@pytest.fixture
|
|
def js_lang(self):
|
|
"""Get JavaScript language instance."""
|
|
return get_language("javascript")
|
|
|
|
def test_language_property(self, js_lang):
|
|
"""Test language property returns 'javascript'."""
|
|
assert js_lang.language == "javascript"
|
|
|
|
def test_get_code_block_tag(self, js_lang):
|
|
"""Test get_code_block_tag returns 'javascript'."""
|
|
assert js_lang.get_code_block_tag() == "javascript"
|
|
|
|
def test_get_validator_returns_validator(self, js_lang):
|
|
"""Test get_validator returns a CodeValidator."""
|
|
validator = js_lang.get_validator()
|
|
assert isinstance(validator, CodeValidator)
|
|
|
|
def test_is_multi_context_false_for_plain_code(self, js_lang):
|
|
"""Test is_multi_context returns False for plain JavaScript code."""
|
|
assert not js_lang.is_multi_context("function foo() {}")
|
|
assert not js_lang.is_multi_context("```javascript\nfunction foo() {}\n```")
|
|
|
|
def test_is_multi_context_true_for_markdown_with_path(self, js_lang):
|
|
"""Test is_multi_context returns True for markdown with filepath."""
|
|
code = "```javascript:test.js\nfunction foo() {}\n```"
|
|
assert js_lang.is_multi_context(code)
|
|
|
|
code_short = "```js:test.js\nfunction foo() {}\n```"
|
|
assert js_lang.is_multi_context(code_short)
|
|
|
|
def test_group_code(self, js_lang):
|
|
"""Test group_code formats code correctly."""
|
|
file_to_code = {
|
|
"file1.js": "function foo() {}",
|
|
"file2.js": "function bar() {}",
|
|
}
|
|
result = js_lang.group_code(file_to_code)
|
|
assert "```javascript:file1.js" in result
|
|
assert "```javascript:file2.js" in result
|
|
|
|
|
|
class TestTypeScriptLanguage:
|
|
"""Tests for the TypeScript language implementation."""
|
|
|
|
@pytest.fixture
|
|
def ts_lang(self):
|
|
"""Get TypeScript language instance."""
|
|
return get_language("typescript")
|
|
|
|
def test_language_property(self, ts_lang):
|
|
"""Test language property returns 'typescript'."""
|
|
assert ts_lang.language == "typescript"
|
|
|
|
def test_get_code_block_tag(self, ts_lang):
|
|
"""Test get_code_block_tag returns 'typescript'."""
|
|
assert ts_lang.get_code_block_tag() == "typescript"
|
|
|
|
def test_is_multi_context_true_for_markdown_with_path(self, ts_lang):
|
|
"""Test is_multi_context returns True for markdown with filepath."""
|
|
code = "```typescript:test.ts\nfunction foo(): void {}\n```"
|
|
assert ts_lang.is_multi_context(code)
|
|
|
|
code_short = "```ts:test.ts\nfunction foo(): void {}\n```"
|
|
assert ts_lang.is_multi_context(code_short)
|
|
|
|
def test_group_code(self, ts_lang):
|
|
"""Test group_code formats code correctly."""
|
|
file_to_code = {"file1.ts": "function foo(): void {}"}
|
|
result = ts_lang.group_code(file_to_code)
|
|
assert "```typescript:file1.ts" in result
|
|
|
|
|
|
class TestLanguageProtocolCompliance:
|
|
"""Tests to verify language implementations satisfy the protocols."""
|
|
|
|
@pytest.mark.parametrize("lang_id", ["python", "javascript", "typescript"])
|
|
def test_language_satisfies_protocol(self, lang_id):
|
|
"""Test that each language satisfies the LanguageSupport protocol."""
|
|
lang = get_language(lang_id)
|
|
assert isinstance(lang, LanguageSupport)
|
|
|
|
# Verify all protocol methods exist and return expected types
|
|
assert isinstance(lang.language, str)
|
|
assert isinstance(lang.get_code_block_tag(), str)
|
|
assert isinstance(lang.get_validator(), CodeValidator)
|
|
assert isinstance(lang.is_multi_context("test"), bool)
|
|
assert isinstance(lang.split_markdown_code("test"), dict)
|
|
assert isinstance(lang.group_code({"a.py": "code"}), str)
|
|
|
|
@pytest.mark.parametrize("lang_id", ["python", "javascript", "typescript"])
|
|
def test_validator_satisfies_protocol(self, lang_id):
|
|
"""Test that each validator satisfies the CodeValidator protocol."""
|
|
lang = get_language(lang_id)
|
|
validator = lang.get_validator()
|
|
assert isinstance(validator, CodeValidator)
|
|
|
|
# Verify validate_syntax returns expected tuple
|
|
result = validator.validate_syntax("test code")
|
|
assert isinstance(result, tuple)
|
|
assert len(result) == 2
|
|
assert isinstance(result[0], bool)
|
|
assert result[1] is None or isinstance(result[1], str)
|