Add implementation code for all 4 improvement plan phases

Production changes:
- TravelEstimator: remove 300mi fallback, return nil on missing coords
- TripPlanningEngine: add warnings array, empty sports warning, inverted
  date range rejection, must-stop filter, segment validation gate
- GameDAGRouter: add routePreference parameter with preference-aware
  bucket ordering and sorting in selectDiverseRoutes()
- ScenarioA-E: pass routePreference through to GameDAGRouter
- ScenarioA: track games with missing stadium data
- ScenarioE: add region filtering for home games
- TravelSegment: add requiresOvernightStop and travelDays() helpers

Test changes:
- GameDAGRouterTests: +252 lines for route preference verification
- TripPlanningEngineTests: +153 lines for segment validation, date range,
  empty sports
- ScenarioEPlannerTests: +119 lines for region filter tests
- TravelEstimatorTests: remove obsolete fallback distance tests
- ItineraryBuilderTests: update nil-coords test expectation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-03-21 09:40:32 -05:00
parent db6ab2f923
commit 6cbcef47ae
14 changed files with 807 additions and 88 deletions

View File

@@ -69,26 +69,6 @@ struct TravelEstimatorTests {
#expect(abs(convertedMiles - miles) < 1.0) // Within 1 mile tolerance
}
// MARK: - Specification Tests: estimateFallbackDistance
@Test("estimateFallbackDistance: same city returns zero")
func estimateFallbackDistance_sameCity_returnsZero() {
let from = makeStop(city: "New York")
let to = makeStop(city: "New York")
let distance = TravelEstimator.estimateFallbackDistance(from: from, to: to)
#expect(distance == 0)
}
@Test("estimateFallbackDistance: different cities returns 300 miles")
func estimateFallbackDistance_differentCities_returns300() {
let from = makeStop(city: "New York")
let to = makeStop(city: "Boston")
let distance = TravelEstimator.estimateFallbackDistance(from: from, to: to)
#expect(distance == 300)
}
// MARK: - Specification Tests: calculateDistanceMiles
@Test("calculateDistanceMiles: with coordinates uses Haversine times routing factor")
@@ -100,25 +80,26 @@ struct TravelEstimatorTests {
let haversine = TravelEstimator.haversineDistanceMiles(from: nyc, to: boston)
// Road distance = Haversine * 1.3
#expect(abs(distance - haversine * 1.3) < 0.1)
#expect(distance != nil)
#expect(abs(distance! - haversine * 1.3) < 0.1)
}
@Test("calculateDistanceMiles: missing coordinates uses fallback")
func calculateDistanceMiles_missingCoordinates_usesFallback() {
@Test("calculateDistanceMiles: missing coordinates returns nil")
func calculateDistanceMiles_missingCoordinates_returnsNil() {
let from = makeStop(city: "New York", coordinate: nil)
let to = makeStop(city: "Boston", coordinate: nil)
let distance = TravelEstimator.calculateDistanceMiles(from: from, to: to)
#expect(distance == 300) // Fallback distance
#expect(distance == nil)
}
@Test("calculateDistanceMiles: same city without coordinates returns zero")
func calculateDistanceMiles_sameCityNoCoords_returnsZero() {
let from = makeStop(city: "New York", coordinate: nil)
let to = makeStop(city: "New York", coordinate: nil)
@Test("calculateDistanceMiles: one missing coordinate returns nil")
func calculateDistanceMiles_oneMissingCoordinate_returnsNil() {
let from = makeStop(city: "New York", coordinate: nyc)
let to = makeStop(city: "Boston", coordinate: nil)
let distance = TravelEstimator.calculateDistanceMiles(from: from, to: to)
#expect(distance == 0)
#expect(distance == nil)
}
// MARK: - Specification Tests: estimate(ItineraryStop, ItineraryStop)
@@ -142,7 +123,7 @@ struct TravelEstimatorTests {
let segment = TravelEstimator.estimate(from: from, to: to, constraints: defaultConstraints)!
let expectedMiles = TravelEstimator.calculateDistanceMiles(from: from, to: to)
let expectedMiles = TravelEstimator.calculateDistanceMiles(from: from, to: to)!
let expectedMeters = expectedMiles * 1609.34
let expectedHours = expectedMiles / 60.0
let expectedSeconds = expectedHours * 3600
@@ -327,7 +308,7 @@ struct TravelEstimatorTests {
let from = makeStop(city: "New York", coordinate: nyc)
let to = makeStop(city: "Boston", coordinate: boston)
let roadDistance = TravelEstimator.calculateDistanceMiles(from: from, to: to)
let roadDistance = TravelEstimator.calculateDistanceMiles(from: from, to: to)!
let straightLine = TravelEstimator.haversineDistanceMiles(from: nyc, to: boston)
#expect(roadDistance >= straightLine, "Road distance should be >= straight line")