Files
Sportstime/SportsTimeTests/Services/PhotoMetadataExtractorTests.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

138 lines
4.7 KiB
Swift

//
// PhotoMetadataExtractorTests.swift
// SportsTimeTests
//
// TDD specification tests for PhotoMetadata types.
//
import Testing
import Foundation
import CoreLocation
@testable import SportsTime
// MARK: - PhotoMetadata Tests
@Suite("PhotoMetadata")
struct PhotoMetadataTests {
// MARK: - Test Data
private func makeMetadata(
captureDate: Date? = Date(),
coordinates: CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: 40.0, longitude: -74.0)
) -> PhotoMetadata {
PhotoMetadata(captureDate: captureDate, coordinates: coordinates)
}
// MARK: - Specification Tests: hasValidLocation
/// - Expected Behavior: true when coordinates are provided
@Test("hasValidLocation: true when coordinates provided")
func hasValidLocation_true() {
let metadata = makeMetadata(coordinates: CLLocationCoordinate2D(latitude: 40.0, longitude: -74.0))
#expect(metadata.hasValidLocation == true)
}
/// - Expected Behavior: false when coordinates are nil
@Test("hasValidLocation: false when coordinates nil")
func hasValidLocation_false() {
let metadata = makeMetadata(coordinates: nil)
#expect(metadata.hasValidLocation == false)
}
// MARK: - Specification Tests: hasValidDate
/// - Expected Behavior: true when captureDate is provided
@Test("hasValidDate: true when captureDate provided")
func hasValidDate_true() {
let metadata = makeMetadata(captureDate: Date())
#expect(metadata.hasValidDate == true)
}
/// - Expected Behavior: false when captureDate is nil
@Test("hasValidDate: false when captureDate nil")
func hasValidDate_false() {
let metadata = makeMetadata(captureDate: nil)
#expect(metadata.hasValidDate == false)
}
// MARK: - Specification Tests: empty
/// - Expected Behavior: empty returns metadata with all nil values
@Test("empty: returns metadata with nil captureDate")
func empty_nilCaptureDate() {
let empty = PhotoMetadata.empty
#expect(empty.captureDate == nil)
}
@Test("empty: returns metadata with nil coordinates")
func empty_nilCoordinates() {
let empty = PhotoMetadata.empty
#expect(empty.coordinates == nil)
}
@Test("empty: returns metadata with hasValidLocation false")
func empty_hasValidLocationFalse() {
let empty = PhotoMetadata.empty
#expect(empty.hasValidLocation == false)
}
@Test("empty: returns metadata with hasValidDate false")
func empty_hasValidDateFalse() {
let empty = PhotoMetadata.empty
#expect(empty.hasValidDate == false)
}
// MARK: - Specification Tests: Combinations
@Test("Both valid: location and date both provided")
func bothValid() {
let metadata = makeMetadata(captureDate: Date(), coordinates: CLLocationCoordinate2D(latitude: 0, longitude: 0))
#expect(metadata.hasValidLocation == true)
#expect(metadata.hasValidDate == true)
}
@Test("Only location: date nil")
func onlyLocation() {
let metadata = makeMetadata(captureDate: nil, coordinates: CLLocationCoordinate2D(latitude: 0, longitude: 0))
#expect(metadata.hasValidLocation == true)
#expect(metadata.hasValidDate == false)
}
@Test("Only date: coordinates nil")
func onlyDate() {
let metadata = makeMetadata(captureDate: Date(), coordinates: nil)
#expect(metadata.hasValidLocation == false)
#expect(metadata.hasValidDate == true)
}
// MARK: - Invariant Tests
/// - Invariant: hasValidLocation == (coordinates != nil)
@Test("Invariant: hasValidLocation equals coordinates check")
func invariant_hasValidLocationEqualsCoordinatesCheck() {
let withCoords = makeMetadata(coordinates: CLLocationCoordinate2D(latitude: 0, longitude: 0))
let withoutCoords = makeMetadata(coordinates: nil)
#expect(withCoords.hasValidLocation == (withCoords.coordinates != nil))
#expect(withoutCoords.hasValidLocation == (withoutCoords.coordinates != nil))
}
/// - Invariant: hasValidDate == (captureDate != nil)
@Test("Invariant: hasValidDate equals captureDate check")
func invariant_hasValidDateEqualsCaptureCheck() {
let withDate = makeMetadata(captureDate: Date())
let withoutDate = makeMetadata(captureDate: nil)
#expect(withDate.hasValidDate == (withDate.captureDate != nil))
#expect(withoutDate.hasValidDate == (withoutDate.captureDate != nil))
}
/// - Invariant: empty.hasValidLocation && empty.hasValidDate == false
@Test("Invariant: empty has no valid data")
func invariant_emptyHasNoValidData() {
let empty = PhotoMetadata.empty
#expect(!empty.hasValidLocation && !empty.hasValidDate)
}
}