- 01-01: Reframe must_haves.truths to user-observable behaviors - 01-01: Remove unimplemented key_link (wiring happens in later phases) - 01-02: Add test case for DATA-04 (custom items at any position) - 01-02: Add must_haves.truths entry for custom item flexibility - 01-02: Document LocalItineraryItem is standalone (no sibling models needed) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.6 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-semantic-position-model | 02 | execute | 2 |
|
|
true |
|
Purpose: Prove that requirements DATA-01 through DATA-05 and PERS-01 through PERS-03 are satisfied. Tests must verify: sortOrder calculation correctness, midpoint insertion math, day derivation accuracy, and persistence survival across SwiftData reload.
Output: Two test files covering unit tests for SortOrderProvider and integration tests for persistence behavior.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
Source files
@SportsTime/Core/Models/Domain/SortOrderProvider.swift @SportsTime/Core/Models/Domain/ItineraryItem.swift @SportsTime/Core/Models/Local/SavedTrip.swift
Task 1: Create SortOrderProvider unit tests SportsTimeTests/SortOrderProviderTests.swift Create a new test file `SortOrderProviderTests.swift` with tests for all SortOrderProvider methods.Test cases to include:
initialSortOrder tests:
test_initialSortOrder_midnight_returns100: 00:00 -> 100.0test_initialSortOrder_noon_returns820: 12:00 -> 100 + 720 = 820.0test_initialSortOrder_7pm_returns1240: 19:00 -> 100 + 1140 = 1240.0test_initialSortOrder_1159pm_returns1539: 23:59 -> 100 + 1439 = 1539.0
sortOrderBetween tests:
test_sortOrderBetween_integers_returnsMidpoint: (1.0, 2.0) -> 1.5test_sortOrderBetween_negativeAndPositive_returnsMidpoint: (-1.0, 1.0) -> 0.0test_sortOrderBetween_fractionals_returnsMidpoint: (1.5, 1.75) -> 1.625
sortOrderBefore tests:
test_sortOrderBefore_positive_returnsLower: 1.0 -> 0.0test_sortOrderBefore_negative_returnsLower: -1.0 -> -2.0
sortOrderAfter tests:
test_sortOrderAfter_positive_returnsHigher: 1.0 -> 2.0test_sortOrderAfter_zero_returnsOne: 0.0 -> 1.0
needsNormalization tests:
test_needsNormalization_wellSpaced_returnsFalse: items with gaps > 1e-10test_needsNormalization_tinyGap_returnsTrue: items with gap < 1e-10test_needsNormalization_empty_returnsFalse: empty arraytest_needsNormalization_singleItem_returnsFalse: one item
normalize tests:
test_normalize_reassignsIntegerSpacing: after normalize, sortOrders are 1.0, 2.0, 3.0...test_normalize_preservesOrder: relative order unchanged after normalize
Use @testable import SportsTime at top.
Tests compile and pass:
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/SortOrderProviderTests test 2>&1 | grep -E "(Test Case|passed|failed)"
These tests verify PERS-01, PERS-02, PERS-03, and DATA-04 requirements.
Test cases to include:
Position persistence (PERS-01):
test_itineraryItem_positionSurvivesEncodeDecode: Create ItineraryItem with specific day/sortOrder, encode to JSON, decode, verify day and sortOrder match exactlytest_localItineraryItem_positionSurvivesSwiftData: Create LocalItineraryItem, save to SwiftData ModelContext, fetch back, verify day and sortOrder match
Semantic-only state (PERS-02):
test_itineraryItem_allPositionPropertiesAreCodable: Verify ItineraryItem.day and .sortOrder are included in Codable output (not transient)
Midpoint insertion (PERS-03):
test_midpointInsertion_50Times_maintainsPrecision: Insert 50 times between adjacent items, verify all sortOrders are distincttest_midpointInsertion_producesCorrectValue: Insert between sortOrder 1.0 and 2.0, verify result is 1.5
Day property updates (DATA-02, DATA-05):
test_travelItem_dayCanBeUpdated: Create travel item with day=1, update to day=3, verify day property changedtest_item_belongsToExactlyOneDay: Verify item.day is a single Int, not optional or array
Game immutability (DATA-03):
test_gameItem_sortOrderDerivedFromTime: Create game item for 7pm game, verify sortOrder is ~1240.0 (100 + 19*60)
Custom item flexibility (DATA-04):
test_customItem_canBePlacedAtAnyPosition: Create custom items with sortOrder values at negative (-5.0, before all games), between games (500.0), and after all games (2000.0). Verify all three persist correctly and can coexist on the same day sorted correctly.
Use in-memory SwiftData ModelContainer for tests. Note: LocalItineraryItem is standalone with no relationships - it can be registered alone:
let config = ModelConfiguration(isStoredInMemoryOnly: true)
let container = try ModelContainer(for: LocalItineraryItem.self, configurations: config)
Import XCTest, SwiftData, and @testable import SportsTime.
Tests compile and pass:
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/SemanticPositionPersistenceTests test 2>&1 | grep -E "(Test Case|passed|failed)"
If any tests fail, investigate and fix before completing the plan.
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test 2>&1 | tail -30
Look for "** TEST SUCCEEDED **" at the end. Full test suite passes with no failures, including all new and existing tests
1. SortOrderProviderTests.swift exists with 16+ test methods covering all SortOrderProvider functions 2. SemanticPositionPersistenceTests.swift exists with 9+ test methods covering persistence requirements 3. All tests pass when run individually and as part of full suite 4. Tests verify the success criteria from ROADMAP.md Phase 1: - Position survives reload (tested via encode/decode and SwiftData) - Travel day update works (tested via day property mutation) - Midpoint insertion works (tested via 50-iteration precision test) - Games use time-based sortOrder (tested via initialSortOrder) - Custom items can be placed anywhere (tested via negative/between/after positions)<success_criteria>
- 25+ new test cases across 2 test files
- All tests pass
- Tests directly verify Phase 1 requirements DATA-01 through DATA-05 and PERS-01 through PERS-03
- No regression in existing tests </success_criteria>