Files
SportstimeAPI/.planning/phases/03-visual-flattening/03-02-PLAN.md
Trey t e8ae80e02b docs(03): create phase 3 visual flattening plans
Phase 03: Visual Flattening
- 2 plans in 2 waves
- Plan 01: Create ItineraryFlattener utility, refactor reloadData()
- Plan 02: Add determinism tests for flattening behavior
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 15:49:49 -06:00

6.4 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
phase plan type wave depends_on files_modified autonomous must_haves
03-visual-flattening 02 execute 2
03-01
SportsTimeTests/ItineraryFlattenerTests.swift
true
truths artifacts key_links
Same semantic state produces identical row order on repeated flattening
Item with sortOrder -1.0 appears before all games in that day
Reordering an item and re-flattening preserves the new order
path provides min_lines
SportsTimeTests/ItineraryFlattenerTests.swift Determinism and ordering tests 80
from to via pattern
ItineraryFlattenerTests ItineraryFlattener.flatten() test assertions ItineraryFlattener.flatten
Add tests verifying ItineraryFlattener produces deterministic, sortOrder-based output.

Purpose: Ensure the three success criteria from ROADMAP.md are verifiable through automated tests.

Output: New test file ItineraryFlattenerTests.swift with tests covering all success criteria.

<execution_context> @/.claude/get-shit-done/workflows/execute-plan.md @/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-visual-flattening/03-RESEARCH.md @.planning/phases/03-visual-flattening/03-01-SUMMARY.md @SportsTime/Core/Models/Domain/ItineraryFlattener.swift @SportsTime/Core/Models/Domain/SortOrderProvider.swift @SportsTimeTests/ItineraryConstraintsTests.swift Task 1: Create ItineraryFlattenerTests with determinism tests SportsTimeTests/ItineraryFlattenerTests.swift Create a new test file `ItineraryFlattenerTests.swift` using Swift Testing (`@Suite`, `@Test`).

Test suite structure:

import Testing
@testable import SportsTime

@Suite("ItineraryFlattener")
struct ItineraryFlattenerTests {
    // Test helper to create mock ItineraryDayData
    // Test helper to create mock RichGame
    // Test helper to create mock ItineraryItem
}

Required tests (map directly to ROADMAP success criteria):

  1. success_negativeSortOrderAppearsBeforeGames (Success Criterion 1)

    • Create item with sortOrder = -1.0
    • Create games with sortOrder ~820 (noon game)
    • Flatten and verify custom item index < games index
    • Assert: "Item with sortOrder -1.0 appears before all games in that day's section"
  2. success_sameStateProducesIdenticalOrder (Success Criterion 2)

    • Create fixed test data (2 days, games, travel, custom items)
    • Flatten twice
    • Compare resulting row IDs
    • Assert: arrays are identical (not just equal length)
  3. success_reorderPreservesNewOrder (Success Criterion 3)

    • Create items with sortOrder 1.0, 2.0, 3.0
    • Simulate reorder: change item from 1.0 to 2.5
    • Flatten
    • Verify new order is [2.0, 2.5, 3.0] not [1.0, 2.0, 3.0]

Additional tests for comprehensive coverage:

  1. flatten_dayHeaderAlwaysFirst

    • Verify first item for each day is .dayHeader
  2. flatten_sortsByDayThenSortOrder

    • Items on day 1 appear before items on day 2
    • Within each day, items sorted by sortOrder
  3. flatten_gamesGetSortOrderFromTime

    • Game at 8:00 PM (sortOrder ~1180) appears after item with sortOrder 500
    • Game at 1:00 PM (sortOrder ~880) appears before item with sortOrder 1000
  4. flatten_emptyDayHasOnlyHeader

    • Day with no games, no items produces only .dayHeader row
  5. flatten_multipleGamesOnSameDay

    • Day with 2 games: both included in single .games row
    • Custom items around games sort correctly

Test helpers needed:

  • makeGame(id:, stadium:, dateTime:) -> RichGame
  • makeItem(day:, sortOrder:, kind:) -> ItineraryItem
  • makeDayData(dayNumber:, date:, games:, items:) -> ItineraryDayData Run tests: xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/ItineraryFlattenerTests test 2>&1 | grep -E "(Test Suite|passed|failed|error:)" ItineraryFlattenerTests.swift exists with:
  • 3 success_* tests mapping to ROADMAP success criteria
  • 5+ additional tests for comprehensive coverage
  • All tests passing
Task 2: Verify existing behavior unchanged SportsTimeTests/ItineraryFlattenerTests.swift Add integration-style tests that verify the refactored flattening produces expected behavior for realistic trip data.

Additional tests:

  1. flatten_travelWithNegativeSortOrderAppearsBeforeGames

    • Travel item with sortOrder = -5.0
    • Should appear before games in same day
  2. flatten_travelWithPositiveSortOrderAppearsAfterGames

    • Travel item with sortOrder = 1500.0 (after noon game)
    • Should appear after games in same day
  3. flatten_mixedItemTypes

    • Day with: travel (-5), custom (-1), games (820), custom (900), travel (1500)
    • Verify exact order: header, travel, custom, games, custom, travel
  4. flatten_multiDayTrip

    • 3-day trip with different item configurations per day
    • Verify each day's items are independent and sorted correctly

Run full test suite to ensure no regressions: xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test Full test suite passes: xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test 2>&1 | grep -E "(Test Suite|passed|failed)" | tail -10

  • All ItineraryFlattenerTests passing (12+ tests)
  • Full test suite passes (no regressions)
  • Tests cover all three ROADMAP success criteria
1. All tests in `ItineraryFlattenerTests.swift` pass 2. Tests explicitly named `success_*` map to ROADMAP success criteria: - success_negativeSortOrderAppearsBeforeGames -> Criterion 1 - success_sameStateProducesIdenticalOrder -> Criterion 2 - success_reorderPreservesNewOrder -> Criterion 3 3. Full test suite passes (no regressions from refactoring)

<success_criteria>

  • FLAT-02: Flattening is deterministic and stateless (verified by success_sameStateProducesIdenticalOrder test)
  • All three ROADMAP success criteria have corresponding tests </success_criteria>
After completion, create `.planning/phases/03-visual-flattening/03-02-SUMMARY.md`