Next alpha stage commit
This commit is contained in:
147
tests/test_journey_search.py
Normal file
147
tests/test_journey_search.py
Normal file
@@ -0,0 +1,147 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.journey import _filter_dominated_journeys
|
||||
from app.journey_search import _rank_journeys, _select_diverse_journeys
|
||||
|
||||
|
||||
def test_progressive_selection_keeps_fast_and_low_walk_transit_options():
|
||||
fast_with_walk = _journey(
|
||||
"fast",
|
||||
arrival=30_000,
|
||||
transfers=0,
|
||||
legs=[
|
||||
_leg("tram", "22", "A", "B"),
|
||||
_leg("walk", "walk", "B", "Z", distance_m=1200),
|
||||
],
|
||||
)
|
||||
slower_low_walk = _journey(
|
||||
"low-walk",
|
||||
arrival=31_200,
|
||||
transfers=1,
|
||||
legs=[
|
||||
_leg("tram", "22", "A", "Hbf"),
|
||||
_leg("bus", "34", "Hbf", "Y"),
|
||||
_leg("walk", "walk", "Y", "Z", distance_m=120),
|
||||
],
|
||||
)
|
||||
walk_only = _journey(
|
||||
"walk-only",
|
||||
arrival=30_900,
|
||||
transfers=0,
|
||||
legs=[_leg("walk", "walk", "A", "Z", distance_m=1800)],
|
||||
)
|
||||
|
||||
ranked = _rank_journeys([slower_low_walk, walk_only, fast_with_walk], "recommended")
|
||||
selected = _select_diverse_journeys(ranked, limit=3)
|
||||
|
||||
assert len(selected) <= 3
|
||||
assert {journey["id"] for journey in selected} == {"fast", "low-walk", "walk-only"}
|
||||
|
||||
|
||||
def test_progressive_selection_collapses_same_journey_from_duplicate_gtfs_feeds():
|
||||
rnv = _journey(
|
||||
"rnv",
|
||||
arrival=29_820,
|
||||
transfers=0,
|
||||
legs=[
|
||||
_leg("walk", "walk", "Jakob-Neu-Straße 2", "Eppelheim Rathaus", dataset_id=10, source_name=None),
|
||||
_leg("tram", "RNV 22", "Eppelheim Rathaus", "Heidelberg Hbf", dataset_id=10, source_name="DE Verkehrsverbund Rhein-Neckar GTFS"),
|
||||
],
|
||||
)
|
||||
delfi = _journey(
|
||||
"delfi",
|
||||
arrival=29_820,
|
||||
transfers=0,
|
||||
legs=[
|
||||
_leg("walk", "walk", "Jakob-Neu-Straße 2", "Eppelheim Rathaus", dataset_id=4, source_name=None),
|
||||
_leg("tram", "RNV 22", "Eppelheim Rathaus", "Heidelberg Hbf", dataset_id=4, source_name="DELFI / GTFS.de Germany", stop_count=8),
|
||||
],
|
||||
)
|
||||
|
||||
ranked = _rank_journeys([rnv, delfi], "recommended")
|
||||
selected = _select_diverse_journeys(ranked, limit=3)
|
||||
|
||||
assert [journey["id"] for journey in selected] == ["delfi"]
|
||||
|
||||
|
||||
def test_dominance_removes_only_slower_more_transfer_same_endpoint_options():
|
||||
direct = _journey(
|
||||
"direct",
|
||||
arrival=30_000,
|
||||
transfers=0,
|
||||
legs=[
|
||||
_leg("tram", "22", "A", "platform-a", canonical_to=500),
|
||||
_leg("walk", "walk", "platform-a", "Z", distance_m=800),
|
||||
],
|
||||
)
|
||||
faster_transfer = _journey(
|
||||
"faster-transfer",
|
||||
arrival=29_500,
|
||||
transfers=1,
|
||||
legs=[
|
||||
_leg("bus", "34", "A", "X"),
|
||||
_leg("tram", "5", "X", "platform-b", canonical_to=500),
|
||||
_leg("walk", "walk", "platform-b", "Z", distance_m=800),
|
||||
],
|
||||
)
|
||||
slower_transfer = _journey(
|
||||
"slower-transfer",
|
||||
arrival=31_000,
|
||||
transfers=1,
|
||||
legs=[
|
||||
_leg("bus", "713", "A", "Y"),
|
||||
_leg("tram", "22", "Y", "platform-c", canonical_to=500),
|
||||
_leg("walk", "walk", "platform-c", "Z", distance_m=800),
|
||||
],
|
||||
)
|
||||
|
||||
filtered = _filter_dominated_journeys([slower_transfer, faster_transfer, direct])
|
||||
|
||||
assert {journey["id"] for journey in filtered} == {"direct", "faster-transfer"}
|
||||
|
||||
|
||||
def _journey(journey_id: str, *, arrival: int, transfers: int, legs: list[dict]) -> dict:
|
||||
departure = 28_800
|
||||
return {
|
||||
"id": journey_id,
|
||||
"departure_seconds": departure,
|
||||
"arrival_seconds": arrival,
|
||||
"duration_seconds": arrival - departure,
|
||||
"duration_minutes": (arrival - departure + 59) // 60,
|
||||
"transfers": transfers,
|
||||
"legs": legs,
|
||||
}
|
||||
|
||||
|
||||
def _leg(
|
||||
mode: str,
|
||||
route: str,
|
||||
from_stop: str,
|
||||
to_stop: str,
|
||||
*,
|
||||
distance_m: float = 0,
|
||||
canonical_to: int | None = None,
|
||||
dataset_id: int = 1,
|
||||
source_name: str | None = "Test GTFS",
|
||||
stop_count: int = 2,
|
||||
) -> dict:
|
||||
to_payload = {"stop_id": to_stop}
|
||||
stops = [{"stop_id": from_stop}, {"stop_id": to_stop}]
|
||||
if canonical_to is not None:
|
||||
stops[-1]["canonical_stop"] = {"id": canonical_to}
|
||||
return {
|
||||
"dataset_id": dataset_id,
|
||||
"source_name": source_name,
|
||||
"mode": mode,
|
||||
"route_id": route,
|
||||
"route_ref": route,
|
||||
"trip_id": f"{route}-trip" if mode != "walk" else None,
|
||||
"from": {"stop_id": from_stop},
|
||||
"to": to_payload,
|
||||
"departure_time": "08:00:00",
|
||||
"arrival_time": "08:10:00",
|
||||
"distance_m": distance_m,
|
||||
"stop_count": stop_count if mode != "walk" else None,
|
||||
"intermediate_stop_count": max(0, stop_count - 2) if mode != "walk" else None,
|
||||
"stops": stops,
|
||||
}
|
||||
Reference in New Issue
Block a user