Add Flask web UI, Docker Compose, core engine + tests
- physcom core: CLI, 5-pass pipeline, SQLite repo, 37 tests - physcom_web: Flask app with HTMX for entity/domain/pipeline/results CRUD - Docker Compose: web + cli services sharing a named volume for the DB - Clean up local settings to use wildcard permissions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
158
tests/conftest.py
Normal file
158
tests/conftest.py
Normal file
@@ -0,0 +1,158 @@
|
||||
"""Shared fixtures for tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlite3
|
||||
|
||||
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", "force_required_watts", "75", "watts", "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", "force_required_watts", "75", "watts", "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", "force_required_watts", "1000000", "watts", "range_min"),
|
||||
Dependency("environment", "medium", "space", None, "requires"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def solar_sail():
|
||||
return Entity(
|
||||
name="Solar Sail",
|
||||
dimension="power_source",
|
||||
description="Propulsion via radiation pressure",
|
||||
dependencies=[
|
||||
Dependency("environment", "atmosphere", "vacuum_or_thin", None, "requires"),
|
||||
Dependency("force", "force_output_watts", "1", "watts", "provides"),
|
||||
Dependency("environment", "medium", "space", None, "requires"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def human_pedalling():
|
||||
return Entity(
|
||||
name="Human Pedalling",
|
||||
dimension="power_source",
|
||||
description="Human-powered via pedalling",
|
||||
dependencies=[
|
||||
Dependency("force", "force_output_watts", "75", "watts", "provides"),
|
||||
Dependency("physical", "mass_kg", "0", "kg", "range_min"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nuclear_reactor():
|
||||
return Entity(
|
||||
name="Modular Nuclear Reactor",
|
||||
dimension="power_source",
|
||||
description="Small modular nuclear fission reactor",
|
||||
dependencies=[
|
||||
Dependency("force", "force_output_watts", "50000000", "watts", "provides"),
|
||||
Dependency("physical", "mass_kg", "2000", "kg", "range_min"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hydrogen_engine():
|
||||
return Entity(
|
||||
name="Hydrogen Combustion Engine",
|
||||
dimension="power_source",
|
||||
description="Hydrogen fuel cell",
|
||||
dependencies=[
|
||||
Dependency("force", "force_output_watts", "80000", "watts", "provides"),
|
||||
Dependency("physical", "mass_kg", "30", "kg", "range_min"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ice_engine():
|
||||
return Entity(
|
||||
name="Internal Combustion Engine",
|
||||
dimension="power_source",
|
||||
description="Gas-powered engine",
|
||||
dependencies=[
|
||||
Dependency("force", "force_output_watts", "100000", "watts", "provides"),
|
||||
Dependency("environment", "atmosphere", "standard", None, "requires"),
|
||||
Dependency("physical", "mass_kg", "50", "kg", "range_min"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@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),
|
||||
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),
|
||||
],
|
||||
)
|
||||
Reference in New Issue
Block a user