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>
186 lines
5.7 KiB
Swift
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)")
|
|
}
|
|
}
|
|
}
|