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:
@@ -129,12 +129,15 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let result = planner.plan(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let gameIds = option.stops.flatMap { $0.games }
|
||||
#expect(gameIds.contains("nyc-game"), "Every route must contain selected NYC game")
|
||||
#expect(gameIds.contains("boston-game"), "Every route must contain selected Boston game")
|
||||
}
|
||||
guard case .success(let options) = result else {
|
||||
Issue.record("Expected .success, got \(result)")
|
||||
return
|
||||
}
|
||||
|
||||
for option in options {
|
||||
let gameIds = option.stops.flatMap { $0.games }
|
||||
#expect(gameIds.contains("nyc-game"), "Every route must contain selected NYC game")
|
||||
#expect(gameIds.contains("boston-game"), "Every route must contain selected Boston game")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,10 +294,12 @@ struct ScenarioBPlannerTests {
|
||||
let result = planner.plan(request: request)
|
||||
|
||||
// Should succeed even without explicit dates because of sliding window
|
||||
if case .success(let options) = result {
|
||||
#expect(!options.isEmpty)
|
||||
guard case .success(let options) = result else {
|
||||
Issue.record("Expected .success, got \(result)")
|
||||
return
|
||||
}
|
||||
// May also fail if no valid date ranges, which is acceptable
|
||||
|
||||
#expect(!options.isEmpty)
|
||||
}
|
||||
|
||||
@Test("plan: explicit date range with out-of-range selected game returns dateRangeViolation")
|
||||
@@ -418,12 +423,15 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let result = planner.plan(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
for option in options {
|
||||
let gameIds = Set(option.stops.flatMap { $0.games })
|
||||
#expect(gameIds.contains("nyc-anchor"), "Anchor game cannot be dropped: nyc-anchor")
|
||||
#expect(gameIds.contains("boston-anchor"), "Anchor game cannot be dropped: boston-anchor")
|
||||
}
|
||||
guard case .success(let options) = result else {
|
||||
Issue.record("Expected .success, got \(result)")
|
||||
return
|
||||
}
|
||||
|
||||
for option in options {
|
||||
let gameIds = Set(option.stops.flatMap { $0.games })
|
||||
#expect(gameIds.contains("nyc-anchor"), "Anchor game cannot be dropped: nyc-anchor")
|
||||
#expect(gameIds.contains("boston-anchor"), "Anchor game cannot be dropped: boston-anchor")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,12 +466,47 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let result = planner.plan(request: request)
|
||||
|
||||
if case .success(let options) = result {
|
||||
#expect(!options.isEmpty, "Success must have options")
|
||||
for option in options {
|
||||
let allGames = option.stops.flatMap { $0.games }
|
||||
#expect(allGames.contains("anchor1"), "Every option must include anchor")
|
||||
}
|
||||
guard case .success(let options) = result else {
|
||||
Issue.record("Expected .success, got \(result)")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(!options.isEmpty, "Success must have options")
|
||||
for option in options {
|
||||
let allGames = option.stops.flatMap { $0.games }
|
||||
#expect(allGames.contains("anchor1"), "Every option must include anchor")
|
||||
}
|
||||
}
|
||||
|
||||
@Test("plan: anchor game in past — handled gracefully")
|
||||
func plan_anchorGameInPast_handledGracefully() {
|
||||
let nycStadium = makeStadium(id: "nyc", city: "New York", coordinate: nycCoord)
|
||||
|
||||
let pastAnchor = makeGame(id: "past_anchor", stadiumId: "nyc", dateTime: TestClock.addingDays(-1))
|
||||
|
||||
let prefs = TripPreferences(
|
||||
planningMode: .gameFirst,
|
||||
sports: [.mlb],
|
||||
mustSeeGameIds: ["past_anchor"],
|
||||
startDate: TestClock.addingDays(-3),
|
||||
endDate: TestClock.addingDays(5),
|
||||
numberOfDrivers: 1
|
||||
)
|
||||
|
||||
let request = PlanningRequest(
|
||||
preferences: prefs,
|
||||
availableGames: [pastAnchor],
|
||||
teams: [:],
|
||||
stadiums: ["nyc": nycStadium]
|
||||
)
|
||||
|
||||
// Should not crash. May include past anchor (it's explicitly selected) or fail gracefully.
|
||||
let result = planner.plan(request: request)
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let f):
|
||||
Issue.record("Unexpected failure: \(f)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user