Files
Sportstime/SportsTimeTests/Domain/GameTests.swift
Trey T a6f538dfed Audit and fix 52 test correctness issues across 22 files
Systematic audit of 1,191 tests found tests written to pass rather than
verify correctness. Key fixes:

Infrastructure:
- TestClock: fixed timezone from .current to America/New_York (deterministic)
- TestFixtures: added 1.3x road routing factor to match production
- ItineraryTestHelpers: real per-city coordinates instead of hardcoded (40,-80)

Planning tests:
- Added missing Scenario E factory dispatch tests
- Tightened 12 loose assertions (>= 1 → == 8.0, > 0 → range checks)
- Fixed 4 no-op tests that accepted both success and failure
- Fixed wrong repeat-city invariant (was checking same-day, not different-day)
- Fixed tautological assertion in missing-stadium edge case

Services/Domain/Export tests:
- Replaced 4 placeholder tests (#expect(true)) with real assertions
- Fixed tautological assertions in POISearchServiceTests
- Fixed Chicago coordinate in RegionMapSelectorTests (-89 → -87.6553)
- Added sort order verification to ItineraryRowFlatteningTests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 23:00:46 -05:00

211 lines
6.4 KiB
Swift

//
// GameTests.swift
// SportsTimeTests
//
// TDD specification tests for Game model.
//
import Testing
import Foundation
@testable import SportsTime
@Suite("Game")
@MainActor
struct GameTests {
// MARK: - Test Data
private func makeGame(dateTime: Date) -> Game {
Game(
id: "game1",
homeTeamId: "team1",
awayTeamId: "team2",
stadiumId: "stadium1",
dateTime: dateTime,
sport: .mlb,
season: "2026",
isPlayoff: false
)
}
// MARK: - Specification Tests: gameDate
@Test("gameDate returns start of day for dateTime")
func gameDate_returnsStartOfDay() {
// Use TestFixtures.date which creates dates at 7:05 PM EST safely same
// calendar day in any US timezone when interpreted by Calendar.current.
let dateTime = TestFixtures.date(year: 2026, month: 6, day: 15, hour: 19, minute: 5)
let game = makeGame(dateTime: dateTime)
// Production gameDate uses Calendar.current, so assert with the same calendar
let systemCalendar = Calendar.current
let expectedStart = systemCalendar.startOfDay(for: dateTime)
#expect(game.gameDate == expectedStart)
// Verify it's at midnight in the system calendar
let components = systemCalendar.dateComponents([.hour, .minute, .second], from: game.gameDate)
#expect(components.hour == 0)
#expect(components.minute == 0)
#expect(components.second == 0)
}
@Test("gameDate is same for games on same calendar day")
func gameDate_sameDay() {
let calendar = TestClock.calendar
// Morning game
let morningTime = calendar.date(from: DateComponents(
year: 2026, month: 6, day: 15,
hour: 10, minute: 0
))!
// Evening game
let eveningTime = calendar.date(from: DateComponents(
year: 2026, month: 6, day: 15,
hour: 20, minute: 0
))!
let morningGame = makeGame(dateTime: morningTime)
let eveningGame = makeGame(dateTime: eveningTime)
#expect(morningGame.gameDate == eveningGame.gameDate)
}
@Test("gameDate differs for games on different calendar days")
func gameDate_differentDays() {
let calendar = TestClock.calendar
let day1 = calendar.date(from: DateComponents(
year: 2026, month: 6, day: 15, hour: 19
))!
let day2 = calendar.date(from: DateComponents(
year: 2026, month: 6, day: 16, hour: 19
))!
let game1 = makeGame(dateTime: day1)
let game2 = makeGame(dateTime: day2)
#expect(game1.gameDate != game2.gameDate)
}
// MARK: - Specification Tests: startTime Alias
@Test("startTime is alias for dateTime")
func startTime_isAliasForDateTime() {
let dateTime = TestClock.now
let game = makeGame(dateTime: dateTime)
#expect(game.startTime == game.dateTime)
}
// MARK: - Specification Tests: Equality
@Test("equality based on id only")
func equality_basedOnId() {
let dateTime = TestClock.now
let game1 = Game(
id: "game1",
homeTeamId: "team1",
awayTeamId: "team2",
stadiumId: "stadium1",
dateTime: dateTime,
sport: .mlb,
season: "2026",
isPlayoff: false
)
// Same id, different fields
let game2 = Game(
id: "game1",
homeTeamId: "different-team",
awayTeamId: "different-team2",
stadiumId: "different-stadium",
dateTime: dateTime.addingTimeInterval(3600),
sport: .nba,
season: "2027",
isPlayoff: true
)
#expect(game1 == game2, "Games with same id should be equal")
}
@Test("inequality when ids differ")
func inequality_differentIds() {
let dateTime = TestClock.now
let game1 = Game(
id: "game1",
homeTeamId: "team1",
awayTeamId: "team2",
stadiumId: "stadium1",
dateTime: dateTime,
sport: .mlb,
season: "2026",
isPlayoff: false
)
let game2 = Game(
id: "game2",
homeTeamId: "team1",
awayTeamId: "team2",
stadiumId: "stadium1",
dateTime: dateTime,
sport: .mlb,
season: "2026",
isPlayoff: false
)
#expect(game1 != game2, "Games with different ids should not be equal")
}
// MARK: - Invariant Tests
@Test("Invariant: gameDate is always at midnight")
func invariant_gameDateAtMidnight() {
// Production gameDate uses Calendar.current, so create dates and assert
// with Calendar.current to avoid cross-timezone mismatches.
// Use TestFixtures.date (7pm EST default) to ensure same calendar day in any US tz.
let times = [8, 12, 15, 19, 22].map { hour in
TestFixtures.date(year: 2026, month: 6, day: 15, hour: hour)
}
let systemCalendar = Calendar.current
for time in times {
let game = makeGame(dateTime: time)
let components = systemCalendar.dateComponents([.hour, .minute, .second], from: game.gameDate)
#expect(components.hour == 0, "gameDate hour should be 0")
#expect(components.minute == 0, "gameDate minute should be 0")
#expect(components.second == 0, "gameDate second should be 0")
}
}
@Test("Invariant: startTime equals dateTime")
func invariant_startTimeEqualsDateTime() {
for _ in 0..<10 {
let dateTime = TestClock.now.addingTimeInterval(Double.random(in: -86400...86400))
let game = makeGame(dateTime: dateTime)
#expect(game.startTime == game.dateTime)
}
}
// MARK: - Property Tests
@Test("Property: gameDate is in same calendar day as dateTime")
func property_gameDateSameCalendarDay() {
let calendar = TestClock.calendar
let dateTime = calendar.date(from: DateComponents(
year: 2026, month: 7, day: 4, hour: 19, minute: 5
))!
let game = makeGame(dateTime: dateTime)
let dateTimeDay = calendar.component(.day, from: dateTime)
let gameDateDay = calendar.component(.day, from: game.gameDate)
#expect(dateTimeDay == gameDateDay)
}
}