Files
Sportstime/SportsTimeTests/Export/PDFGeneratorTests.swift
Trey t 8162b4a029 refactor(tests): TDD rewrite of all unit tests with spec documentation
Complete rewrite of unit test suite using TDD methodology:

Planning Engine Tests:
- GameDAGRouterTests: Beam search, anchor games, transitions
- ItineraryBuilderTests: Stop connection, validators, EV enrichment
- RouteFiltersTests: Region, time window, scoring filters
- ScenarioA/B/C/D PlannerTests: All planning scenarios
- TravelEstimatorTests: Distance, duration, travel days
- TripPlanningEngineTests: Orchestration, caching, preferences

Domain Model Tests:
- AchievementDefinitionsTests, AnySportTests, DivisionTests
- GameTests, ProgressTests, RegionTests, StadiumTests
- TeamTests, TravelSegmentTests, TripTests, TripPollTests
- TripPreferencesTests, TripStopTests, SportTests

Service Tests:
- FreeScoreAPITests, RouteDescriptionGeneratorTests
- SuggestedTripsGeneratorTests

Export Tests:
- ShareableContentTests (card types, themes, dimensions)

Bug fixes discovered through TDD:
- ShareCardDimensions: mapSnapshotSize exceeded available width (960x480)
- ScenarioBPlanner: Added anchor game validation filter

All tests include:
- Specification tests (expected behavior)
- Invariant tests (properties that must always hold)
- Edge case tests (boundary conditions)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:07:41 -06:00

186 lines
5.7 KiB
Swift

//
// PDFGeneratorTests.swift
// SportsTimeTests
//
// TDD specification tests for PDFGenerator types.
//
import Testing
import Foundation
import UIKit
@testable import SportsTime
// MARK: - UIColor Hex Extension Tests
@Suite("UIColor Hex Extension")
struct UIColorHexExtensionTests {
// MARK: - Specification Tests: Parsing
/// - Expected Behavior: Parses 6-digit hex without #
@Test("init(hex:): parses 6-digit hex without #")
func initHex_sixDigitWithoutHash() {
let color = UIColor(hex: "FF0000")
#expect(color != nil)
}
/// - Expected Behavior: Parses 6-digit hex with #
@Test("init(hex:): parses 6-digit hex with #")
func initHex_sixDigitWithHash() {
let color = UIColor(hex: "#FF0000")
#expect(color != nil)
}
/// - Expected Behavior: Returns nil for invalid length
@Test("init(hex:): returns nil for invalid length")
func initHex_invalidLength() {
let tooShort = UIColor(hex: "FF00")
let tooLong = UIColor(hex: "FF00FF00")
#expect(tooShort == nil)
#expect(tooLong == nil)
}
/// - Expected Behavior: Handles whitespace
@Test("init(hex:): handles whitespace")
func initHex_whitespace() {
let color = UIColor(hex: " FF0000 ")
#expect(color != nil)
}
// MARK: - Specification Tests: Color Values
/// - Expected Behavior: Red hex produces red color
@Test("init(hex:): FF0000 produces red")
func initHex_redColor() {
let color = UIColor(hex: "FF0000")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
#expect(abs(r - 1.0) < 0.01)
#expect(abs(g - 0.0) < 0.01)
#expect(abs(b - 0.0) < 0.01)
#expect(abs(a - 1.0) < 0.01)
}
/// - Expected Behavior: Green hex produces green color
@Test("init(hex:): 00FF00 produces green")
func initHex_greenColor() {
let color = UIColor(hex: "00FF00")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
#expect(abs(r - 0.0) < 0.01)
#expect(abs(g - 1.0) < 0.01)
#expect(abs(b - 0.0) < 0.01)
}
/// - Expected Behavior: Blue hex produces blue color
@Test("init(hex:): 0000FF produces blue")
func initHex_blueColor() {
let color = UIColor(hex: "0000FF")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
#expect(abs(r - 0.0) < 0.01)
#expect(abs(g - 0.0) < 0.01)
#expect(abs(b - 1.0) < 0.01)
}
/// - Expected Behavior: Black hex produces black color
@Test("init(hex:): 000000 produces black")
func initHex_blackColor() {
let color = UIColor(hex: "000000")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
#expect(abs(r - 0.0) < 0.01)
#expect(abs(g - 0.0) < 0.01)
#expect(abs(b - 0.0) < 0.01)
}
/// - Expected Behavior: White hex produces white color
@Test("init(hex:): FFFFFF produces white")
func initHex_whiteColor() {
let color = UIColor(hex: "FFFFFF")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
#expect(abs(r - 1.0) < 0.01)
#expect(abs(g - 1.0) < 0.01)
#expect(abs(b - 1.0) < 0.01)
}
/// - Expected Behavior: Mixed hex produces correct color
@Test("init(hex:): mixed color produces correct values")
func initHex_mixedColor() {
// 80 = 128 = 0.502 (50%)
let color = UIColor(hex: "804020")!
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
// 0x80 = 128/255 = ~0.502
// 0x40 = 64/255 = ~0.251
// 0x20 = 32/255 = ~0.125
#expect(abs(r - 0.502) < 0.01)
#expect(abs(g - 0.251) < 0.01)
#expect(abs(b - 0.125) < 0.01)
}
// MARK: - Edge Cases
/// - Expected Behavior: Lowercase hex works
@Test("init(hex:): lowercase hex works")
func initHex_lowercase() {
let color = UIColor(hex: "ff0000")
#expect(color != nil)
}
/// - Expected Behavior: Mixed case hex works
@Test("init(hex:): mixed case hex works")
func initHex_mixedCase() {
let color = UIColor(hex: "Ff00fF")
#expect(color != nil)
}
/// - Expected Behavior: Empty string returns nil
@Test("init(hex:): empty string returns nil")
func initHex_emptyString() {
let color = UIColor(hex: "")
#expect(color == nil)
}
/// - Expected Behavior: Just # returns nil
@Test("init(hex:): just # returns nil")
func initHex_justHash() {
let color = UIColor(hex: "#")
#expect(color == nil)
}
// MARK: - Invariant Tests
/// - Invariant: Alpha is always 1.0
@Test("Invariant: alpha is always 1.0")
func invariant_alphaIsOne() {
let testHexes = ["FF0000", "00FF00", "0000FF", "123456", "ABCDEF"]
for hex in testHexes {
let color = UIColor(hex: hex)!
var a: CGFloat = 0
color.getRed(nil, green: nil, blue: nil, alpha: &a)
#expect(abs(a - 1.0) < 0.001)
}
}
/// - Invariant: Valid 6-digit hex always succeeds
@Test("Invariant: valid 6-digit hex always succeeds")
func invariant_validHexSucceeds() {
let validHexes = ["000000", "FFFFFF", "123456", "ABCDEF", "abcdef", "#000000", "#FFFFFF"]
for hex in validHexes {
let color = UIColor(hex: hex)
#expect(color != nil, "Failed for hex: \(hex)")
}
}
}