Groundwork for the Library tab: RoutineOrdering.changedOrders turns an .onMove gesture into the minimal set of order writes (normalizing legacy colliding orders on first drag), RoutineNaming.uniqueName picks the next free "X Copy" name for duplication, and ExerciseCatalog groups the bundled exercise library into curated category sections with name/category/target search. Plus ExerciseDocument.planSummary for read-only document rendering. All covered by unit tests, including a motion/info name-parity assertion. Claude-Session: https://claude.ai/code/session_01H8VxUX4ckjU3vRF5M4L5FV
45 lines
1.5 KiB
Swift
45 lines
1.5 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import Workouts
|
|
|
|
/// Locks `RoutineNaming.uniqueName` — the "duplicate this routine" naming scheme.
|
|
struct RoutineNamingTests {
|
|
|
|
@Test func firstCopyWhenNameIsFree() {
|
|
#expect(RoutineNaming.uniqueName(base: "Upper Body", existing: []) == "Upper Body Copy")
|
|
}
|
|
|
|
@Test func collisionAdvancesToCopyTwo() {
|
|
#expect(RoutineNaming.uniqueName(
|
|
base: "Upper Body", existing: ["Upper Body Copy"]
|
|
) == "Upper Body Copy 2")
|
|
}
|
|
|
|
@Test func multipleCollisionsAdvanceToCopyThree() {
|
|
#expect(RoutineNaming.uniqueName(
|
|
base: "Upper Body", existing: ["Upper Body Copy", "Upper Body Copy 2"]
|
|
) == "Upper Body Copy 3")
|
|
}
|
|
|
|
@Test func onlyLaterCollisionSkipsAhead() {
|
|
// "Copy" itself is free, but "Copy 2" is taken — the first free slot is still
|
|
// "Copy" since collisions are only checked, not assumed contiguous.
|
|
#expect(RoutineNaming.uniqueName(
|
|
base: "Upper Body", existing: ["Upper Body Copy 2"]
|
|
) == "Upper Body Copy")
|
|
}
|
|
|
|
@Test func matchIsCaseSensitive() {
|
|
// A differently-cased existing name doesn't count as a collision.
|
|
#expect(RoutineNaming.uniqueName(
|
|
base: "Upper Body", existing: ["upper body copy"]
|
|
) == "Upper Body Copy")
|
|
}
|
|
|
|
@Test func unrelatedNamesDontCollide() {
|
|
#expect(RoutineNaming.uniqueName(
|
|
base: "Upper Body", existing: ["Lower Body", "Core"]
|
|
) == "Upper Body Copy")
|
|
}
|
|
}
|