linalg-zero / tests /generation /generators /test_determinant_generator.py
atomwalk12
initial commit
0dd6c2f
import json
import pytest
from linalg_zero.generator.difficulty_config import get_problem_config
from linalg_zero.generator.entropy_control import EntropyConstraints
from linalg_zero.generator.models import DifficultyCategory, Question, Task, Topic
from linalg_zero.generator.sympy.generators.determinant_generator import (
DeterminantGenerator,
)
from linalg_zero.shared.lib import determinant
class TestDeterminantGenerator:
"""Focused end-to-end tests for DeterminantGenerator."""
config = get_problem_config(DifficultyCategory.TWO_TOOL_CALLS)
def _make_generator(self, difficulty: DifficultyCategory) -> DeterminantGenerator:
from linalg_zero.generator.generation_constraints import GenerationConstraints
from linalg_zero.generator.sympy.template_engine import TemplateEngine
entropy_constraints = EntropyConstraints(entropy=1.0)
return DeterminantGenerator(
gen_constraints=GenerationConstraints(),
template_engine=TemplateEngine(),
local_index=0,
constraints={},
entropy=entropy_constraints.sample_entropy(),
difficulty_level=difficulty,
problem_type=Task.ONE_DETERMINANT,
topic=Topic.LINEAR_ALGEBRA,
)
def test_basic_generation_easy(self):
generator = self._make_generator(DifficultyCategory.ONE_TOOL_CALL)
q = generator.generate()
assert isinstance(q, Question)
assert q.is_valid
assert q.topic == Topic.LINEAR_ALGEBRA
assert q.difficulty == DifficultyCategory.ONE_TOOL_CALL
assert q.tool_calls_required == 1
assert len(q.question) > 0
assert len(q.answer) > 0
# Answer should be numeric (stringified JSON number)
value = float(q.answer)
assert isinstance(value, float)
def test_medium_and_hard_generation(self):
for difficulty in (DifficultyCategory.TWO_TOOL_CALLS, DifficultyCategory.THREE_TOOL_CALLS):
generator = self._make_generator(difficulty)
q = generator.generate()
assert q.is_valid
assert q.difficulty == difficulty
assert q.tool_calls_required == 1
value = float(q.answer)
assert isinstance(value, float)
def test_question_contains_determinant_language(self):
generator = self._make_generator(DifficultyCategory.TWO_TOOL_CALLS)
q = generator.generate()
text = q.question.lower()
assert any(kw in text for kw in ["determinant", "det(", "det ", "calculate", "compute", "find"])
def test_multiple_generations_stability(self):
generator = self._make_generator(DifficultyCategory.TWO_TOOL_CALLS)
for _ in range(10):
q = generator.generate()
assert q.is_valid
float(json.loads(q.answer))
def test_determinant_tool_function_examples(self):
# 2x2 matrix should have determinant -2
result = determinant([[1, 2], [3, 4]])
assert result == -2
assert isinstance(result, float)
# Diagonal matrix determinant is product of diagonal entries
result = determinant([[2, 0], [0, 3]])
assert result == 6
# Identity determinant is 1
result = determinant([[1, 0], [0, 1]])
assert result == 1
# 1x1 matrix
result = determinant([[5]])
assert result == 5
def test_determinant_tool_function_error_handling(self):
# Non-square matrix should raise ValueError
with pytest.raises(ValueError, match="Matrix must be square"):
determinant([[1, 2, 3], [4, 5, 6]])