CoolFace
Apppublic

blackopsrepl/quickstart-template

sourceHugging Faceapache-2.0updated 9mo agoView on Hugging Face
2likes
test_constraints.py141 linesDownload Raw Back to tests
1"""2Constraint verification tests.3 4These tests verify that each constraint behaves correctly in isolation.5Use ConstraintVerifier to test individual constraints without running the full solver.6"""7 8import pytest9from solverforge_legacy.solver.test import ConstraintVerifier10from my_quickstart.domain import Resource, Task, Schedule11from my_quickstart.constraints import define_constraints12 13 14@pytest.fixture15def constraint_verifier():16    """Create a constraint verifier for testing."""17    return ConstraintVerifier.build(18        define_constraints,19        Schedule,20        Task,21    )22 23 24# =============================================================================25# TEST DATA FIXTURES26# =============================================================================27 28@pytest.fixture29def alice():30    return Resource(name="Alice", capacity=100, skills={"python", "sql"})31 32 33@pytest.fixture34def bob():35    return Resource(name="Bob", capacity=50, skills={"java"})36 37 38# =============================================================================39# HARD CONSTRAINT TESTS40# =============================================================================41 42class TestRequiredSkill:43    """Tests for the 'Required skill missing' constraint."""44 45    def test_no_penalty_when_skill_matches(self, constraint_verifier, alice):46        """Task with matching skill should not be penalized."""47        task = Task(id="1", name="Python Task", duration=30, required_skill="python", resource=alice)48 49        constraint_verifier.verify_that("Required skill missing") \50            .given(task) \51            .penalizes_by(0)52 53    def test_penalty_when_skill_missing(self, constraint_verifier, bob):54        """Task assigned to resource without required skill should be penalized."""55        task = Task(id="1", name="Python Task", duration=30, required_skill="python", resource=bob)56 57        constraint_verifier.verify_that("Required skill missing") \58            .given(task) \59            .penalizes_by(1)60 61    def test_no_penalty_when_no_skill_required(self, constraint_verifier, alice):62        """Task with no skill requirement should not be penalized."""63        task = Task(id="1", name="Any Task", duration=30, required_skill="", resource=alice)64 65        constraint_verifier.verify_that("Required skill missing") \66            .given(task) \67            .penalizes_by(0)68 69 70class TestResourceCapacity:71    """Tests for the 'Resource capacity exceeded' constraint."""72 73    def test_no_penalty_under_capacity(self, constraint_verifier, alice):74        """Tasks under capacity should not be penalized."""75        task1 = Task(id="1", name="Task 1", duration=30, resource=alice)76        task2 = Task(id="2", name="Task 2", duration=40, resource=alice)77        # Total: 70, Capacity: 10078 79        constraint_verifier.verify_that("Resource capacity exceeded") \80            .given(task1, task2) \81            .penalizes_by(0)82 83    def test_penalty_over_capacity(self, constraint_verifier, bob):84        """Tasks exceeding capacity should be penalized by the overflow amount."""85        task1 = Task(id="1", name="Task 1", duration=30, resource=bob)86        task2 = Task(id="2", name="Task 2", duration=40, resource=bob)87        # Total: 70, Capacity: 50, Overflow: 2088 89        constraint_verifier.verify_that("Resource capacity exceeded") \90            .given(task1, task2) \91            .penalizes_by(20)92 93 94# =============================================================================95# SOFT CONSTRAINT TESTS96# =============================================================================97 98class TestMinimizeDuration:99    """Tests for the 'Minimize total duration' constraint."""100 101    def test_penalizes_by_duration(self, constraint_verifier, alice):102        """Each assigned task should be penalized by its duration."""103        task = Task(id="1", name="Task", duration=45, resource=alice)104 105        constraint_verifier.verify_that("Minimize total duration") \106            .given(task) \107            .penalizes_by(45)108 109    def test_unassigned_not_penalized(self, constraint_verifier):110        """Unassigned tasks should not be penalized."""111        task = Task(id="1", name="Task", duration=45, resource=None)112 113        constraint_verifier.verify_that("Minimize total duration") \114            .given(task) \115            .penalizes_by(0)116 117 118# =============================================================================119# INTEGRATION TEST120# =============================================================================121 122class TestFullSolution:123    """Test the full constraint set on a complete solution."""124 125    def test_feasible_solution(self, constraint_verifier, alice, bob):126        """A feasible solution should have no hard constraint violations."""127        tasks = [128            Task(id="1", name="Python Task", duration=30, required_skill="python", resource=alice),129            Task(id="2", name="SQL Task", duration=20, required_skill="sql", resource=alice),130            Task(id="3", name="Java Task", duration=40, required_skill="java", resource=bob),131        ]132 133        # Verify no hard violations134        constraint_verifier.verify_that("Required skill missing") \135            .given(*tasks) \136            .penalizes_by(0)137 138        constraint_verifier.verify_that("Resource capacity exceeded") \139            .given(*tasks) \140            .penalizes_by(0)141