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
Co-Authored-By: Codex <noreply@anthropic.com>
114 lines
3.5 KiB
TypeScript
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"]);
|
|
});
|