Spaces:
Sleeping
Sleeping
File size: 6,966 Bytes
f9adcbf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
"""
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"])
|