Realign code with the 2026-07-30 findings-resolution rulings
Delete Immediately is removed entirely (rulingae1dd96, Redesign card d40bfac1): the delete vocabulary is purely staged — board → trash, trash → permanent (confirmed on no-git boards), Empty Trash for bulk. Gone: File ▸ Delete Immediately (⌥⌘⌫) and its validation, both ⌥-alternate context rows (card + the permanently-disabled lane row), the VO custom action, BoardStore.deleteImmediately, TrashModel.canDeleteImmediately, TrashConfirmations' .purge action (zero surviving callers — trash-side Delete always used .deleteTrashCards), and the pinning tests. purgePrompt drops its now-single-purpose container parameter (.trash is the only surviving caller). BoardWriter.purgeItem survives — create-undo rollback still needs it — with its comment rewritten. README's trash paragraph drops the ⌥⌘⌫ sentence. The other 2026-07-30 rulings (2ec2c95registry freshness stamp,c741b02unified-log-as-coerce-consumer) required no code changes — already conformant. Both schemes 1844 tests / 318 suites green. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -224,42 +224,18 @@ struct TrashPhrasingTests {
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
let sole = try #require(TrashModel.purgePrompt(
|
||||
for: [cardF], in: .trash, snapshot: snapshot, unrecoverable: true
|
||||
for: [cardF], snapshot: snapshot, unrecoverable: true
|
||||
))
|
||||
#expect(sole.title == "Permanently delete \u{201C}Newest\u{201D}?")
|
||||
#expect(sole.message == "This can\u{2019}t be undone.")
|
||||
#expect(sole.confirmTitle == "Delete")
|
||||
|
||||
let several = try #require(TrashModel.purgePrompt(
|
||||
for: [cardE, cardF], in: .trash, snapshot: snapshot, unrecoverable: true
|
||||
for: [cardE, cardF], snapshot: snapshot, unrecoverable: true
|
||||
))
|
||||
#expect(several.title == "Permanently delete 2 cards?")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Test("Delete Immediately reads the same either side of the boundary")
|
||||
func purgePromptSpansContainers() throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
let fromBoard = try #require(TrashModel.purgePrompt(
|
||||
for: [card1], in: .board, snapshot: snapshot, unrecoverable: true
|
||||
))
|
||||
#expect(fromBoard.title == "Permanently delete \u{201C}First\u{201D}?",
|
||||
"11 ▸ Delete Immediately skips the trash from anywhere")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Test("A lane in the set contributes nothing — no purge path reaches one")
|
||||
func lanesAreNeverPurged() throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
#expect(TrashModel.purgePrompt(for: [laneA], in: .board, snapshot: snapshot, unrecoverable: true) == nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Test("An untitled card reads as the untitled rendering, never as an empty pair of quotes")
|
||||
func untitledReadsAsARendering() throws {
|
||||
@@ -271,7 +247,7 @@ struct TrashPhrasingTests {
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
let prompt = try #require(TrashModel.purgePrompt(
|
||||
for: [cardD], in: .trash, snapshot: snapshot, unrecoverable: true
|
||||
for: [cardD], snapshot: snapshot, unrecoverable: true
|
||||
))
|
||||
#expect(prompt.title == "Permanently delete \u{201C}Untitled\u{201D}?")
|
||||
}
|
||||
@@ -284,9 +260,9 @@ struct TrashPhrasingTests {
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
#expect(TrashModel.purgePrompt(
|
||||
for: [ItemID(rawValue: Ident.indexless)], in: .trash, snapshot: snapshot, unrecoverable: true
|
||||
for: [ItemID(rawValue: Ident.indexless)], snapshot: snapshot, unrecoverable: true
|
||||
) == nil)
|
||||
#expect(TrashModel.purgePrompt(for: [], in: .board, snapshot: snapshot, unrecoverable: true) == nil)
|
||||
#expect(TrashModel.purgePrompt(for: [], snapshot: snapshot, unrecoverable: true) == nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@@ -344,22 +320,4 @@ struct TrashValidationTests {
|
||||
selection: ItemReferenceSet(ids: [cardD], container: .board), in: snapshot
|
||||
))
|
||||
}
|
||||
|
||||
@Test("Delete Immediately is cards only, in either container")
|
||||
func canDeleteImmediatelyIsCardsOnly() throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
let snapshot = try load(fixture)
|
||||
|
||||
#expect(TrashModel.canDeleteImmediately(
|
||||
selection: ItemReferenceSet(ids: [card1], container: .board), in: snapshot
|
||||
))
|
||||
#expect(TrashModel.canDeleteImmediately(
|
||||
selection: ItemReferenceSet(ids: [cardD], container: .trash), in: snapshot
|
||||
))
|
||||
#expect(!TrashModel.canDeleteImmediately(
|
||||
selection: ItemReferenceSet(ids: [laneA], container: .board), in: snapshot
|
||||
), "a lane's delete is physical already — there is nothing for 'skip the trash' to mean")
|
||||
#expect(!TrashModel.canDeleteImmediately(selection: .empty, in: snapshot))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user