refactor: change domain model IDs from UUID to String canonical IDs
This refactor fixes the achievement system by using stable canonical string IDs (e.g., "stadium_mlb_fenway_park") instead of random UUIDs. This ensures stadium mappings for achievements are consistent across app launches and CloudKit sync operations. Changes: - Stadium, Team, Game: id property changed from UUID to String - Trip, TripStop, TripPreferences: updated to use String IDs for games/stadiums - CKModels: removed UUID parsing, use canonical IDs directly - AchievementEngine: now matches against canonical stadium IDs - All test files updated to use String IDs instead of UUID() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,7 @@ struct ConcurrencyTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -50,10 +50,10 @@ struct ConcurrencyTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -73,7 +73,7 @@ struct ConcurrencyTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium]
|
||||
stadiums: [String: Stadium]
|
||||
) -> PlanningRequest {
|
||||
let preferences = TripPreferences(
|
||||
planningMode: .dateRange,
|
||||
@@ -107,8 +107,8 @@ struct ConcurrencyTests {
|
||||
|
||||
let pair = cityPairs[requestIndex % cityPairs.count]
|
||||
|
||||
let stadium1Id = UUID()
|
||||
let stadium2Id = UUID()
|
||||
let stadium1Id = "stadium_1_\(UUID().uuidString)"
|
||||
let stadium2Id = "stadium_2_\(UUID().uuidString)"
|
||||
|
||||
let stadium1 = makeStadium(id: stadium1Id, city: pair.city1.0, lat: pair.city1.1, lon: pair.city1.2)
|
||||
let stadium2 = makeStadium(id: stadium2Id, city: pair.city2.0, lat: pair.city2.1, lon: pair.city2.2)
|
||||
|
||||
@@ -31,7 +31,7 @@ struct EdgeCaseTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
state: String = "ST",
|
||||
lat: Double,
|
||||
@@ -52,10 +52,10 @@ struct EdgeCaseTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -75,7 +75,7 @@ struct EdgeCaseTests {
|
||||
city: String,
|
||||
state: String = "ST",
|
||||
coordinate: CLLocationCoordinate2D? = nil,
|
||||
games: [UUID] = [],
|
||||
games: [String] = [],
|
||||
arrivalDate: Date = Date()
|
||||
) -> ItineraryStop {
|
||||
ItineraryStop(
|
||||
@@ -95,8 +95,8 @@ struct EdgeCaseTests {
|
||||
@Test("11.1 - Nil stadium ID handled gracefully")
|
||||
func test_nilStadium_HandlesGracefully() {
|
||||
// Setup: Create games where stadium lookup would return nil
|
||||
let validStadiumId = UUID()
|
||||
let nonExistentStadiumId = UUID()
|
||||
let validStadiumId = "stadium_valid_\(UUID().uuidString)"
|
||||
let nonExistentStadiumId = "stadium_nonexistent_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: validStadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [validStadiumId: chicago]
|
||||
@@ -133,7 +133,7 @@ struct EdgeCaseTests {
|
||||
@Test("11.2 - Malformed date handled gracefully")
|
||||
func test_malformedDate_HandlesGracefully() {
|
||||
// Setup: Create games with dates at extremes
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: chicago]
|
||||
|
||||
@@ -172,9 +172,9 @@ struct EdgeCaseTests {
|
||||
@Test("11.3 - Invalid coordinates handled gracefully")
|
||||
func test_invalidCoordinates_HandlesGracefully() {
|
||||
// Setup: Create stadiums with invalid coordinates
|
||||
let validId = UUID()
|
||||
let invalidLatId = UUID()
|
||||
let invalidLonId = UUID()
|
||||
let validId = "stadium_valid_\(UUID().uuidString)"
|
||||
let invalidLatId = "stadium_invalidlat_\(UUID().uuidString)"
|
||||
let invalidLonId = "stadium_invalidlon_\(UUID().uuidString)"
|
||||
|
||||
// Valid stadium
|
||||
let validStadium = makeStadium(id: validId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -239,7 +239,7 @@ struct EdgeCaseTests {
|
||||
@Test("11.4 - Missing required fields handled gracefully")
|
||||
func test_missingRequiredFields_HandlesGracefully() {
|
||||
// Setup: Test with empty games array
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: chicago]
|
||||
|
||||
@@ -258,7 +258,7 @@ struct EdgeCaseTests {
|
||||
|
||||
// Test with empty stadiums dictionary
|
||||
let game = makeGame(stadiumId: stadiumId, dateTime: makeDate(day: 5, hour: 19))
|
||||
let emptyStadiums: [UUID: Stadium] = [:]
|
||||
let emptyStadiums: [String: Stadium] = [:]
|
||||
|
||||
let routes2 = GameDAGRouter.findRoutes(
|
||||
games: [game],
|
||||
@@ -271,9 +271,9 @@ struct EdgeCaseTests {
|
||||
|
||||
// Test with mismatched team IDs (homeTeamId and awayTeamId don't exist)
|
||||
let game2 = Game(
|
||||
id: UUID(),
|
||||
homeTeamId: UUID(), // Non-existent team
|
||||
awayTeamId: UUID(), // Non-existent team
|
||||
id: "game_test_\(UUID().uuidString)",
|
||||
homeTeamId: "team_nonexistent_\(UUID().uuidString)", // Non-existent team
|
||||
awayTeamId: "team_nonexistent_\(UUID().uuidString)", // Non-existent team
|
||||
stadiumId: stadiumId,
|
||||
dateTime: makeDate(day: 5, hour: 19),
|
||||
sport: .mlb,
|
||||
@@ -298,8 +298,8 @@ struct EdgeCaseTests {
|
||||
// Default: 8 hours/day * 60 mph * 2 days = 960 miles max
|
||||
// With 1.3 road factor, haversine distance should be 960/1.3 ≈ 738 miles
|
||||
|
||||
let stadiumId1 = UUID()
|
||||
let stadiumId2 = UUID()
|
||||
let stadiumId1 = "stadium_1_\(UUID().uuidString)"
|
||||
let stadiumId2 = "stadium_2_\(UUID().uuidString)"
|
||||
|
||||
// NYC and Chicago are about 790 miles apart (haversine)
|
||||
// With road factor 1.3, that's ~1027 road miles
|
||||
@@ -344,8 +344,8 @@ struct EdgeCaseTests {
|
||||
// NYC to LA is ~2,451 miles haversine, ~3,186 with road factor
|
||||
// At 60 mph, that's ~53 hours - way over 16 hour limit
|
||||
|
||||
let stadiumId1 = UUID()
|
||||
let stadiumId2 = UUID()
|
||||
let stadiumId1 = "stadium_1_\(UUID().uuidString)"
|
||||
let stadiumId2 = "stadium_2_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: stadiumId1, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let la = makeStadium(id: stadiumId2, city: "Los Angeles", lat: 34.0522, lon: -118.2437)
|
||||
@@ -398,7 +398,7 @@ struct EdgeCaseTests {
|
||||
// Calculate a point exactly 50 miles south (along a corridor)
|
||||
// 1 degree of latitude ≈ 69 miles
|
||||
// 50 miles ≈ 0.725 degrees
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let exactlyAtBoundary = makeStadium(
|
||||
id: stadiumId,
|
||||
city: "BoundaryCity",
|
||||
@@ -434,7 +434,7 @@ struct EdgeCaseTests {
|
||||
// Calculate a point 51 miles south (just outside the radius)
|
||||
// 1 degree of latitude ≈ 69 miles
|
||||
// 51 miles ≈ 0.739 degrees
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let justOutsideBoundary = makeStadium(
|
||||
id: stadiumId,
|
||||
city: "OutsideCity",
|
||||
@@ -464,8 +464,8 @@ struct EdgeCaseTests {
|
||||
@Test("11.9 - Game in different time zone normalizes correctly")
|
||||
func test_gameInDifferentTimeZone_NormalizesToUTC() {
|
||||
// Setup: Create games in different time zones
|
||||
let stadiumId1 = UUID()
|
||||
let stadiumId2 = UUID()
|
||||
let stadiumId1 = "stadium_1_\(UUID().uuidString)"
|
||||
let stadiumId2 = "stadium_2_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: stadiumId1, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let la = makeStadium(id: stadiumId2, city: "Los Angeles", lat: 34.0522, lon: -118.2437)
|
||||
@@ -508,7 +508,7 @@ struct EdgeCaseTests {
|
||||
@Test("11.10 - DST spring forward handled correctly")
|
||||
func test_dstSpringForward_HandlesCorrectly() {
|
||||
// Setup: Test around DST transition (Spring forward: March 8, 2026, 2 AM -> 3 AM)
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: chicago]
|
||||
|
||||
@@ -553,7 +553,7 @@ struct EdgeCaseTests {
|
||||
@Test("11.11 - DST fall back handled correctly")
|
||||
func test_dstFallBack_HandlesCorrectly() {
|
||||
// Setup: Test around DST transition (Fall back: November 1, 2026, 2 AM -> 1 AM)
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: chicago]
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
// Create a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double
|
||||
@@ -48,14 +48,14 @@ struct GameDAGRouterTests {
|
||||
|
||||
// Create a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
dateTime: Date
|
||||
) -> Game {
|
||||
Game(
|
||||
id: id,
|
||||
homeTeamId: UUID(),
|
||||
awayTeamId: UUID(),
|
||||
homeTeamId: "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: "team_test_\(UUID().uuidString)",
|
||||
stadiumId: stadiumId,
|
||||
dateTime: dateTime,
|
||||
sport: .mlb,
|
||||
@@ -78,7 +78,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.2 - Single game returns single route")
|
||||
func test_findRoutes_SingleGame_ReturnsSingleRoute() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let game = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
|
||||
@@ -95,7 +95,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.3 - Single game with matching anchor returns single route")
|
||||
func test_findRoutes_SingleGame_WithMatchingAnchor_ReturnsSingleRoute() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let game = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
|
||||
@@ -112,10 +112,10 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.4 - Single game with non-matching anchor returns empty")
|
||||
func test_findRoutes_SingleGame_WithNonMatchingAnchor_ReturnsEmpty() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let game = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
let nonExistentAnchor = UUID()
|
||||
let nonExistentAnchor = "stadium_nonexistent_\(UUID().uuidString)"
|
||||
|
||||
let routes = GameDAGRouter.findRoutes(
|
||||
games: [game],
|
||||
@@ -132,8 +132,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.5 - Two games with feasible transition returns both in order")
|
||||
func test_findRoutes_TwoGames_FeasibleTransition_ReturnsBothInOrder() {
|
||||
// Chicago to Milwaukee is ~90 miles - easily feasible
|
||||
let chicagoStadiumId = UUID()
|
||||
let milwaukeeStadiumId = UUID()
|
||||
let chicagoStadiumId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeStadiumId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicagoStadium = makeStadium(id: chicagoStadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukeeStadium = makeStadium(id: milwaukeeStadiumId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -162,8 +162,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.6 - Two games with infeasible transition returns separate routes")
|
||||
func test_findRoutes_TwoGames_InfeasibleTransition_ReturnsSeparateRoutes() {
|
||||
// NYC to LA on same day is infeasible
|
||||
let nycStadiumId = UUID()
|
||||
let laStadiumId = UUID()
|
||||
let nycStadiumId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let laStadiumId = "stadium_la_\(UUID().uuidString)"
|
||||
|
||||
let nycStadium = makeStadium(id: nycStadiumId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let laStadium = makeStadium(id: laStadiumId, city: "Los Angeles", lat: 34.0522, lon: -118.2437)
|
||||
@@ -191,7 +191,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.7 - Two games same stadium same day (doubleheader) succeeds")
|
||||
func test_findRoutes_TwoGames_SameStadiumSameDay_Succeeds() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
// Doubleheader: 1pm and 7pm same day, same stadium
|
||||
@@ -219,7 +219,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.8 - With anchors only returns routes containing all anchors")
|
||||
func test_findRoutes_WithAnchors_OnlyReturnsRoutesContainingAllAnchors() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
let game1 = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
@@ -246,8 +246,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.9 - Impossible anchors returns empty")
|
||||
func test_findRoutes_ImpossibleAnchors_ReturnsEmpty() {
|
||||
// Two anchors at opposite ends of country on same day - impossible to attend both
|
||||
let nycStadiumId = UUID()
|
||||
let laStadiumId = UUID()
|
||||
let nycStadiumId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let laStadiumId = "stadium_la_\(UUID().uuidString)"
|
||||
|
||||
let nycStadium = makeStadium(id: nycStadiumId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let laStadium = makeStadium(id: laStadiumId, city: "Los Angeles", lat: 34.0522, lon: -118.2437)
|
||||
@@ -271,9 +271,9 @@ struct GameDAGRouterTests {
|
||||
@Test("2.10 - Multiple anchors route must contain all")
|
||||
func test_findRoutes_MultipleAnchors_RouteMustContainAll() {
|
||||
// Three games in nearby cities over 3 days - all feasible
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -306,7 +306,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.11 - Allow repeat cities same city multiple days allowed")
|
||||
func test_findRoutes_AllowRepeatCities_SameCityMultipleDays_Allowed() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
// Three games in Chicago over 3 days
|
||||
@@ -330,8 +330,8 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.12 - Disallow repeat cities skips second visit")
|
||||
func test_findRoutes_DisallowRepeatCities_SkipsSecondVisit() {
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -360,7 +360,7 @@ struct GameDAGRouterTests {
|
||||
@Test("2.13 - Disallow repeat cities only option is repeat overrides with warning")
|
||||
func test_findRoutes_DisallowRepeatCities_OnlyOptionIsRepeat_OverridesWithWarning() {
|
||||
// When only games available are in the same city, we still need to produce routes
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
// Only Chicago games available
|
||||
@@ -388,8 +388,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.14 - Exceeds max daily driving transition rejected")
|
||||
func test_findRoutes_ExceedsMaxDailyDriving_TransitionRejected() {
|
||||
// NYC to Denver is ~1,800 miles, way over 8 hours of driving (480 miles at 60mph)
|
||||
let nycId = UUID()
|
||||
let denverId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let denverId = "stadium_denver_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let denver = makeStadium(id: denverId, city: "Denver", lat: 39.7392, lon: -104.9903)
|
||||
@@ -417,8 +417,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.15 - Multi-day drive allowed if within daily limits")
|
||||
func test_findRoutes_MultiDayDrive_Allowed_IfWithinDailyLimits() {
|
||||
// NYC to Chicago is ~790 miles - doable over multiple days
|
||||
let nycId = UUID()
|
||||
let chicagoId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -443,8 +443,8 @@ struct GameDAGRouterTests {
|
||||
@Test("2.16 - Same day different stadiums checks available time")
|
||||
func test_findRoutes_SameDayDifferentStadiums_ChecksAvailableTime() {
|
||||
// Chicago to Milwaukee is ~90 miles (~1.5 hours driving)
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -484,7 +484,7 @@ struct GameDAGRouterTests {
|
||||
@Test("2.17 - Max day lookahead respects limit")
|
||||
func test_findRoutes_MaxDayLookahead_RespectsLimit() {
|
||||
// Games more than 5 days apart should not connect directly
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
let game1 = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
@@ -514,7 +514,7 @@ struct GameDAGRouterTests {
|
||||
@Test("2.18 - DST transition handles correctly")
|
||||
func test_findRoutes_DSTTransition_HandlesCorrectly() {
|
||||
// Test around DST transition (March 9, 2026 - spring forward)
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
// Create dates around DST transition
|
||||
@@ -550,7 +550,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.19 - Midnight game assigns to correct day")
|
||||
func test_findRoutes_MidnightGame_AssignsToCorrectDay() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
// Game at 12:05 AM belongs to the new day
|
||||
@@ -583,7 +583,7 @@ struct GameDAGRouterTests {
|
||||
@Test("2.20 - Select diverse routes includes short and long trips")
|
||||
func test_selectDiverseRoutes_ShortAndLongTrips_BothRepresented() {
|
||||
// Create a mix of games over a week
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
var games: [Game] = []
|
||||
@@ -611,9 +611,9 @@ struct GameDAGRouterTests {
|
||||
@Test("2.21 - Select diverse routes includes high and low mileage")
|
||||
func test_selectDiverseRoutes_HighAndLowMileage_BothRepresented() {
|
||||
// Create games in both nearby and distant cities
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let laId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let laId = "stadium_la_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -647,11 +647,11 @@ struct GameDAGRouterTests {
|
||||
("Cleveland", 41.4993, -81.6944),
|
||||
]
|
||||
|
||||
var stadiums: [UUID: Stadium] = [:]
|
||||
var stadiums: [String: Stadium] = [:]
|
||||
var games: [Game] = []
|
||||
|
||||
for (index, city) in cities.enumerated() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
stadiums[stadiumId] = makeStadium(id: stadiumId, city: city.0, lat: city.1, lon: city.2)
|
||||
games.append(makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: index + 1)))
|
||||
}
|
||||
@@ -675,7 +675,7 @@ struct GameDAGRouterTests {
|
||||
|
||||
@Test("2.23 - Select diverse routes deduplicates")
|
||||
func test_selectDiverseRoutes_DuplicateRoutes_Deduplicated() {
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
let game1 = makeGame(stadiumId: stadiumId, dateTime: gameDate(daysFromNow: 1))
|
||||
@@ -693,7 +693,7 @@ struct GameDAGRouterTests {
|
||||
// Check for duplicates
|
||||
var seen = Set<String>()
|
||||
for route in routes {
|
||||
let key = route.map { $0.id.uuidString }.joined(separator: "-")
|
||||
let key = route.map { $0.id }.joined(separator: "-")
|
||||
#expect(!seen.contains(key), "Routes should be deduplicated")
|
||||
seen.insert(key)
|
||||
}
|
||||
@@ -704,9 +704,9 @@ struct GameDAGRouterTests {
|
||||
@Test("2.24 - Graph with potential cycle handles silently")
|
||||
func test_findRoutes_GraphWithPotentialCycle_HandlesSilently() {
|
||||
// Create a scenario where a naive algorithm might get stuck in a loop
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
|
||||
@@ -29,7 +29,7 @@ struct ItineraryBuilderTests {
|
||||
@Test("Single stop creates itinerary with one stop and no travel segments")
|
||||
func test_builder_SingleGame_CreatesSingleDay() {
|
||||
// Arrange
|
||||
let gameId = UUID()
|
||||
let gameId = "game_test_\(UUID().uuidString)"
|
||||
let stop = makeItineraryStop(
|
||||
city: "New York",
|
||||
state: "NY",
|
||||
@@ -60,9 +60,9 @@ struct ItineraryBuilderTests {
|
||||
func test_builder_MultiCity_CreatesTravelSegmentsBetween() {
|
||||
// Arrange
|
||||
let stops = [
|
||||
makeItineraryStop(city: "Boston", state: "MA", coordinate: boston, games: [UUID()]),
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: [UUID()]),
|
||||
makeItineraryStop(city: "Chicago", state: "IL", coordinate: chicago, games: [UUID()])
|
||||
makeItineraryStop(city: "Boston", state: "MA", coordinate: boston, games: ["game_boston_\(UUID().uuidString)"]),
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: ["game_nyc_\(UUID().uuidString)"]),
|
||||
makeItineraryStop(city: "Chicago", state: "IL", coordinate: chicago, games: ["game_chicago_\(UUID().uuidString)"])
|
||||
]
|
||||
|
||||
// Act
|
||||
@@ -103,8 +103,8 @@ struct ItineraryBuilderTests {
|
||||
func test_builder_SameCity_MultipleGames_GroupsOnSameDay() {
|
||||
// Arrange - Two stops in the same city (different games, same location)
|
||||
let stops = [
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: [UUID()]),
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: [UUID()])
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: ["game_nyc_1_\(UUID().uuidString)"]),
|
||||
makeItineraryStop(city: "New York", state: "NY", coordinate: nyc, games: ["game_nyc_2_\(UUID().uuidString)"])
|
||||
]
|
||||
|
||||
// Act
|
||||
@@ -141,8 +141,8 @@ struct ItineraryBuilderTests {
|
||||
// Boston to Chicago is ~850 miles haversine, ~1100 with road factor
|
||||
// At 60 mph, that's ~18 hours = 3 travel days (ceil(18/8) = 3)
|
||||
let stops = [
|
||||
makeItineraryStop(city: "Boston", state: "MA", coordinate: boston, games: [UUID()]),
|
||||
makeItineraryStop(city: "Chicago", state: "IL", coordinate: chicago, games: [UUID()])
|
||||
makeItineraryStop(city: "Boston", state: "MA", coordinate: boston, games: ["game_boston_\(UUID().uuidString)"]),
|
||||
makeItineraryStop(city: "Chicago", state: "IL", coordinate: chicago, games: ["game_chicago_\(UUID().uuidString)"])
|
||||
]
|
||||
|
||||
// Use constraints that allow long trips
|
||||
@@ -192,7 +192,7 @@ struct ItineraryBuilderTests {
|
||||
city: "Boston",
|
||||
state: "MA",
|
||||
coordinate: boston,
|
||||
games: [UUID()],
|
||||
games: ["game_boston_\(UUID().uuidString)"],
|
||||
departureDate: now
|
||||
)
|
||||
|
||||
@@ -201,7 +201,7 @@ struct ItineraryBuilderTests {
|
||||
city: "New York",
|
||||
state: "NY",
|
||||
coordinate: nyc,
|
||||
games: [UUID()],
|
||||
games: ["game_nyc_\(UUID().uuidString)"],
|
||||
firstGameStart: gameStartSoon
|
||||
)
|
||||
|
||||
@@ -231,7 +231,7 @@ struct ItineraryBuilderTests {
|
||||
city: "Boston",
|
||||
state: "MA",
|
||||
coordinate: boston,
|
||||
games: [UUID()],
|
||||
games: ["game_boston_\(UUID().uuidString)"],
|
||||
departureDate: now
|
||||
)
|
||||
|
||||
@@ -239,7 +239,7 @@ struct ItineraryBuilderTests {
|
||||
city: "New York",
|
||||
state: "NY",
|
||||
coordinate: nyc,
|
||||
games: [UUID()],
|
||||
games: ["game_nyc_\(UUID().uuidString)"],
|
||||
firstGameStart: gameLater
|
||||
)
|
||||
|
||||
@@ -283,7 +283,7 @@ struct ItineraryBuilderTests {
|
||||
city: String,
|
||||
state: String,
|
||||
coordinate: CLLocationCoordinate2D? = nil,
|
||||
games: [UUID] = [],
|
||||
games: [String] = [],
|
||||
arrivalDate: Date = Date(),
|
||||
departureDate: Date? = nil,
|
||||
firstGameStart: Date? = nil
|
||||
|
||||
@@ -39,8 +39,8 @@ struct RouteFiltersTests {
|
||||
coordinate: nil,
|
||||
arrivalDate: startDate,
|
||||
departureDate: end,
|
||||
games: [UUID()],
|
||||
stadium: UUID()
|
||||
games: ["game_test_\(UUID().uuidString)"],
|
||||
stadium: "stadium_test_\(UUID().uuidString)"
|
||||
)
|
||||
|
||||
return Trip(
|
||||
|
||||
@@ -31,7 +31,7 @@ struct ScenarioAPlannerTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -51,10 +51,10 @@ struct ScenarioAPlannerTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -74,8 +74,8 @@ struct ScenarioAPlannerTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
teams: [UUID: Team] = [:],
|
||||
stadiums: [String: Stadium],
|
||||
teams: [String: Team] = [:],
|
||||
allowRepeatCities: Bool = true,
|
||||
numberOfDrivers: Int = 1,
|
||||
maxDrivingHoursPerDriver: Double = 8.0,
|
||||
@@ -106,9 +106,9 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.1 - Valid date range returns games in range")
|
||||
func test_planByDates_ValidDateRange_ReturnsGamesInRange() {
|
||||
// Setup: 3 games across nearby cities over 5 days
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -144,7 +144,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.2 - Single day range returns games on that day")
|
||||
func test_planByDates_SingleDayRange_ReturnsGamesOnThatDay() {
|
||||
// Setup: Multiple games on a single day at the same stadium
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
@@ -182,10 +182,10 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.3 - Multi-week range returns multiple games")
|
||||
func test_planByDates_MultiWeekRange_ReturnsMultipleGames() {
|
||||
// Setup: Games spread across 3 weeks in nearby cities
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let clevelandId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -230,7 +230,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.4 - No games in range returns failure")
|
||||
func test_planByDates_NoGamesInRange_ThrowsError() {
|
||||
// Setup: Games outside the requested date range
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
@@ -257,7 +257,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.5 - End date before start date returns failure")
|
||||
func test_planByDates_EndDateBeforeStartDate_ThrowsError() {
|
||||
// Setup: Invalid date range where end < start
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
@@ -283,7 +283,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.6 - Single game in range returns single game route")
|
||||
func test_planByDates_SingleGameInRange_ReturnsSingleGameRoute() {
|
||||
// Setup: Only one game in the date range
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
@@ -354,9 +354,9 @@ struct ScenarioAPlannerTests {
|
||||
func test_planByDates_UsesDAGRouterForRouting() {
|
||||
// Setup: Games that require DAG routing logic
|
||||
// Create games in multiple cities with feasible transitions
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -403,8 +403,8 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.9 - Respects driver constraints")
|
||||
func test_planByDates_RespectsDriverConstraints() {
|
||||
// Setup: Games that would require excessive daily driving if constraints are loose
|
||||
let nycId = UUID()
|
||||
let chicagoId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
|
||||
// NYC to Chicago is ~790 miles (~13 hours of driving)
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -474,9 +474,9 @@ struct ScenarioAPlannerTests {
|
||||
func test_planByDates_MustStop_FiltersToGamesInCity() {
|
||||
// Setup: Games in Chicago, Milwaukee, Detroit
|
||||
// Must-stop = Chicago → should only return Chicago games
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -518,8 +518,8 @@ struct ScenarioAPlannerTests {
|
||||
func test_planByDates_MustStop_NoMatchingGames_ReturnsFailure() {
|
||||
// Setup: Games only in Milwaukee and Detroit
|
||||
// Must-stop = Chicago → no games there, should fail
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
let detroit = makeStadium(id: detroitId, city: "Detroit", lat: 42.3314, lon: -83.0458)
|
||||
@@ -553,10 +553,10 @@ struct ScenarioAPlannerTests {
|
||||
// Setup: Cubs home game in Chicago + Cubs away game in Milwaukee (playing at Milwaukee)
|
||||
// Must-stop = Chicago → should ONLY return the Chicago home game
|
||||
// This tests Issue #8: "Must stop needs to be home team"
|
||||
let chicagoStadiumId = UUID()
|
||||
let milwaukeeStadiumId = UUID()
|
||||
let cubsTeamId = UUID()
|
||||
let brewersTeamId = UUID()
|
||||
let chicagoStadiumId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeStadiumId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let cubsTeamId = "team_cubs_\(UUID().uuidString)"
|
||||
let brewersTeamId = "team_brewers_\(UUID().uuidString)"
|
||||
|
||||
let wrigleyField = makeStadium(id: chicagoStadiumId, city: "Chicago", lat: 41.9484, lon: -87.6553)
|
||||
let millerPark = makeStadium(id: milwaukeeStadiumId, city: "Milwaukee", lat: 43.0280, lon: -87.9712)
|
||||
@@ -608,7 +608,7 @@ struct ScenarioAPlannerTests {
|
||||
func test_planByDates_MustStop_PartialCityMatch_Works() {
|
||||
// Setup: User types "Chicago" but stadium city is "Chicago, IL"
|
||||
// Should still match via contains
|
||||
let chicagoId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [chicagoId: chicago]
|
||||
|
||||
@@ -636,7 +636,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.14 - Must-stop case insensitive")
|
||||
func test_planByDates_MustStop_CaseInsensitive() {
|
||||
// Setup: Must-stop = "CHICAGO" (uppercase) should match "Chicago"
|
||||
let chicagoId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [chicagoId: chicago]
|
||||
|
||||
@@ -662,7 +662,7 @@ struct ScenarioAPlannerTests {
|
||||
@Test("4.15 - Multiple games in must-stop city all included")
|
||||
func test_planByDates_MustStop_MultipleGamesInCity_AllIncluded() {
|
||||
// Setup: Multiple games in Chicago on different days
|
||||
let chicagoId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [chicagoId: chicago]
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -51,10 +51,10 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -74,9 +74,9 @@ struct ScenarioBPlannerTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
allGames: [Game],
|
||||
mustSeeGameIds: Set<UUID>,
|
||||
stadiums: [UUID: Stadium],
|
||||
teams: [UUID: Team] = [:],
|
||||
mustSeeGameIds: Set<String>,
|
||||
stadiums: [String: Stadium],
|
||||
teams: [String: Team] = [:],
|
||||
allowRepeatCities: Bool = true,
|
||||
numberOfDrivers: Int = 1,
|
||||
maxDrivingHoursPerDriver: Double = 8.0
|
||||
@@ -106,11 +106,11 @@ struct ScenarioBPlannerTests {
|
||||
@Test("5.1 - Single must-see game returns trip with that game")
|
||||
func test_mustSeeGames_SingleGame_ReturnsTripWithThatGame() {
|
||||
// Setup: Single must-see game
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let gameId = UUID()
|
||||
let gameId = "game_test_\(UUID().uuidString)"
|
||||
let game = makeGame(id: gameId, stadiumId: stadiumId, dateTime: makeDate(day: 10, hour: 19))
|
||||
|
||||
let request = makePlanningRequest(
|
||||
@@ -139,9 +139,9 @@ struct ScenarioBPlannerTests {
|
||||
func test_mustSeeGames_MultipleGames_ReturnsOptimalRoute() {
|
||||
// Setup: 3 must-see games in nearby cities (all Central region for single-region search)
|
||||
// Region boundary: Central is -110 to -85 longitude
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let stLouisId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let stLouisId = "stadium_stlouis_\(UUID().uuidString)"
|
||||
|
||||
// All cities in Central region (longitude between -110 and -85)
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -150,9 +150,9 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let stadiums = [chicagoId: chicago, milwaukeeId: milwaukee, stLouisId: stLouis]
|
||||
|
||||
let game1Id = UUID()
|
||||
let game2Id = UUID()
|
||||
let game3Id = UUID()
|
||||
let game1Id = "game_test_1_\(UUID().uuidString)"
|
||||
let game2Id = "game_test_2_\(UUID().uuidString)"
|
||||
let game3Id = "game_test_3_\(UUID().uuidString)"
|
||||
|
||||
let game1 = makeGame(id: game1Id, stadiumId: chicagoId, dateTime: makeDate(day: 5, hour: 19))
|
||||
let game2 = makeGame(id: game2Id, stadiumId: milwaukeeId, dateTime: makeDate(day: 7, hour: 19))
|
||||
@@ -187,8 +187,8 @@ struct ScenarioBPlannerTests {
|
||||
@Test("5.3 - Games in different cities are connected")
|
||||
func test_mustSeeGames_GamesInDifferentCities_ConnectsThem() {
|
||||
// Setup: 2 must-see games in distant but reachable cities
|
||||
let nycId = UUID()
|
||||
let bostonId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
|
||||
// NYC to Boston is ~215 miles (~4 hours driving)
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -196,8 +196,8 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let stadiums = [nycId: nyc, bostonId: boston]
|
||||
|
||||
let game1Id = UUID()
|
||||
let game2Id = UUID()
|
||||
let game1Id = "game_test_1_\(UUID().uuidString)"
|
||||
let game2Id = "game_test_2_\(UUID().uuidString)"
|
||||
|
||||
// Games 2 days apart - plenty of time to drive
|
||||
let game1 = makeGame(id: game1Id, stadiumId: nycId, dateTime: makeDate(day: 5, hour: 19))
|
||||
@@ -238,7 +238,7 @@ struct ScenarioBPlannerTests {
|
||||
@Test("5.4 - Empty selection returns failure")
|
||||
func test_mustSeeGames_EmptySelection_ThrowsError() {
|
||||
// Setup: No must-see games selected
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
@@ -266,8 +266,8 @@ struct ScenarioBPlannerTests {
|
||||
func test_mustSeeGames_ImpossibleToConnect_ThrowsError() {
|
||||
// Setup: Games on same day in cities ~850 miles apart (impossible in 8 hours)
|
||||
// Both cities in East region (> -85 longitude) so regional search covers both
|
||||
let nycId = UUID()
|
||||
let atlantaId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let atlantaId = "stadium_atlanta_\(UUID().uuidString)"
|
||||
|
||||
// NYC to Atlanta is ~850 miles (~13 hours driving) - impossible with 8-hour limit
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -275,8 +275,8 @@ struct ScenarioBPlannerTests {
|
||||
|
||||
let stadiums = [nycId: nyc, atlantaId: atlanta]
|
||||
|
||||
let game1Id = UUID()
|
||||
let game2Id = UUID()
|
||||
let game1Id = "game_test_1_\(UUID().uuidString)"
|
||||
let game2Id = "game_test_2_\(UUID().uuidString)"
|
||||
|
||||
// Same day games 6 hours apart - even if you left right after game 1,
|
||||
// you can't drive 850 miles in 6 hours with 8-hour daily limit
|
||||
@@ -409,10 +409,10 @@ struct ScenarioBPlannerTests {
|
||||
}
|
||||
|
||||
// Build coordinate map for brute force verification
|
||||
var stopCoordinates: [UUID: CLLocationCoordinate2D] = [:]
|
||||
var stopCoordinates: [String: CLLocationCoordinate2D] = [:]
|
||||
for stop in firstOption.stops {
|
||||
if let coord = stop.coordinate {
|
||||
stopCoordinates[stop.id] = coord
|
||||
stopCoordinates[stop.id.uuidString] = coord
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ struct ScenarioBPlannerTests {
|
||||
return
|
||||
}
|
||||
|
||||
let stopIds = firstOption.stops.map { $0.id }
|
||||
let stopIds = firstOption.stops.map { $0.id.uuidString }
|
||||
let verificationResult = BruteForceRouteVerifier.verify(
|
||||
proposedRoute: stopIds,
|
||||
stops: stopCoordinates,
|
||||
@@ -471,17 +471,17 @@ struct ScenarioBPlannerTests {
|
||||
#expect(!includedMustSee.isEmpty, "Should include some must-see games")
|
||||
|
||||
// Build coordinate map
|
||||
var stopCoordinates: [UUID: CLLocationCoordinate2D] = [:]
|
||||
var stopCoordinates: [String: CLLocationCoordinate2D] = [:]
|
||||
for stop in firstOption.stops {
|
||||
if let coord = stop.coordinate {
|
||||
stopCoordinates[stop.id] = coord
|
||||
stopCoordinates[stop.id.uuidString] = coord
|
||||
}
|
||||
}
|
||||
|
||||
// Check that there's no obviously better route (10% threshold)
|
||||
guard stopCoordinates.count >= 2 else { return }
|
||||
|
||||
let stopIds = firstOption.stops.map { $0.id }
|
||||
let stopIds = firstOption.stops.map { $0.id.uuidString }
|
||||
let (hasBetter, improvement) = BruteForceRouteVerifier.hasObviouslyBetterRoute(
|
||||
proposedRoute: stopIds,
|
||||
stops: stopCoordinates,
|
||||
|
||||
@@ -32,7 +32,7 @@ struct ScenarioCPlannerTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
state: String = "ST",
|
||||
lat: Double,
|
||||
@@ -53,10 +53,10 @@ struct ScenarioCPlannerTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -91,8 +91,8 @@ struct ScenarioCPlannerTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
allGames: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
teams: [UUID: Team] = [:],
|
||||
stadiums: [String: Stadium],
|
||||
teams: [String: Team] = [:],
|
||||
mustStopLocations: [LocationInput] = [],
|
||||
allowRepeatCities: Bool = true,
|
||||
numberOfDrivers: Int = 1,
|
||||
@@ -127,8 +127,8 @@ struct ScenarioCPlannerTests {
|
||||
func test_departReturn_SameCity_ReturnsRoundTrip() {
|
||||
// Setup: Start and end in Chicago
|
||||
// Create stadiums in Chicago and a nearby city (Milwaukee) for games along the route
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -169,10 +169,10 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.2 - Different cities creates one-way route")
|
||||
func test_departReturn_DifferentCities_ReturnsOneWayRoute() {
|
||||
// Setup: Boston to Washington DC corridor (East Coast)
|
||||
let bostonId = UUID()
|
||||
let nycId = UUID()
|
||||
let phillyId = UUID()
|
||||
let dcId = UUID()
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let phillyId = "stadium_philly_\(UUID().uuidString)"
|
||||
let dcId = "stadium_dc_\(UUID().uuidString)"
|
||||
|
||||
// East Coast corridor from north to south
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", state: "MA", lat: 42.3601, lon: -71.0589)
|
||||
@@ -220,10 +220,10 @@ struct ScenarioCPlannerTests {
|
||||
func test_departReturn_GamesAlongCorridor_IncludesNearbyGames() {
|
||||
// Setup: Chicago to St. Louis corridor
|
||||
// Include games that are "along the way" (directional)
|
||||
let chicagoId = UUID()
|
||||
let springfieldId = UUID()
|
||||
let stLouisId = UUID()
|
||||
let milwaukeeId = UUID() // This is NOT along the route (north of Chicago)
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let springfieldId = "stadium_springfield_\(UUID().uuidString)"
|
||||
let stLouisId = "stadium_stlouis_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)" // This is NOT along the route (north of Chicago)
|
||||
|
||||
// Chicago to St. Louis is ~300 miles south
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -280,9 +280,9 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.4 - No games along route returns failure")
|
||||
func test_departReturn_NoGamesAlongRoute_ThrowsError() {
|
||||
// Setup: Start/end cities have no games
|
||||
let chicagoId = UUID()
|
||||
let stLouisId = UUID()
|
||||
let seattleId = UUID() // Games here, but not along Chicago-St. Louis route
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let stLouisId = "stadium_stlouis_\(UUID().uuidString)"
|
||||
let seattleId = "stadium_seattle_\(UUID().uuidString)" // Games here, but not along Chicago-St. Louis route
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stLouis = makeStadium(id: stLouisId, city: "St. Louis", lat: 38.6270, lon: -90.1994)
|
||||
@@ -325,7 +325,7 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.5 - Invalid city (no stadiums) returns failure")
|
||||
func test_departReturn_InvalidCity_ThrowsError() {
|
||||
// Setup: Start location is a city with no stadium
|
||||
let chicagoId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [chicagoId: chicago]
|
||||
|
||||
@@ -357,10 +357,10 @@ struct ScenarioCPlannerTests {
|
||||
func test_departReturn_ExtremeDistance_RespectsConstraints() {
|
||||
// Setup: NYC to LA route (~2,800 miles)
|
||||
// With 8 hours/day at 60 mph = 480 miles/day, this takes ~6 days just driving
|
||||
let nycId = UUID()
|
||||
let laId = UUID()
|
||||
let chicagoId = UUID() // Along the route
|
||||
let denverID = UUID() // Along the route
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let laId = "stadium_la_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)" // Along the route
|
||||
let denverID = "stadium_denver_\(UUID().uuidString)" // Along the route
|
||||
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let la = makeStadium(id: laId, city: "Los Angeles", lat: 34.0522, lon: -118.2437)
|
||||
@@ -426,9 +426,9 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.7 - Must-stop location is included in route")
|
||||
func test_departReturn_WithMustStopLocation_IncludesStop() {
|
||||
// Setup: Boston to DC with must-stop in Philadelphia
|
||||
let bostonId = UUID()
|
||||
let phillyId = UUID()
|
||||
let dcId = UUID()
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
let phillyId = "stadium_philly_\(UUID().uuidString)"
|
||||
let dcId = "stadium_dc_\(UUID().uuidString)"
|
||||
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", lat: 42.3601, lon: -71.0589)
|
||||
let philly = makeStadium(id: phillyId, city: "Philadelphia", lat: 39.9526, lon: -75.1652)
|
||||
@@ -476,8 +476,8 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.8 - Must-stop with no nearby games is still included")
|
||||
func test_departReturn_MustStopNoNearbyGames_IncludesStopAnyway() {
|
||||
// Setup: Boston to DC with must-stop in a city without games
|
||||
let bostonId = UUID()
|
||||
let dcId = UUID()
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
let dcId = "stadium_dc_\(UUID().uuidString)"
|
||||
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", lat: 42.3601, lon: -71.0589)
|
||||
let dc = makeStadium(id: dcId, city: "Washington", lat: 38.9072, lon: -77.0369)
|
||||
@@ -528,10 +528,10 @@ struct ScenarioCPlannerTests {
|
||||
@Test("6.9 - Multiple must-stops are all included")
|
||||
func test_departReturn_MultipleMustStops_AllIncluded() {
|
||||
// Setup: Boston to DC with must-stops in NYC and Philadelphia
|
||||
let bostonId = UUID()
|
||||
let nycId = UUID()
|
||||
let phillyId = UUID()
|
||||
let dcId = UUID()
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let phillyId = "stadium_philly_\(UUID().uuidString)"
|
||||
let dcId = "stadium_dc_\(UUID().uuidString)"
|
||||
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", lat: 42.3601, lon: -71.0589)
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -588,10 +588,10 @@ struct ScenarioCPlannerTests {
|
||||
func test_departReturn_MustStopConflictsWithRoute_FindsCompromise() {
|
||||
// Setup: Boston to DC with must-stop that's slightly off the optimal route
|
||||
// Cleveland is west of the Boston-DC corridor but could be included with detour
|
||||
let bostonId = UUID()
|
||||
let dcId = UUID()
|
||||
let clevelandId = UUID()
|
||||
let pittsburghId = UUID()
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
let dcId = "stadium_dc_\(UUID().uuidString)"
|
||||
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
|
||||
let pittsburghId = "stadium_pittsburgh_\(UUID().uuidString)"
|
||||
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", lat: 42.3601, lon: -71.0589)
|
||||
let dc = makeStadium(id: dcId, city: "Washington", lat: 38.9072, lon: -77.0369)
|
||||
|
||||
@@ -31,7 +31,7 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -51,9 +51,9 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
/// Creates a team
|
||||
private func makeTeam(
|
||||
id: UUID = UUID(),
|
||||
id: String = "team_test_\(UUID().uuidString)",
|
||||
name: String,
|
||||
stadiumId: UUID,
|
||||
stadiumId: String,
|
||||
sport: Sport = .mlb
|
||||
) -> Team {
|
||||
Team(
|
||||
@@ -71,10 +71,10 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID,
|
||||
awayTeamId: UUID,
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String,
|
||||
awayTeamId: String,
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -93,10 +93,10 @@ struct ScenarioDPlannerTests {
|
||||
private func makePlanningRequest(
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
followTeamId: UUID?,
|
||||
followTeamId: String?,
|
||||
allGames: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
teams: [UUID: Team] = [:],
|
||||
stadiums: [String: Stadium],
|
||||
teams: [String: Team] = [:],
|
||||
selectedRegions: Set<Region> = [],
|
||||
allowRepeatCities: Bool = true,
|
||||
useHomeLocation: Bool = false,
|
||||
@@ -132,12 +132,12 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.1.1 - Single team with home games returns trip with those games")
|
||||
func test_followTeam_HomeGames_ReturnsTrip() {
|
||||
// Setup: Team with 2 home games
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
let team = makeTeam(id: teamId, name: "Chicago Cubs", stadiumId: stadiumId)
|
||||
|
||||
let game1 = makeGame(
|
||||
@@ -179,8 +179,8 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.1.2 - Team with away games includes those games")
|
||||
func test_followTeam_AwayGames_IncludesAwayGames() {
|
||||
// Setup: Team with one home game and one away game (2 cities for simpler route)
|
||||
let homeStadiumId = UUID()
|
||||
let awayStadiumId = UUID()
|
||||
let homeStadiumId = "stadium_home_\(UUID().uuidString)"
|
||||
let awayStadiumId = "stadium_away_\(UUID().uuidString)"
|
||||
|
||||
let homeStadium = makeStadium(id: homeStadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let awayStadium = makeStadium(id: awayStadiumId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -190,8 +190,8 @@ struct ScenarioDPlannerTests {
|
||||
awayStadiumId: awayStadium
|
||||
]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
|
||||
// Home game
|
||||
let homeGame = makeGame(
|
||||
@@ -237,8 +237,8 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.1.3 - Team games filtered by selected regions")
|
||||
func test_followTeam_RegionFilter_FiltersGames() {
|
||||
// Setup: Team with games in multiple regions
|
||||
let eastStadiumId = UUID()
|
||||
let centralStadiumId = UUID()
|
||||
let eastStadiumId = "stadium_east_\(UUID().uuidString)"
|
||||
let centralStadiumId = "stadium_central_\(UUID().uuidString)"
|
||||
|
||||
// East region (> -85 longitude)
|
||||
let eastStadium = makeStadium(id: eastStadiumId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -247,8 +247,8 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
let stadiums = [eastStadiumId: eastStadium, centralStadiumId: centralStadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
|
||||
let eastGame = makeGame(
|
||||
stadiumId: eastStadiumId,
|
||||
@@ -292,14 +292,14 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.2.1 - No team selected returns missingTeamSelection failure")
|
||||
func test_followTeam_NoTeamSelected_ReturnsMissingTeamSelection() {
|
||||
// Setup: No team ID
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let game = makeGame(
|
||||
stadiumId: stadiumId,
|
||||
homeTeamId: UUID(),
|
||||
awayTeamId: UUID(),
|
||||
homeTeamId: "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: "team_opponent_\(UUID().uuidString)",
|
||||
dateTime: makeDate(day: 5, hour: 19)
|
||||
)
|
||||
|
||||
@@ -323,17 +323,17 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.2.2 - Team with no games in date range returns noGamesInRange failure")
|
||||
func test_followTeam_NoGamesInRange_ReturnsNoGamesFailure() {
|
||||
// Setup: Team's games are outside date range
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
|
||||
// Game is in July, but we search June
|
||||
let game = makeGame(
|
||||
stadiumId: stadiumId,
|
||||
homeTeamId: teamId,
|
||||
awayTeamId: UUID(),
|
||||
awayTeamId: "team_opponent_\(UUID().uuidString)",
|
||||
dateTime: makeDate(month: 7, day: 15, hour: 19)
|
||||
)
|
||||
|
||||
@@ -357,13 +357,13 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.2.3 - Team not involved in any games returns noGamesInRange failure")
|
||||
func test_followTeam_TeamNotInGames_ReturnsNoGamesFailure() {
|
||||
// Setup: Games exist but team isn't playing
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let otherTeam1 = UUID()
|
||||
let otherTeam2 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let otherTeam1 = "team_other1_\(UUID().uuidString)"
|
||||
let otherTeam2 = "team_other2_\(UUID().uuidString)"
|
||||
|
||||
// Game between other teams
|
||||
let game = makeGame(
|
||||
@@ -393,12 +393,12 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.2.4 - Repeat city filter removes duplicate city visits")
|
||||
func test_followTeam_RepeatCityFilter_RemovesDuplicates() {
|
||||
// Setup: Team has multiple games at same stadium
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
|
||||
let game1 = makeGame(
|
||||
stadiumId: stadiumId,
|
||||
@@ -445,16 +445,16 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.2.5 - Missing date range returns missingDateRange failure")
|
||||
func test_followTeam_MissingDateRange_ReturnsMissingDateRangeFailure() {
|
||||
// Setup: Invalid date range (end before start)
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
let teamId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
|
||||
let game = makeGame(
|
||||
stadiumId: stadiumId,
|
||||
homeTeamId: teamId,
|
||||
awayTeamId: UUID(),
|
||||
awayTeamId: "team_opponent_\(UUID().uuidString)",
|
||||
dateTime: makeDate(day: 5, hour: 19)
|
||||
)
|
||||
|
||||
@@ -481,16 +481,16 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.3.1 - Route connects team games chronologically")
|
||||
func test_followTeam_RouteIsChronological() {
|
||||
// Setup: Team with games in 2 nearby cities chronologically
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
|
||||
let stadiums = [chicagoId: chicago, milwaukeeId: milwaukee]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
|
||||
// Games in chronological order: Chicago → Milwaukee
|
||||
let game1 = makeGame(
|
||||
@@ -534,16 +534,16 @@ struct ScenarioDPlannerTests {
|
||||
@Test("D.3.2 - Travel segments connect stops correctly")
|
||||
func test_followTeam_TravelSegmentsConnectStops() {
|
||||
// Setup: Team with 2 games in different cities
|
||||
let nycId = UUID()
|
||||
let bostonId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let bostonId = "stadium_boston_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let boston = makeStadium(id: bostonId, city: "Boston", lat: 42.3601, lon: -71.0589)
|
||||
|
||||
let stadiums = [nycId: nyc, bostonId: boston]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponentId = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponentId = "team_opponent_\(UUID().uuidString)"
|
||||
|
||||
let game1 = makeGame(
|
||||
stadiumId: nycId,
|
||||
@@ -597,9 +597,9 @@ struct ScenarioDPlannerTests {
|
||||
// Setup: Simulates Houston → Chicago → Anaheim (Astros July 20-29 scenario)
|
||||
// Houston to Chicago: ~1000 miles, Chicago to Anaheim: ~2000 miles
|
||||
// With 4+ days between each leg, both should be feasible
|
||||
let houstonId = UUID()
|
||||
let chicagoId = UUID()
|
||||
let anaheimId = UUID()
|
||||
let houstonId = "stadium_houston_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let anaheimId = "stadium_anaheim_\(UUID().uuidString)"
|
||||
|
||||
let houston = makeStadium(id: houstonId, city: "Houston", lat: 29.7604, lon: -95.3698)
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -607,10 +607,10 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
let stadiums = [houstonId: houston, chicagoId: chicago, anaheimId: anaheim]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let opponent3 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
let opponent3 = "team_opponent3_\(UUID().uuidString)"
|
||||
|
||||
// Houston home games: July 20-22
|
||||
let houstonGame = makeGame(
|
||||
@@ -674,9 +674,9 @@ struct ScenarioDPlannerTests {
|
||||
func test_followTeam_ThreeCityRoute_InsufficientTime_ExcludesUnreachableCities() {
|
||||
// Setup: Same cities but games too close together
|
||||
// Chicago to Anaheim needs ~37 hours driving, but only 1 day between games
|
||||
let houstonId = UUID()
|
||||
let chicagoId = UUID()
|
||||
let anaheimId = UUID()
|
||||
let houstonId = "stadium_houston_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let anaheimId = "stadium_anaheim_\(UUID().uuidString)"
|
||||
|
||||
let houston = makeStadium(id: houstonId, city: "Houston", lat: 29.7604, lon: -95.3698)
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -684,10 +684,10 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
let stadiums = [houstonId: houston, chicagoId: chicago, anaheimId: anaheim]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let opponent3 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
let opponent3 = "team_opponent3_\(UUID().uuidString)"
|
||||
|
||||
// Houston: July 20
|
||||
let houstonGame = makeGame(
|
||||
@@ -744,17 +744,17 @@ struct ScenarioDPlannerTests {
|
||||
func test_followTeam_PicksOptimalGamePerCity_ForRouteFeasibility() {
|
||||
// Setup: Team has 3 games in each city (series)
|
||||
// With allowRepeatCities=false, router should pick games that make the route work
|
||||
let chicagoId = UUID()
|
||||
let anaheimId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let anaheimId = "stadium_anaheim_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let anaheim = makeStadium(id: anaheimId, city: "Anaheim", lat: 33.8003, lon: -117.8827)
|
||||
|
||||
let stadiums = [chicagoId: chicago, anaheimId: anaheim]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
|
||||
// Chicago series: July 24, 25, 26
|
||||
let chicagoGame1 = makeGame(
|
||||
@@ -826,8 +826,8 @@ struct ScenarioDPlannerTests {
|
||||
func test_followTeam_FiveDaySegment_AtLimit_Succeeds() {
|
||||
// Setup: ~38 hours of driving with exactly 5 days between games
|
||||
// 5 days × 8 hours = 40 hours max, which should pass
|
||||
let seattleId = UUID()
|
||||
let miamiId = UUID()
|
||||
let seattleId = "stadium_seattle_\(UUID().uuidString)"
|
||||
let miamiId = "stadium_denver_\(UUID().uuidString)"
|
||||
|
||||
// Seattle to Miami: ~3,300 miles straight line × 1.3 = ~4,300 miles
|
||||
// At 60 mph = ~72 hours - this is too far even for 5 days
|
||||
@@ -837,9 +837,9 @@ struct ScenarioDPlannerTests {
|
||||
|
||||
let stadiums = [seattleId: seattle, miamiId: denver]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
|
||||
let seattleGame = makeGame(
|
||||
stadiumId: seattleId,
|
||||
@@ -889,17 +889,17 @@ struct ScenarioDPlannerTests {
|
||||
// Setup: Distance that would take > 40 hours to drive
|
||||
// Seattle to Miami: ~3,300 miles straight line × 1.3 = ~4,300 miles
|
||||
// At 60 mph = ~72 hours - exceeds 40 hour (5 day) limit
|
||||
let seattleId = UUID()
|
||||
let miamiId = UUID()
|
||||
let seattleId = "stadium_seattle_\(UUID().uuidString)"
|
||||
let miamiId = "stadium_miami_\(UUID().uuidString)"
|
||||
|
||||
let seattle = makeStadium(id: seattleId, city: "Seattle", lat: 47.6062, lon: -122.3321)
|
||||
let miami = makeStadium(id: miamiId, city: "Miami", lat: 25.7617, lon: -80.1918)
|
||||
|
||||
let stadiums = [seattleId: seattle, miamiId: miami]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
|
||||
let seattleGame = makeGame(
|
||||
stadiumId: seattleId,
|
||||
@@ -950,17 +950,17 @@ struct ScenarioDPlannerTests {
|
||||
// Setup: Same Chicago→Anaheim route but with 2 drivers
|
||||
// With 2 drivers × 8 hours = 16 hours/day
|
||||
// Chicago to Anaheim in 3 days = 48 hours available (vs 24 hours with 1 driver)
|
||||
let chicagoId = UUID()
|
||||
let anaheimId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let anaheimId = "stadium_anaheim_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let anaheim = makeStadium(id: anaheimId, city: "Anaheim", lat: 33.8003, lon: -117.8827)
|
||||
|
||||
let stadiums = [chicagoId: chicago, anaheimId: anaheim]
|
||||
|
||||
let teamId = UUID()
|
||||
let opponent1 = UUID()
|
||||
let opponent2 = UUID()
|
||||
let teamId = "team_test_\(UUID().uuidString)"
|
||||
let opponent1 = "team_opponent1_\(UUID().uuidString)"
|
||||
let opponent2 = "team_opponent2_\(UUID().uuidString)"
|
||||
|
||||
let chicagoGame = makeGame(
|
||||
stadiumId: chicagoId,
|
||||
|
||||
@@ -35,7 +35,7 @@ struct TripPlanningEngineTests {
|
||||
|
||||
/// Creates a stadium at a known location
|
||||
private func makeStadium(
|
||||
id: UUID = UUID(),
|
||||
id: String = "stadium_test_\(UUID().uuidString)",
|
||||
city: String,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
@@ -55,10 +55,10 @@ struct TripPlanningEngineTests {
|
||||
|
||||
/// Creates a game at a stadium
|
||||
private func makeGame(
|
||||
id: UUID = UUID(),
|
||||
stadiumId: UUID,
|
||||
homeTeamId: UUID = UUID(),
|
||||
awayTeamId: UUID = UUID(),
|
||||
id: String = "game_test_\(UUID().uuidString)",
|
||||
stadiumId: String,
|
||||
homeTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
awayTeamId: String = "team_test_\(UUID().uuidString)",
|
||||
dateTime: Date,
|
||||
sport: Sport = .mlb
|
||||
) -> Game {
|
||||
@@ -78,7 +78,7 @@ struct TripPlanningEngineTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
stadiums: [String: Stadium],
|
||||
numberOfDrivers: Int = 1,
|
||||
maxDrivingHoursPerDriver: Double = 8.0,
|
||||
allowRepeatCities: Bool = true
|
||||
@@ -104,11 +104,11 @@ struct TripPlanningEngineTests {
|
||||
|
||||
/// Creates a PlanningRequest for Scenario B (selected games)
|
||||
private func makeScenarioBRequest(
|
||||
mustSeeGameIds: Set<UUID>,
|
||||
mustSeeGameIds: Set<String>,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
stadiums: [String: Stadium],
|
||||
numberOfDrivers: Int = 1,
|
||||
maxDrivingHoursPerDriver: Double = 8.0,
|
||||
allowRepeatCities: Bool = true
|
||||
@@ -140,7 +140,7 @@ struct TripPlanningEngineTests {
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium],
|
||||
stadiums: [String: Stadium],
|
||||
numberOfDrivers: Int = 1,
|
||||
maxDrivingHoursPerDriver: Double = 8.0
|
||||
) -> PlanningRequest {
|
||||
@@ -169,8 +169,8 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.1 - Engine delegates to Scenario A correctly")
|
||||
func test_engine_ScenarioA_DelegatesCorrectly() {
|
||||
// Setup: Date range only request (Scenario A)
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -202,8 +202,8 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.2 - Engine delegates to Scenario B correctly")
|
||||
func test_engine_ScenarioB_DelegatesCorrectly() {
|
||||
// Setup: Selected games request (Scenario B)
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -244,9 +244,9 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.3 - Engine delegates to Scenario C correctly")
|
||||
func test_engine_ScenarioC_DelegatesCorrectly() {
|
||||
// Setup: Start/end locations request (Scenario C)
|
||||
let chicagoId = UUID()
|
||||
let clevelandId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let cleveland = makeStadium(id: clevelandId, city: "Cleveland", lat: 41.4993, lon: -81.6944)
|
||||
@@ -294,8 +294,8 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.4 - Scenarios are mutually exclusive")
|
||||
func test_engine_ScenariosAreMutuallyExclusive() {
|
||||
// Setup: Create requests that could theoretically match multiple scenarios
|
||||
let chicagoId = UUID()
|
||||
let clevelandId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let cleveland = makeStadium(id: clevelandId, city: "Cleveland", lat: 41.4993, lon: -81.6944)
|
||||
@@ -350,9 +350,9 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.5 - Result contains travel segments")
|
||||
func test_engine_Result_ContainsTravelSegments() {
|
||||
// Setup: Multi-city trip that requires travel
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let detroitId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
let detroitId = "stadium_detroit_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -396,8 +396,8 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.6 - Result contains itinerary days")
|
||||
func test_engine_Result_ContainsItineraryDays() {
|
||||
// Setup: Multi-day trip
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -445,7 +445,7 @@ struct TripPlanningEngineTests {
|
||||
func test_engine_Result_IncludesWarnings_WhenApplicable() {
|
||||
// Setup: Request that would normally violate repeat cities
|
||||
// but allowRepeatCities=true so it should succeed without warnings
|
||||
let chicagoId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
|
||||
@@ -497,8 +497,8 @@ struct TripPlanningEngineTests {
|
||||
func test_engine_NumberOfDrivers_AffectsMaxDailyDriving() {
|
||||
// Setup: Long distance trip that requires significant driving
|
||||
// NYC to Chicago is ~790 miles (~13 hours of driving)
|
||||
let nycId = UUID()
|
||||
let chicagoId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
@@ -593,8 +593,8 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.10 - AllowRepeatCities is propagated to DAG")
|
||||
func test_engine_AllowRepeatCities_PropagatedToDAG() {
|
||||
// Setup: Games that would require visiting the same city twice
|
||||
let chicagoId = UUID()
|
||||
let milwaukeeId = UUID()
|
||||
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
|
||||
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
|
||||
|
||||
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
|
||||
@@ -657,8 +657,8 @@ struct TripPlanningEngineTests {
|
||||
func test_engine_ImpossibleConstraints_ReturnsNoResult() {
|
||||
// Setup: Create an impossible constraint scenario
|
||||
// Games at the same time on same day in cities far apart (can't make both)
|
||||
let nycId = UUID()
|
||||
let laId = UUID()
|
||||
let nycId = "stadium_nyc_\(UUID().uuidString)"
|
||||
let laId = "stadium_la_\(UUID().uuidString)"
|
||||
|
||||
// NYC to LA is ~2,800 miles - impossible to drive same day
|
||||
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
|
||||
@@ -711,7 +711,7 @@ struct TripPlanningEngineTests {
|
||||
@Test("7.12 - Empty input returns error")
|
||||
func test_engine_EmptyInput_ThrowsError() {
|
||||
// Setup: Request with no games
|
||||
let stadiumId = UUID()
|
||||
let stadiumId = "stadium_test_\(UUID().uuidString)"
|
||||
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
|
||||
let stadiums = [stadiumId: stadium]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user