domain-level constraints
This commit is contained in:
@@ -7,7 +7,7 @@ import pytest
|
||||
from physcom.db.schema import init_db
|
||||
from physcom.db.repository import Repository
|
||||
from physcom.models.entity import Entity, Dependency
|
||||
from physcom.models.domain import Domain, MetricBound
|
||||
from physcom.models.domain import Domain, DomainConstraint, MetricBound
|
||||
from physcom.models.combination import Combination
|
||||
|
||||
|
||||
@@ -225,4 +225,5 @@ def urban_domain():
|
||||
MetricBound("availability", weight=0.15, norm_min=0.0, norm_max=1.0),
|
||||
MetricBound("range_fuel", weight=0.10, norm_min=5000, norm_max=500000),
|
||||
],
|
||||
constraints=[DomainConstraint("medium", ["ground", "air"])],
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from physcom.engine.constraint_resolver import ConstraintResolver
|
||||
from physcom.models.combination import Combination
|
||||
from physcom.models.domain import DomainConstraint
|
||||
from physcom.models.entity import Entity, Dependency
|
||||
|
||||
|
||||
@@ -140,3 +141,22 @@ def test_energy_density_no_constraint_if_no_provider():
|
||||
result = resolver.resolve(combo)
|
||||
density_violations = [v for v in result.violations if "energy density" in v]
|
||||
assert len(density_violations) == 0
|
||||
|
||||
|
||||
def test_domain_constraint_blocks_wrong_medium(spaceship, solar_sail, solar_radiation):
|
||||
"""Spaceship (space medium) should be blocked in a ground-only domain."""
|
||||
resolver = ConstraintResolver()
|
||||
combo = Combination(entities=[spaceship, solar_sail, solar_radiation])
|
||||
constraints = [DomainConstraint("medium", ["ground", "air"])]
|
||||
result = resolver.check_domain_constraints(combo, constraints)
|
||||
assert result.status == "p1_fail"
|
||||
assert any("medium" in v for v in result.violations)
|
||||
|
||||
|
||||
def test_domain_constraint_allows_matching_medium(bicycle, human_pedalling, food_calories):
|
||||
"""Bicycle (ground medium) should pass a ground+air domain constraint."""
|
||||
resolver = ConstraintResolver()
|
||||
combo = Combination(entities=[bicycle, human_pedalling, food_calories])
|
||||
constraints = [DomainConstraint("medium", ["ground", "air"])]
|
||||
result = resolver.check_domain_constraints(combo, constraints)
|
||||
assert result.status == "valid"
|
||||
|
||||
@@ -251,10 +251,10 @@ def test_blocked_combos_have_results(seeded_repo):
|
||||
assert total_with_results == result.pass1_failed + result.pass3_scored
|
||||
|
||||
# Failed combos should have pass_reached=1 and composite_score=0.0
|
||||
failed_results = [r for r in all_results if r["combination"].status == "p1_fail"]
|
||||
# (includes both entity-blocked and domain-blocked combos)
|
||||
failed_results = [r for r in all_results if r["pass_reached"] == 1]
|
||||
assert len(failed_results) == result.pass1_failed
|
||||
for br in failed_results:
|
||||
assert br["pass_reached"] == 1
|
||||
assert br["composite_score"] == 0.0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user