"""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, 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 walking(): return Entity( name="Walking", dimension="platform", description="Bipedal locomotion", dependencies=[ Dependency("environment", "ground_surface", "true", None, "requires"), Dependency("environment", "gravity", "true", None, "requires"), Dependency("physical", "mass_kg", "150", "kg", "range_max"), Dependency("force", "power_density_required_w_kg", "1", "W/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_kg", "30", "kg", "range_max"), Dependency("force", "power_density_required_w_kg", "1", "W/kg", "range_min"), 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_kg", "5000", "kg", "range_min"), Dependency("force", "power_density_required_w_kg", "500", "W/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_w_kg", "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_kg", "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_w_kg", "1.5", "W/kg", "provides"), Dependency("physical", "mass_kg", "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_kg", "0", "kg", "range_min"), Dependency("physical", "energy_density_wh_kg", "200", "Wh/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_w_kg", "50", "W/kg", "provides"), Dependency("physical", "mass_kg", "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_kg", "500", "kg", "range_min"), Dependency("physical", "energy_density_wh_kg", "500000", "Wh/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_w_kg", "1500", "W/kg", "provides"), Dependency("physical", "mass_kg", "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_w_kg", "1000", "W/kg", "provides"), Dependency("environment", "atmosphere", "standard", None, "requires"), Dependency("physical", "mass_kg", "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_kg", "10", "kg", "range_min"), Dependency("physical", "energy_density_wh_kg", "1500", "Wh/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_kg", "5", "kg", "range_min"), Dependency("physical", "energy_density_wh_kg", "600", "Wh/kg", "provides"), ], ) @pytest.fixture def urban_domain(): return Domain( name="urban_commuting", description="Daily city travel", metric_bounds=[ MetricBound("speed", weight=0.25, norm_min=5, norm_max=120), MetricBound("cost_efficiency", weight=0.25, norm_min=0.01, norm_max=2.0, 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=5, norm_max=500), ], )