""" 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"])