Harden planning test suite with realistic fixtures and output sanity checks
Adds messy/realistic data factories to TestFixtures, new PlannerOutputSanityTests, and updates all scenario planner tests with improved coverage and assertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,10 @@ struct MustStopValidationTests {
|
||||
let engine = TripPlanningEngine()
|
||||
let result = engine.planItineraries(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Every route must include Boston as a must-stop")
|
||||
}
|
||||
guard case .success(let options) = result else { Issue.record("Expected .success, got \(result)"); return }
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Every route must include Boston as a must-stop")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,11 +115,10 @@ struct MustStopValidationTests {
|
||||
let engine = TripPlanningEngine()
|
||||
let result = engine.planItineraries(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included")
|
||||
}
|
||||
guard case .success(let options) = result else { Issue.record("Expected .success, got \(result)"); return }
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,41 +154,39 @@ struct MustStopValidationTests {
|
||||
let engine = TripPlanningEngine()
|
||||
let result = engine.planItineraries(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included in follow-team mode")
|
||||
}
|
||||
guard case .success(let options) = result else { Issue.record("Expected .success, got \(result)"); return }
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included in follow-team mode")
|
||||
}
|
||||
}
|
||||
|
||||
@Test("scenarioE: must stops enforced via centralized filter")
|
||||
func scenarioE_mustStops_routesContainRequiredCities() {
|
||||
let baseDate = TestFixtures.date(year: 2026, month: 6, day: 1, hour: 19, minute: 0)
|
||||
let day1 = TestClock.calendar.date(byAdding: .day, value: 1, to: baseDate)!
|
||||
let day2 = TestClock.calendar.date(byAdding: .day, value: 2, to: baseDate)!
|
||||
// 2 teams → windowDuration = 4 days. Games must be within 3 days to fit in a single window.
|
||||
let day3 = TestClock.calendar.date(byAdding: .day, value: 3, to: baseDate)!
|
||||
|
||||
let teamNYC = "team_mlb_new_york"
|
||||
let teamBOS = "team_mlb_boston"
|
||||
|
||||
let gameNYC = TestFixtures.game(city: "New York", dateTime: baseDate, homeTeamId: teamNYC)
|
||||
let gameBOS = TestFixtures.game(city: "Boston", dateTime: day1, homeTeamId: teamBOS)
|
||||
let gamePHL = TestFixtures.game(city: "Philadelphia", dateTime: day2, homeTeamId: "team_mlb_philadelphia")
|
||||
let gameBOS = TestFixtures.game(city: "Boston", dateTime: day3, homeTeamId: teamBOS)
|
||||
|
||||
let stadiums = TestFixtures.stadiumMap(for: [gameNYC, gameBOS, gamePHL])
|
||||
let stadiums = TestFixtures.stadiumMap(for: [gameNYC, gameBOS])
|
||||
|
||||
let prefs = TripPreferences(
|
||||
planningMode: .teamFirst,
|
||||
sports: [.mlb],
|
||||
startDate: baseDate,
|
||||
endDate: day2,
|
||||
endDate: day3,
|
||||
mustStopLocations: [LocationInput(name: "Boston")],
|
||||
selectedTeamIds: [teamNYC, teamBOS]
|
||||
)
|
||||
|
||||
let request = PlanningRequest(
|
||||
preferences: prefs,
|
||||
availableGames: [gameNYC, gameBOS, gamePHL],
|
||||
availableGames: [gameNYC, gameBOS],
|
||||
teams: [
|
||||
teamNYC: TestFixtures.team(city: "New York"),
|
||||
teamBOS: TestFixtures.team(city: "Boston"),
|
||||
@@ -201,54 +197,58 @@ struct MustStopValidationTests {
|
||||
let engine = TripPlanningEngine()
|
||||
let result = engine.planItineraries(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included in team-first mode")
|
||||
}
|
||||
guard case .success(let options) = result else { Issue.record("Expected .success, got \(result)"); return }
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("boston"), "Must-stop filter should ensure Boston is included in team-first mode")
|
||||
}
|
||||
}
|
||||
|
||||
@Test("scenarioC: must stops enforced via centralized filter")
|
||||
func scenarioC_mustStops_routesContainRequiredCities() {
|
||||
let baseDate = TestFixtures.date(year: 2026, month: 6, day: 1, hour: 19, minute: 0)
|
||||
let day2 = TestClock.calendar.date(byAdding: .day, value: 1, to: baseDate)!
|
||||
let day3 = TestClock.calendar.date(byAdding: .day, value: 2, to: baseDate)!
|
||||
// Route: Chicago → New York (eastward). Detroit is directionally between them.
|
||||
let baseDate = TestClock.now
|
||||
let endDate = TestClock.calendar.date(byAdding: .day, value: 10, to: baseDate)!
|
||||
|
||||
let chiCoord = TestFixtures.coordinates["Chicago"]!
|
||||
let detCoord = TestFixtures.coordinates["Detroit"]!
|
||||
let nycCoord = TestFixtures.coordinates["New York"]!
|
||||
let bosCoord = TestFixtures.coordinates["Boston"]!
|
||||
|
||||
let gameNYC = TestFixtures.game(city: "New York", dateTime: baseDate)
|
||||
let gamePHL = TestFixtures.game(city: "Philadelphia", dateTime: day2)
|
||||
let gameBOS = TestFixtures.game(city: "Boston", dateTime: day3)
|
||||
let chiStadium = TestFixtures.stadium(id: "chi", city: "Chicago")
|
||||
let detStadium = TestFixtures.stadium(id: "det", city: "Detroit")
|
||||
let nycStadium = TestFixtures.stadium(id: "nyc", city: "New York")
|
||||
|
||||
let stadiums = TestFixtures.stadiumMap(for: [gameNYC, gamePHL, gameBOS])
|
||||
let gameCHI = TestFixtures.game(city: "Chicago", dateTime: TestClock.addingDays(1), stadiumId: "chi")
|
||||
let gameDET = TestFixtures.game(city: "Detroit", dateTime: TestClock.addingDays(4), stadiumId: "det")
|
||||
let gameNYC = TestFixtures.game(city: "New York", dateTime: TestClock.addingDays(7), stadiumId: "nyc")
|
||||
|
||||
let prefs = TripPreferences(
|
||||
planningMode: .locations,
|
||||
startLocation: LocationInput(name: "New York", coordinate: nycCoord),
|
||||
endLocation: LocationInput(name: "Boston", coordinate: bosCoord),
|
||||
startLocation: LocationInput(name: "Chicago", coordinate: chiCoord),
|
||||
endLocation: LocationInput(name: "New York", coordinate: nycCoord),
|
||||
sports: [.mlb],
|
||||
startDate: baseDate,
|
||||
endDate: day3,
|
||||
mustStopLocations: [LocationInput(name: "Philadelphia")]
|
||||
endDate: endDate,
|
||||
leisureLevel: .moderate,
|
||||
mustStopLocations: [LocationInput(name: "Detroit")],
|
||||
lodgingType: .hotel,
|
||||
numberOfDrivers: 2
|
||||
)
|
||||
|
||||
let request = PlanningRequest(
|
||||
preferences: prefs,
|
||||
availableGames: [gameNYC, gamePHL, gameBOS],
|
||||
availableGames: [gameCHI, gameDET, gameNYC],
|
||||
teams: [:],
|
||||
stadiums: stadiums
|
||||
stadiums: ["chi": chiStadium, "det": detStadium, "nyc": nycStadium]
|
||||
)
|
||||
|
||||
let engine = TripPlanningEngine()
|
||||
let result = engine.planItineraries(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("philadelphia"), "Must-stop filter should ensure Philadelphia is included in route mode")
|
||||
}
|
||||
guard case .success(let options) = result else { Issue.record("Expected .success, got \(result)"); return }
|
||||
for option in options {
|
||||
let cities = option.stops.map { $0.city.lowercased() }
|
||||
#expect(cities.contains("detroit"), "Must-stop filter should ensure Detroit is included in Chicago→NYC route")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user