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:
88
tests/test_repository.py
Normal file
88
tests/test_repository.py
Normal file
@@ -0,0 +1,88 @@
|
||||
"""Tests for the database repository."""
|
||||
|
||||
from physcom.models.entity import Entity, Dependency
|
||||
from physcom.models.domain import Domain, MetricBound
|
||||
|
||||
|
||||
def test_ensure_dimension(repo):
|
||||
dim_id = repo.ensure_dimension("platform", "Vehicle platforms")
|
||||
assert dim_id > 0
|
||||
# Idempotent
|
||||
dim_id2 = repo.ensure_dimension("platform", "Vehicle platforms")
|
||||
assert dim_id == dim_id2
|
||||
|
||||
|
||||
def test_add_and_get_entity(repo):
|
||||
entity = Entity(
|
||||
name="TestBike",
|
||||
dimension="platform",
|
||||
description="A test bicycle",
|
||||
dependencies=[
|
||||
Dependency("environment", "ground_surface", "true", None, "requires"),
|
||||
],
|
||||
)
|
||||
saved = repo.add_entity(entity)
|
||||
assert saved.id is not None
|
||||
|
||||
loaded = repo.get_entity(saved.id)
|
||||
assert loaded is not None
|
||||
assert loaded.name == "TestBike"
|
||||
assert loaded.dimension == "platform"
|
||||
assert len(loaded.dependencies) == 1
|
||||
assert loaded.dependencies[0].key == "ground_surface"
|
||||
|
||||
|
||||
def test_list_entities_by_dimension(repo):
|
||||
repo.add_entity(Entity(name="A", dimension="platform"))
|
||||
repo.add_entity(Entity(name="B", dimension="platform"))
|
||||
repo.add_entity(Entity(name="C", dimension="power_source"))
|
||||
|
||||
platforms = repo.list_entities(dimension="platform")
|
||||
assert len(platforms) == 2
|
||||
|
||||
all_entities = repo.list_entities()
|
||||
assert len(all_entities) == 3
|
||||
|
||||
|
||||
def test_add_and_get_domain(repo):
|
||||
domain = Domain(
|
||||
name="test_domain",
|
||||
description="A test domain",
|
||||
metric_bounds=[
|
||||
MetricBound("speed", weight=0.5, norm_min=0, norm_max=100),
|
||||
MetricBound("safety", weight=0.5, norm_min=0, norm_max=1),
|
||||
],
|
||||
)
|
||||
saved = repo.add_domain(domain)
|
||||
assert saved.id is not None
|
||||
|
||||
loaded = repo.get_domain("test_domain")
|
||||
assert loaded is not None
|
||||
assert loaded.name == "test_domain"
|
||||
assert len(loaded.metric_bounds) == 2
|
||||
assert loaded.metric_bounds[0].metric_name == "speed"
|
||||
|
||||
|
||||
def test_combination_save_and_dedup(repo):
|
||||
e1 = repo.add_entity(Entity(name="A", dimension="platform"))
|
||||
e2 = repo.add_entity(Entity(name="B", dimension="power_source"))
|
||||
|
||||
from physcom.models.combination import Combination
|
||||
combo = Combination(entities=[e1, e2])
|
||||
saved = repo.save_combination(combo)
|
||||
assert saved.id is not None
|
||||
|
||||
# Same entities, same hash → should not create duplicate
|
||||
combo2 = Combination(entities=[e1, e2])
|
||||
saved2 = repo.save_combination(combo2)
|
||||
assert saved2.id == saved.id
|
||||
|
||||
|
||||
def test_seed_loads(seeded_repo):
|
||||
platforms = seeded_repo.list_entities(dimension="platform")
|
||||
power_sources = seeded_repo.list_entities(dimension="power_source")
|
||||
assert len(platforms) == 9
|
||||
assert len(power_sources) == 9
|
||||
|
||||
domains = seeded_repo.list_domains()
|
||||
assert len(domains) == 2
|
||||
Reference in New Issue
Block a user