---
phase: 09-trip-planner-modes-tdd
plan: 03
type: tdd
---
Test-driven validation of Scenario C (start/end cities routing) travel corridor game inclusion and geographic efficiency validation.
Purpose: Ensure routes start at the specified city, end at the specified city, and only include games along the efficient travel corridor (no backtracking). Tests define correctness - code must match.
Output: Working corridor-based routing with anti-backtracking validation and passing TDD tests.
~/.claude/get-shit-done/workflows/execute-phase.md
./summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/09-trip-planner-modes-tdd/09-01-SUMMARY.md
@.planning/phases/09-trip-planner-modes-tdd/09-02-SUMMARY.md
@SportsTime/Planning/Engine/ScenarioCPlanner.swift
@SportsTimeTests/ScenarioCPlannerTests.swift
@SportsTimeTests/GameDAGRouterTests.swift
**Tech stack available:** Swift Testing framework, GameDAGRouter with directional filtering, corridor-based routing
**Established patterns:** Swift Testing @Test/@Suite, TDD RED-GREEN-REFACTOR, geographic efficiency validation
**Constraining decisions:**
- Phase 08-01: GameDAGRouter validates routes don't include excessive backtracking
- Phase 08-02: Dynamic beam scaling for performance
- Phase 09-01: Timezone and same-day conflict patterns
- Phase 09-02: Impossible combination detection patterns
**Issues being addressed:** None (new test coverage)
Feature 1: Travel corridor game inclusion
SportsTimeTests/ScenarioCPlannerTests.swift
SportsTime/Planning/Engine/ScenarioCPlanner.swift
Test cases for games along the travel corridor:
**Case 1: Direct route with games along path**
- Start: Los Angeles, End: San Francisco
- Games available: LA Jan 5, San Jose Jan 6 (midpoint), SF Jan 7
- Expected: Route includes all 3 games (LA → SJ → SF)
**Case 2: Game slightly off corridor (within tolerance)**
- Start: LA, End: SF (straight north on I-5)
- Games available: LA Jan 5, Sacramento Jan 6 (20mi east of I-5), SF Jan 7
- Expected: Route includes Sacramento (within corridor tolerance)
**Case 3: Game far from corridor (excluded)**
- Start: LA, End: SF (north-bound)
- Games available: LA Jan 5, Phoenix Jan 6 (300mi east), SF Jan 7
- Expected: Route excludes Phoenix (too far from LA→SF corridor)
**Case 4: Multiple games, some on corridor, some off**
- Start: LA, End: Portland
- Games: LA Jan 5, San Diego Jan 6 (south), SF Jan 7 (on path), Seattle Jan 8 (beyond end)
- Expected: LA → SF → Portland (excludes SD south, excludes Seattle beyond)
**Case 5: No games along corridor**
- Start: LA, End: Seattle
- Games available: Phoenix Jan 5, Denver Jan 6 (both far from LA→Seattle I-5 route)
- Expected: Route has start/end waypoints only, no games OR .failure(.noGamesInRange)
Corridor tolerance: Games within ~50-100 miles of direct path should be included.
If tests fail:
1. ScenarioCPlanner may not be calculating corridor boundaries correctly
2. Geographic proximity threshold may be too strict or too loose
3. Directional filtering may exclude valid corridor games
4. Fix ScenarioCPlanner's corridor calculation and game filtering logic
Do NOT weaken test assertions - fix the code to match expected behavior.
Feature 2: Geographic efficiency validation (anti-backtracking)
SportsTimeTests/ScenarioCPlannerTests.swift
SportsTime/Planning/Engine/ScenarioCPlanner.swift
Test cases for preventing geographic backtracking:
**Case 1: Route must start at specified start city**
- Start: San Francisco, End: Los Angeles
- Games available: LA Jan 5, SF Jan 7
- Expected: Route begins at SF waypoint → LA game (not LA → SF)
**Case 2: Route must end at specified end city**
- Start: LA, End: Seattle
- Games available: LA Jan 5, SF Jan 6
- Expected: Route ends at Seattle waypoint (LA → SF → Seattle)
**Case 3: Intermediate games in wrong order (backtracking)**
- Start: LA, End: Portland
- Games available: SF Jan 5, LA Jan 6 (south of SF), Portland Jan 7
- Expected: Route rejects LA Jan 6 (requires backtrack south) OR reorders to LA→SF→Portland
**Case 4: Multiple options, least backtracking preferred**
- Start: LA, End: SF
- Option A: LA → San Diego (south) → SF (major backtrack)
- Option B: LA → San Jose → SF (direct north)
- Expected: Rank Option B higher (less backtracking)
**Case 5: Backtracking within tolerance (acceptable)**
- Start: LA, End: SF
- Games: LA Jan 5, Anaheim Jan 6 (30mi south), San Jose Jan 7, SF Jan 8
- Expected: Route includes Anaheim if time permits (minor backtrack acceptable)
**Case 6: Excessive backtracking rejected**
- Start: LA, End: Seattle (north-bound)
- Games: LA Jan 5, San Diego Jan 6 (120mi south), SF Jan 7, Seattle Jan 8
- Expected: Excludes San Diego (excessive backtrack) OR returns failure if must include
**Case 7: Correct directional classification**
- Start: Boston, End: Miami (north to south)
- Games: Boston Jan 5, NYC Jan 6, DC Jan 7, Miami Jan 8
- Expected: Route follows north→south direction (Boston→NYC→DC→Miami)
Backtracking tolerance: Minor detours (<50mi off path) acceptable, major backtracking (>100mi) rejected.
If tests fail:
1. ScenarioCPlanner may not be validating route direction matches start→end vector
2. GameDAGRouter may not be penalizing backtracking routes
3. Route ranking may not prioritize directional efficiency
4. Fix ScenarioCPlanner's directional validation and GameDAGRouter's scoring
Do NOT weaken test assertions - fix the code to match expected behavior.
All tests pass:
```bash
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime \
-destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
-only-testing:SportsTimeTests/ScenarioCPlannerTests test
```
Specific tests to verify:
- Corridor inclusion tests: 5 new tests (direct path, slightly off, far off, mixed, no games)
- Anti-backtracking tests: 7 new tests (start city, end city, wrong order, least backtrack, tolerance, excessive, directional)
- 12 new tests added to ScenarioCPlannerTests.swift
- All tests follow TDD pattern (RED → GREEN → REFACTOR)
- Each feature produces 2-3 commits (test, feat, optional refactor)
- No test assertions weakened
- All existing tests continue to pass
- Tests use existing helper patterns (makeStadium, makeGame, makeRequest)