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>
This commit is contained in:
@@ -8,7 +8,12 @@
|
||||
import Foundation
|
||||
|
||||
/// Protocol that all scenario planners must implement.
|
||||
/// Each scenario (A, B, C) has its own isolated implementation.
|
||||
/// Each scenario (A, B, C, D) has its own isolated implementation.
|
||||
///
|
||||
/// - Invariants:
|
||||
/// - Always returns either success or explicit failure, never throws
|
||||
/// - Success contains ranked itinerary options
|
||||
/// - Failure contains reason and any constraint violations
|
||||
protocol ScenarioPlanner {
|
||||
|
||||
/// Plan itineraries for this scenario.
|
||||
@@ -17,10 +22,24 @@ protocol ScenarioPlanner {
|
||||
func plan(request: PlanningRequest) -> ItineraryResult
|
||||
}
|
||||
|
||||
/// Factory for creating the appropriate scenario planner
|
||||
/// Factory for creating the appropriate scenario planner.
|
||||
///
|
||||
/// - Expected Behavior:
|
||||
/// - followTeamId != nil → ScenarioDPlanner
|
||||
/// - selectedGames not empty → ScenarioBPlanner
|
||||
/// - startLocation AND endLocation != nil → ScenarioCPlanner
|
||||
/// - Otherwise → ScenarioAPlanner (default)
|
||||
///
|
||||
/// Priority order: D > B > C > A (first matching wins)
|
||||
enum ScenarioPlannerFactory {
|
||||
|
||||
/// Creates the appropriate planner based on the request inputs
|
||||
/// Creates the appropriate planner based on the request inputs.
|
||||
///
|
||||
/// - Expected Behavior:
|
||||
/// - followTeamId set → ScenarioDPlanner
|
||||
/// - selectedGames not empty → ScenarioBPlanner
|
||||
/// - Both start and end locations → ScenarioCPlanner
|
||||
/// - Otherwise → ScenarioAPlanner
|
||||
static func planner(for request: PlanningRequest) -> ScenarioPlanner {
|
||||
print("🔍 ScenarioPlannerFactory: Selecting planner...")
|
||||
print(" - followTeamId: \(request.preferences.followTeamId ?? "nil")")
|
||||
@@ -51,7 +70,13 @@ enum ScenarioPlannerFactory {
|
||||
return ScenarioAPlanner()
|
||||
}
|
||||
|
||||
/// Classifies which scenario applies to this request
|
||||
/// Classifies which scenario applies to this request.
|
||||
///
|
||||
/// - Expected Behavior:
|
||||
/// - followTeamId set → .scenarioD
|
||||
/// - selectedGames not empty → .scenarioB
|
||||
/// - Both start and end locations → .scenarioC
|
||||
/// - Otherwise → .scenarioA
|
||||
static func classify(_ request: PlanningRequest) -> PlanningScenario {
|
||||
if request.preferences.followTeamId != nil {
|
||||
return .scenarioD
|
||||
|
||||
Reference in New Issue
Block a user