Spaces:
Sleeping
Sleeping
| """ | |
| Unit tests for code validators | |
| Tests the validation modules to ensure they work correctly. | |
| """ | |
| import pytest | |
| import sys | |
| from pathlib import Path | |
| # Add project root to path | |
| project_root = Path(__file__).parent.parent.parent | |
| sys.path.insert(0, str(project_root)) | |
| from scripts.code_validators import ( | |
| SyntaxValidator, | |
| ExecutionValidator, | |
| QualityValidator, | |
| TestValidator, | |
| CompositeValidator | |
| ) | |
| class TestSyntaxValidator: | |
| """Test syntax validation""" | |
| def test_valid_syntax(self): | |
| """Test that valid Python code passes""" | |
| validator = SyntaxValidator() | |
| code = "def hello():\n print('Hello, World!')" | |
| result = validator.validate(code, "python") | |
| assert result.success is True | |
| assert result.score == 1.0 | |
| def test_invalid_syntax(self): | |
| """Test that invalid syntax is detected""" | |
| validator = SyntaxValidator() | |
| code = "def hello(\n print('Missing closing paren')" | |
| result = validator.validate(code, "python") | |
| assert result.success is False | |
| assert result.score == 0.0 | |
| assert "syntax" in result.message.lower() | |
| def test_indentation_error(self): | |
| """Test that indentation errors are detected""" | |
| validator = SyntaxValidator() | |
| code = "def hello():\nprint('Bad indent')" | |
| result = validator.validate(code, "python") | |
| assert result.success is False | |
| assert result.score == 0.0 | |
| class TestExecutionValidator: | |
| """Test execution validation""" | |
| def test_successful_execution(self): | |
| """Test that valid code executes successfully""" | |
| validator = ExecutionValidator(timeout=5) | |
| code = "print('Hello, World!')" | |
| result = validator.validate(code, "python") | |
| assert result.success is True | |
| assert result.score == 1.0 | |
| assert "Hello, World!" in result.details["stdout"] | |
| def test_runtime_error(self): | |
| """Test that runtime errors are detected""" | |
| validator = ExecutionValidator(timeout=5) | |
| code = "x = 1 / 0" # Division by zero | |
| result = validator.validate(code, "python") | |
| assert result.success is False | |
| assert result.score == 0.5 # Partial credit | |
| def test_timeout(self): | |
| """Test that infinite loops timeout""" | |
| validator = ExecutionValidator(timeout=1) | |
| code = "while True:\n pass" | |
| result = validator.validate(code, "python") | |
| assert result.success is False | |
| assert "timeout" in result.message.lower() | |
| class TestQualityValidator: | |
| """Test quality validation""" | |
| def test_high_quality_code(self): | |
| """Test that high-quality code gets good score""" | |
| validator = QualityValidator() | |
| code = '''def fibonacci(n: int) -> int: | |
| """Calculate nth Fibonacci number""" | |
| if n <= 1: | |
| return n | |
| return fibonacci(n-1) + fibonacci(n-2) | |
| ''' | |
| result = validator.validate(code, "python") | |
| assert result.success is True | |
| assert result.score > 0.5 # Should get decent score | |
| assert result.details["has_docstrings"] is True | |
| assert result.details["has_type_hints"] is True | |
| def test_low_quality_code(self): | |
| """Test that low-quality code gets lower score""" | |
| validator = QualityValidator() | |
| code = "def f(x):\n return x*2" | |
| result = validator.validate(code, "python") | |
| assert result.success is True | |
| assert result.score < 0.5 # Should get lower score | |
| assert result.details["has_docstrings"] is False | |
| class TestTestValidator: | |
| """Test the test validator""" | |
| def test_passing_tests(self): | |
| """Test that passing test cases work""" | |
| validator = TestValidator(timeout=5) | |
| code = "x = input()\nprint(int(x) * 2)" | |
| expected_behavior = { | |
| "test_cases": [ | |
| {"input": "5", "expected_output": "10"}, | |
| {"input": "3", "expected_output": "6"} | |
| ] | |
| } | |
| result = validator.validate(code, expected_behavior) | |
| assert result.success is True | |
| assert result.score == 1.0 | |
| assert result.details["passed"] == 2 | |
| assert result.details["failed"] == 0 | |
| def test_failing_tests(self): | |
| """Test that failing test cases are detected""" | |
| validator = TestValidator(timeout=5) | |
| code = "x = input()\nprint(int(x) * 3)" # Wrong multiplier | |
| expected_behavior = { | |
| "test_cases": [ | |
| {"input": "5", "expected_output": "10"} | |
| ] | |
| } | |
| result = validator.validate(code, expected_behavior) | |
| assert result.score < 1.0 | |
| assert result.details["failed"] > 0 | |
| class TestCompositeValidator: | |
| """Test composite validator""" | |
| def test_all_validators(self): | |
| """Test that composite validator runs all validators""" | |
| validator = CompositeValidator( | |
| enable_syntax=True, | |
| enable_execution=True, | |
| enable_quality=True | |
| ) | |
| code = '''def greet(name: str) -> str: | |
| """Greet someone by name""" | |
| return f"Hello, {name}!" | |
| print(greet("World")) | |
| ''' | |
| results = validator.validate(code, "python") | |
| assert "syntax" in results | |
| assert "execution" in results | |
| assert "quality" in results | |
| assert results["syntax"].success is True | |
| assert results["execution"].success is True | |
| assert results["quality"].success is True | |
| def test_overall_score(self): | |
| """Test overall score calculation""" | |
| validator = CompositeValidator() | |
| code = '''def add(a: int, b: int) -> int: | |
| """Add two numbers""" | |
| return a + b | |
| print(add(2, 3)) | |
| ''' | |
| results = validator.validate(code, "python") | |
| overall_score = validator.get_overall_score(results) | |
| assert 0.0 <= overall_score <= 1.0 | |
| assert overall_score > 0.7 # Should be high quality | |
| def test_syntax_failure_stops_execution(self): | |
| """Test that syntax failure prevents execution""" | |
| validator = CompositeValidator( | |
| enable_syntax=True, | |
| enable_execution=True | |
| ) | |
| code = "def broken(\n pass" # Syntax error | |
| results = validator.validate(code, "python") | |
| assert "syntax" in results | |
| assert results["syntax"].success is False | |
| # Execution should not run if syntax fails | |
| assert "execution" not in results | |
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v"]) | |