"""Shared fixtures for tests.""" from __future__ import annotations 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, DomainConstraint, MetricBound from physcom.models.combination import Combination @pytest.fixture def repo(tmp_path): """Fresh in-memory repository for each test.""" db_path = tmp_path / "test.db" conn = init_db(db_path) return Repository(conn) @pytest.fixture def seeded_repo(repo): """Repository pre-loaded with transport seed data.""" from physcom.seed.transport_example import load_transport_seed load_transport_seed(repo) return repo @pytest.fixture def road_vehicle(): return Entity( name="Road Vehicle", dimension="platform", description="Generic wheeled road vehicle", dependencies=[ Dependency("environment", "ground_surface", "true", None, "requires"), Dependency("environment", "gravity", "true", None, "requires"), Dependency("physical", "mass", "36000", "kg", "range_max"), Dependency("physical", "mass", "50", "kg", "range_min"), Dependency("environment", "medium", "ground", None, "requires"), ], ) @pytest.fixture def bicycle(): return Entity( name="Bicycle", dimension="platform", description="Two-wheeled human-scale vehicle", dependencies=[ Dependency("environment", "ground_surface", "true", None, "requires"), Dependency("environment", "gravity", "true", None, "requires"), Dependency("physical", "mass", "30", "kg", "range_max"), Dependency("environment", "medium", "ground", None, "requires"), ], ) @pytest.fixture def spaceship(): return Entity( name="Spaceship", dimension="platform", description="Vehicle designed for space travel", dependencies=[ Dependency("environment", "atmosphere", "vacuum_or_thin", None, "requires"), Dependency("physical", "mass", "5000", "kg", "range_min"), Dependency("environment", "medium", "space", None, "requires"), ], ) @pytest.fixture def solar_sail(): return Entity( name="Solar Sail", dimension="actuator", description="Propulsion via radiation pressure", dependencies=[ Dependency("energy", "energy_form", "radiation_pressure", None, "requires"), Dependency("environment", "atmosphere", "vacuum_or_thin", None, "requires"), Dependency("force", "power_density", "0.01", "W/kg", "provides"), Dependency("environment", "medium", "space", None, "requires"), ], ) @pytest.fixture def solar_radiation(): return Entity( name="Solar Radiation", dimension="energy_storage", description="Photon flux from a nearby star", dependencies=[ Dependency("energy", "energy_form", "radiation_pressure", None, "provides"), Dependency("physical", "mass", "0", "kg", "range_min"), ], ) @pytest.fixture def human_pedalling(): return Entity( name="Human Pedalling", dimension="actuator", description="Human-powered via pedalling", dependencies=[ Dependency("energy", "energy_form", "biological", None, "requires"), Dependency("force", "power_density", "1.5", "W/kg", "provides"), Dependency("physical", "mass", "0", "kg", "range_min"), ], ) @pytest.fixture def food_calories(): return Entity( name="Food/Calories", dimension="energy_storage", description="Metabolic energy from food", dependencies=[ Dependency("energy", "energy_form", "biological", None, "provides"), Dependency("physical", "mass", "0", "kg", "range_min"), Dependency("physical", "energy_density", "720000", "J/kg", "provides"), ], ) @pytest.fixture def nuclear_thermal_drive(): return Entity( name="Nuclear Thermal Drive", dimension="actuator", description="Nuclear fission reactor for thrust", dependencies=[ Dependency("energy", "energy_form", "nuclear_thermal", None, "requires"), Dependency("force", "power_density", "50", "W/kg", "provides"), Dependency("physical", "mass", "1500", "kg", "range_min"), ], ) @pytest.fixture def nuclear_fuel(): return Entity( name="Nuclear Fuel", dimension="energy_storage", description="Enriched uranium fuel rods", dependencies=[ Dependency("energy", "energy_form", "nuclear_thermal", None, "provides"), Dependency("physical", "mass", "500", "kg", "range_min"), Dependency("physical", "energy_density", "1800000000", "J/kg", "provides"), ], ) @pytest.fixture def hydrogen_engine(): return Entity( name="Hydrogen Combustion Engine", dimension="actuator", description="Hydrogen combustion engine", dependencies=[ Dependency("energy", "energy_form", "chemical_combustible", None, "requires"), Dependency("force", "power_density", "1500", "W/kg", "provides"), Dependency("physical", "mass", "25", "kg", "range_min"), ], ) @pytest.fixture def ice_engine(): return Entity( name="Internal Combustion Engine", dimension="actuator", description="Spark-ignition engine", dependencies=[ Dependency("energy", "energy_form", "chemical_combustible", None, "requires"), Dependency("force", "power_density", "1000", "W/kg", "provides"), Dependency("environment", "atmosphere", "standard", None, "requires"), Dependency("physical", "mass", "40", "kg", "range_min"), ], ) @pytest.fixture def gasoline(): return Entity( name="Gasoline", dimension="energy_storage", description="Liquid hydrocarbon fuel", dependencies=[ Dependency("energy", "energy_form", "chemical_combustible", None, "provides"), Dependency("physical", "mass", "10", "kg", "range_min"), Dependency("physical", "energy_density", "5400000", "J/kg", "provides"), ], ) @pytest.fixture def hydrogen(): return Entity( name="Hydrogen", dimension="energy_storage", description="Compressed hydrogen gas", dependencies=[ Dependency("energy", "energy_form", "chemical_combustible", None, "provides"), Dependency("physical", "mass", "5", "kg", "range_min"), Dependency("physical", "energy_density", "2160000", "J/kg", "provides"), ], ) @pytest.fixture def urban_domain(): return Domain( name="urban_commuting", description="Daily city travel", metric_bounds=[ MetricBound("power_density", weight=0.25, norm_min=1, norm_max=2000), MetricBound("cost_efficiency", weight=0.25, norm_min=1e-5, norm_max=2e-3, lower_is_better=True), MetricBound("safety", weight=0.25, norm_min=0.0, norm_max=1.0), 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"])], )