Files
beaver-calendar/tests/archive.test.ts
T
hh 9c0e57e29b feat(archive): completed cards move to a mirror of the boards folder
"Archive completed tasks" empties every board of what is finished into a
twin of the boards folder - `Boards/work.md` into `Boards/archive/work.md` -
itself a Kanban board with the same lanes, so the history opens like any
other board and the live one stays short. The same pass lifts a board's
native archive (everything below the `***` separator) into that mirror, so
finished work is not left sitting in two places.

Archived tasks render beside live ones when "Include the archive" and "Show
completed" are both on, from the mirrors and from any `***` section still in
a board. They carry an Archive badge instead of a project chip, ride with
the sphere they came from in the rail, and refuse drops.
2026-09-05 00:21:36 +02:00

86 lines
2.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
archiveRoot,
isArchivePath,
toArchivePath,
toBoardPath,
} from "../src/model/archive";
import { parseBoard, sphereOf } from "../src/model/board";
describe("archive paths", () => {
it("mirrors a board into the archive folder", () => {
expect(toArchivePath("Boards/work.md", "Boards", "archive")).toBe(
"Boards/archive/work.md",
);
expect(toArchivePath("📆 доски/работа.md", "📆 доски", "архив")).toBe(
"📆 доски/архив/работа.md",
);
});
it("keeps the shape of a nested board", () => {
expect(toArchivePath("Boards/team/ops.md", "Boards", "archive")).toBe(
"Boards/archive/team/ops.md",
);
expect(toBoardPath("Boards/archive/team/ops.md", "Boards", "archive")).toBe(
"Boards/team/ops.md",
);
});
it("leaves a mirror file where it is", () => {
const mirror = "Boards/archive/work.md";
expect(toArchivePath(mirror, "Boards", "archive")).toBe(mirror);
expect(isArchivePath(mirror, "Boards", "archive")).toBe(true);
expect(isArchivePath("Boards/work.md", "Boards", "archive")).toBe(false);
});
it("has nowhere to put a board outside the boards folder", () => {
expect(toArchivePath("Notes/work.md", "Boards", "archive")).toBeNull();
expect(toArchivePath("Boards/work.md", "Boards", "")).toBeNull();
expect(archiveRoot("Boards", " ")).toBe("");
});
it("works with no boards folder at all", () => {
expect(archiveRoot("", "archive")).toBe("archive");
expect(toArchivePath("work.md", "", "archive")).toBe("archive/work.md");
expect(toBoardPath("archive/work.md", "", "archive")).toBe("work.md");
});
it("shrugs at slashes around the folder names", () => {
expect(toArchivePath("Boards/work.md", "/Boards/", "/archive/")).toBe(
"Boards/archive/work.md",
);
});
it("a mirror file keeps the sphere of the board it shadows", () => {
expect(sphereOf("Boards/archive/работа.md")).toBe("работа");
});
});
describe("parsing a mirror file", () => {
const content = [
"---",
"",
"kanban-plugin: board",
"",
"---",
"",
"## errands",
"",
"- [x] pick up the parcel ✅ 2026-07-30",
"",
].join("\n");
it("marks everything archive, separator or no separator", () => {
const board = parseBoard("Boards/archive/personal.md", content, true);
expect(board.tasks).toHaveLength(1);
expect(board.tasks[0].inArchive).toBe(true);
expect(board.tasks[0].project).toBe("errands");
expect(board.lanes.every((lane) => lane.inArchive)).toBe(true);
});
it("reads as a plain board when nobody says it is a mirror", () => {
const board = parseBoard("Boards/personal.md", content);
expect(board.tasks[0].inArchive).toBe(false);
});
});