Build card faces with edge-accent styling
The card face becomes real: leading SF Symbol (card default doc.text, tinted by a valid hand-written iconColor — schema yes, control no), title or the quiet untitled placeholder, and a quiet paperclip when the card has attachments — title-only by design, no body excerpt. Color is the settled K1 edge accent, not a fill: background paints a 4pt stripe down the left edge, resolved through the ported pathfinder palette (12 icon tints + 12 backgrounds carried over verbatim, plus raw #RRGGBB[AA]); anything unresolvable paints nothing and stays on disk exactly as written. The snapshot now carries each card's flat attachment names — the loader's one read inside a card folder, shared with the Writer's listing so the m5 carousel and m6 sidebar can never disagree on order (Finder order, the Writer's existing comparator). The face keeps its top-aligned structure so the sole-selection carousel can expand inside the card without moving masonry neighbors. 18 new tests. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -117,6 +117,38 @@ struct FixtureRichBoardTests {
|
||||
#expect(done.cards[0].title.value == "Ship v1")
|
||||
}
|
||||
|
||||
/// `attachments/` is **flat** (01-storage-format.md § Attachments): the card's listing is its
|
||||
/// top-level regular files and nothing else. This card's folder holds all four shapes on real
|
||||
/// disk — two ordinary files, a hidden one, and a subfolder with a file in it — so the rule is
|
||||
/// asserted against a filesystem rather than against a mock.
|
||||
///
|
||||
/// The excluded three are excluded for three different reasons and only one of them is stated
|
||||
/// in the design doc: subfolders are "tolerated, preserved verbatim … and not surfaced"; the
|
||||
/// hidden file is the loader's uniform `.skipsHiddenFiles` stance (a `.DS_Store` is not
|
||||
/// anyone's attachment); symlinks are the loader's never-resolve stance, covered in
|
||||
/// `BoardLoaderTests` because git cannot carry that shape into a fixture reliably.
|
||||
@Test func aCardListsOnlyTheTopLevelFilesOfItsAttachmentsFolder() throws {
|
||||
let result = try loadFixture("Valid/rich-board.kanban")
|
||||
let doing = try #require(result.model.lanes.first { $0.id.rawValue == RichBoard.laneDoing })
|
||||
let taxonomy = try #require(doing.cards.first { $0.id.rawValue == RichBoard.cardTaxonomy })
|
||||
|
||||
#expect(taxonomy.attachments == ["notes.txt", "sketch.png"])
|
||||
}
|
||||
|
||||
/// The overwhelmingly common shape: no `attachments/` folder at all. It reads as an empty
|
||||
/// listing, never as a warning or a failure — nothing has been attached yet is an ordinary
|
||||
/// state, and it is what makes the face's paperclip indicator absent by default.
|
||||
@Test func cardsWithoutAnAttachmentsFolderListNothing() throws {
|
||||
let result = try loadFixture("Valid/rich-board.kanban")
|
||||
let doing = try #require(result.model.lanes.first { $0.id.rawValue == RichBoard.laneDoing })
|
||||
let second = try #require(doing.cards.first { $0.id.rawValue == RichBoard.cardSecond })
|
||||
let done = try #require(result.model.lanes.first { $0.id.rawValue == RichBoard.laneDone })
|
||||
|
||||
#expect(second.attachments.isEmpty)
|
||||
#expect(done.cards.map(\.attachments) == [[]])
|
||||
#expect(result.warnings.isEmpty)
|
||||
}
|
||||
|
||||
@Test func boardUnknownAndReservedKeysPreserveOrder() throws {
|
||||
let result = try loadFixture("Valid/rich-board.kanban")
|
||||
// schema-owned keys (schema, title, created, modified, modified-by, background, icon,
|
||||
|
||||
Reference in New Issue
Block a user