Files
plainleaf/client/components/plainleaf_tasks.test.ts
T
wushenghuaandCodex bab4b36fae
CI / config (push) Canceled after 0s
CI / test-frontend (push) Canceled after 0s
CI / test-rust (push) Canceled after 0s
CI / test-e2e (push) Canceled after 0s
CI / test-e2e-release (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / release (push) Canceled after 0s
CI / docker (push) Canceled after 0s
CI / docker-website (push) Canceled after 0s
feat: build Markdown-native task center
Co-Authored-By: Codex <noreply@anthropic.com>
2026-08-12 19:26:10 +08:00

114 lines
3.5 KiB
TypeScript

import { expect, test } from "vitest";
import {
groupScheduledTasks,
groupTasksByProject,
isOverdueTask,
localDateKey,
logbookTasks,
projectForTask,
sortTodayTasks,
taskBelongsToToday,
tasksForAnytime,
tasksForInbox,
type PlainleafTask,
} from "./plainleaf_tasks.ts";
function task(extra: Partial<PlainleafTask> = {}): PlainleafTask {
return {
ref: "测试@0",
page: "测试",
name: "测试任务",
state: " ",
done: false,
...extra,
};
}
test("localDateKey uses local calendar fields", () => {
expect(localDateKey(new Date(2026, 7, 12, 23, 30))).toBe("2026-08-12");
});
test("today contains scheduled today and overdue or due deadlines", () => {
const today = "2026-08-12";
expect(taskBelongsToToday(task({ scheduled: today }), today)).toBe(true);
expect(taskBelongsToToday(task({ deadline: "2026-08-10" }), today)).toBe(
true,
);
expect(taskBelongsToToday(task({ deadline: today }), today)).toBe(true);
expect(taskBelongsToToday(task({ scheduled: "2026-08-13" }), today)).toBe(
false,
);
expect(
taskBelongsToToday(task({ scheduled: today, done: true }), today),
).toBe(false);
expect(isOverdueTask(task({ deadline: "2026-08-11" }), today)).toBe(true);
});
test("sortTodayTasks puts overdue and due tasks before scheduled tasks", () => {
const today = "2026-08-12";
expect(
sortTodayTasks(
[
task({ ref: "scheduled", name: "计划", scheduled: today }),
task({ ref: "due", name: "截止", deadline: today }),
task({ ref: "overdue", name: "逾期", deadline: "2026-08-11" }),
],
today,
).map((item) => item.ref),
).toEqual(["overdue", "due", "scheduled"]);
});
test("inbox and anytime remain distinct", () => {
const inbox = task({ ref: "inbox", page: "任务/收件箱" });
const anytime = task({ ref: "anytime", page: "生活/采购" });
const planned = task({
ref: "planned",
page: "生活/采购",
scheduled: "2026-08-13",
});
expect(tasksForInbox([inbox, anytime, planned])).toEqual([inbox]);
expect(tasksForAnytime([inbox, anytime, planned])).toEqual([anytime]);
});
test("planned tasks are grouped by the next meaningful date", () => {
const groups = groupScheduledTasks(
[
task({ ref: "a", scheduled: "2026-08-14" }),
task({ ref: "b", deadline: "2026-08-13" }),
task({ ref: "c", scheduled: "2026-08-13", deadline: "2026-08-20" }),
task({ ref: "old", deadline: "2026-08-11" }),
],
"2026-08-12",
);
expect(
groups.map((group) => [group.date, group.tasks.map((item) => item.ref)]),
).toEqual([
["2026-08-13", ["b", "c"]],
["2026-08-14", ["a"]],
]);
});
test("explicit wiki links override source pages as projects", () => {
expect(
projectForTask(task({ page: "工作/周会", links: ["项目/Plainleaf"] })),
).toBe("项目/Plainleaf");
expect(projectForTask(task({ page: "工作/周会" }))).toBe("工作/周会");
expect(projectForTask(task({ page: "任务/收件箱" }))).toBeUndefined();
expect(
groupTasksByProject([
task({ ref: "a", page: "工作", links: ["项目 A"] }),
task({ ref: "b", page: "项目 B" }),
]).map((group) => group.project),
).toEqual(["项目 A", "项目 B"]);
});
test("logbook sorts completed metadata before source modification time", () => {
expect(
logbookTasks([
task({ ref: "old", done: true, completed: "2026-08-10" }),
task({ ref: "new", done: true, completed: "2026-08-12" }),
task({ ref: "open" }),
]).map((item) => item.ref),
).toEqual(["new", "old"]);
});