WanderLust / tests /test_robustness.py
Tristan Leduc
Add on-demand worldwide cities (any city via live OSM)
1a502dd
Raw
History Blame Contribute Delete
3.85 kB
"""Regression tests for the adversarial-review fixes (input robustness + clarity).
These lock in invariants that were previously violated: mode validation, the
budget=0 == plain-route guarantee, non-Paris rejection, nonsense-vibe → neutral,
the unnamed-POI demotion, and place-count consistency across UI surfaces.
"""
from __future__ import annotations
import app
from discoverroute.data import taxonomy
from discoverroute.interpret.affinity import resolve_affinity
from discoverroute.pipeline import plan_route
from discoverroute.routing import scoring
S = "Place de la République, Paris"
D = "Jardin du Luxembourg, Paris"
# ---- input validation ------------------------------------------------------
def test_invalid_mode_rejected():
assert plan_route(S, D, mode="car").error
assert plan_route(S, D, mode="xyz").error
def test_uppercase_mode_normalized():
assert plan_route(S, D, mode="WALK").error is None
def test_far_apart_endpoints_rejected_not_namesake_routed():
# World support: endpoints on different continents can't form one walkable
# discovery route. Resolve via lat/lon (no network) so the distance cap fires
# — and crucially we get an honest error, never a fake namesake route.
london, tokyo = "51.5079, -0.0877", "35.6586, 139.7454"
r = plan_route(london, tokyo, vibe="quiet")
assert r.error and "far" in r.error.lower()
assert r.discovery is None and not r.pois
def test_budget_zero_is_plain_route_even_with_pace_word():
# P0-3: an explicit 0 slider must win over a vibe pace hint ("all day").
r = plan_route(S, D, budget=0.0, vibe="I want to spend all day exploring")
assert r.discovery is None and not r.pois
# ---- vibe interpretation ---------------------------------------------------
def test_nonsense_vibe_degrades_to_neutral():
aff, _ = resolve_affinity("quantum physics asdfgh")
spread = max(aff.values()) - min(aff.values())
assert spread < 1e-6 # all categories equal → neutral
def test_real_vibe_is_confident():
aff, _ = resolve_affinity("quiet green park")
assert (max(aff.values()) - min(aff.values())) > 0.2
# ---- unnamed-POI demotion --------------------------------------------------
class _POI:
def __init__(self, name, category="park_garden", confidence=0.5):
self.name, self.category, self.confidence = name, category, confidence
def test_unnamed_poi_scored_below_named():
w = scoring.Weights(category_affinity={"park_garden": 1.0})
named = scoring.base_score(_POI("Jardin X"), w, adventurousness=1.0)
unnamed = scoring.base_score(_POI(None), w, adventurousness=1.0)
assert unnamed < named # demoted even at max adventurousness
def test_high_adventurousness_not_mostly_unnamed():
r = plan_route(S, D, vibe="hidden gems off the beaten path",
budget=0.7, adventurousness=1.0)
if r.pois:
unnamed = sum(1 for p in r.pois
if not (getattr(p, "name", None) and str(p.name).strip()))
assert unnamed / len(r.pois) <= 0.5
# ---- labels & count consistency --------------------------------------------
def test_display_label_article_and_no_snake_case():
assert taxonomy.display_label(_POI(None, "artwork")) == "a piece of public art"
assert taxonomy.display_label(_POI(None, "attraction")) == "a landmark"
assert "_" not in taxonomy.display_label(_POI(None, "monument_historic"))
assert taxonomy.display_label(_POI("Louvre")) == "Louvre"
def test_place_count_consistent_across_surfaces():
r = plan_route(S, D, vibe="quiet green bookshops", budget=0.5, n_alternatives=1)
if r.alternatives:
a = r.alternatives[0]
n = len(a.pois)
assert f"{n} place" in a.summary_md
assert f"{n} place" in app._alt_label(0, a, r.plain)
assert f"{n} place" in a.itinerary_md