// // RegionTests.swift // SportsTimeTests // // TDD specification tests for Region enum. // import Testing @testable import SportsTime @Suite("Region") struct RegionTests { // MARK: - Specification Tests: classify(longitude:) @Test("classify: longitude > -85 returns .east") func classify_east() { // NYC: -73.9855 #expect(Region.classify(longitude: -73.9855) == .east) // Boston: -71.0972 #expect(Region.classify(longitude: -71.0972) == .east) // Miami: -80.1918 #expect(Region.classify(longitude: -80.1918) == .east) // Toronto: -79.3832 #expect(Region.classify(longitude: -79.3832) == .east) // Atlanta: -84.3880 #expect(Region.classify(longitude: -84.3880) == .east) // Just above boundary #expect(Region.classify(longitude: -84.9999) == .east) } @Test("classify: longitude in -110...-85 returns .central") func classify_central() { // Chicago: -87.6233 #expect(Region.classify(longitude: -87.6233) == .central) // Houston: -95.3698 #expect(Region.classify(longitude: -95.3698) == .central) // Dallas: -96.7970 #expect(Region.classify(longitude: -96.7970) == .central) // Minneapolis: -93.2650 #expect(Region.classify(longitude: -93.2650) == .central) // Denver: -104.9903 #expect(Region.classify(longitude: -104.9903) == .central) // Boundary: exactly -85 #expect(Region.classify(longitude: -85.0) == .central) // Boundary: exactly -110 #expect(Region.classify(longitude: -110.0) == .central) } @Test("classify: longitude < -110 returns .west") func classify_west() { // Los Angeles: -118.2673 #expect(Region.classify(longitude: -118.2673) == .west) // San Francisco: -122.4194 #expect(Region.classify(longitude: -122.4194) == .west) // Seattle: -122.3321 #expect(Region.classify(longitude: -122.3321) == .west) // Phoenix: -112.0740 #expect(Region.classify(longitude: -112.0740) == .west) // Las Vegas: -115.1398 #expect(Region.classify(longitude: -115.1398) == .west) // Just below boundary #expect(Region.classify(longitude: -110.0001) == .west) } // MARK: - Specification Tests: Boundary Values @Test("classify boundary: -85 is central, -84.9999 is east") func classify_eastCentralBoundary() { #expect(Region.classify(longitude: -85.0) == .central) #expect(Region.classify(longitude: -84.9999) == .east) #expect(Region.classify(longitude: -85.0001) == .central) } @Test("classify boundary: -110 is central, -110.0001 is west") func classify_centralWestBoundary() { #expect(Region.classify(longitude: -110.0) == .central) #expect(Region.classify(longitude: -109.9999) == .central) #expect(Region.classify(longitude: -110.0001) == .west) } // MARK: - Specification Tests: Edge Cases @Test("classify: extreme east longitude (positive) returns .east") func classify_extremeEast() { #expect(Region.classify(longitude: 0.0) == .east) #expect(Region.classify(longitude: 50.0) == .east) } @Test("classify: extreme west longitude returns .west") func classify_extremeWest() { #expect(Region.classify(longitude: -180.0) == .west) #expect(Region.classify(longitude: -150.0) == .west) } // MARK: - Invariant Tests @Test("Invariant: classify never returns .crossCountry") func invariant_classifyNeverReturnsCrossCountry() { let testLongitudes: [Double] = [-180, -150, -120, -110.0001, -110, -100, -85.0001, -85, -70, 0, 50] for lon in testLongitudes { let region = Region.classify(longitude: lon) #expect(region != .crossCountry, "classify should never return crossCountry for longitude \(lon)") } } @Test("Invariant: every longitude maps to exactly one region") func invariant_everyLongitudeMapsToOneRegion() { // Test a range of longitudes for lon in stride(from: -180.0, through: 50.0, by: 10.0) { let region = Region.classify(longitude: lon) #expect([Region.east, .central, .west].contains(region), "Longitude \(lon) should map to east, central, or west") } } // MARK: - Property Tests @Test("Property: id equals rawValue") func property_idEqualsRawValue() { for region in Region.allCases { #expect(region.id == region.rawValue) } } @Test("Property: displayName equals rawValue") func property_displayNameEqualsRawValue() { for region in Region.allCases { #expect(region.displayName == region.rawValue) } } @Test("Property: all regions have iconName") func property_allRegionsHaveIconName() { for region in Region.allCases { #expect(!region.iconName.isEmpty) } } // MARK: - Specification Tests: Display Properties @Test("shortName values are correct") func shortName_values() { #expect(Region.east.shortName == "East") #expect(Region.central.shortName == "Central") #expect(Region.west.shortName == "West") #expect(Region.crossCountry.shortName == "Coast to Coast") } }