The cycle task status command now turns a non-task line into `- [ ]` (or inserts `[ ]` after an existing list marker), so users can run the shortcut on plain text without first creating a task. Adds a bun test preload that mocks the obsidian runtime so taskActions can be unit-tested directly.
116 lines
3.8 KiB
TypeScript
116 lines
3.8 KiB
TypeScript
import {describe, expect, it} from "bun:test";
|
||
import type {Editor} from "obsidian";
|
||
import {createTask, cycleTaskStatus} from "../src/taskActions";
|
||
import type {MarkdownTasksSettings} from "../src/settings";
|
||
|
||
const baseSettings = {
|
||
completedSymbol: "x",
|
||
inProgressSymbol: "/",
|
||
movedSymbol: ">",
|
||
cycleStatuses: {open: true, inProgress: true, completed: true, moved: false},
|
||
} as unknown as MarkdownTasksSettings;
|
||
|
||
const settings = (overrides: Partial<MarkdownTasksSettings> = {}): MarkdownTasksSettings => ({
|
||
...baseSettings,
|
||
...overrides,
|
||
});
|
||
|
||
interface FakeEditor {
|
||
editor: Editor;
|
||
getLines(): string[];
|
||
}
|
||
|
||
function makeEditor(initial: string[], from = 0, to = initial.length - 1): FakeEditor {
|
||
const lines = [...initial];
|
||
const editor = {
|
||
getCursor: (which: "from" | "to") => ({line: which === "from" ? from : to, ch: 0}),
|
||
getLine: (n: number) => lines[n],
|
||
setLine: (n: number, text: string) => {
|
||
lines[n] = text;
|
||
},
|
||
} as unknown as Editor;
|
||
return {editor, getLines: () => lines};
|
||
}
|
||
|
||
describe("cycleTaskStatus – existing tasks", () => {
|
||
it("cycles open → in-progress with default settings", () => {
|
||
const fake = makeEditor(["- [ ] thing"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [/] thing"]);
|
||
});
|
||
|
||
it("wraps the last enabled status back to the first", () => {
|
||
const fake = makeEditor(["- [x] done"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [ ] done"]);
|
||
});
|
||
|
||
it("treats unknown markers as the start of the cycle", () => {
|
||
const fake = makeEditor(["- [?] mystery"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [ ] mystery"]);
|
||
});
|
||
|
||
it("does nothing when no statuses are enabled in the cycle", () => {
|
||
const fake = makeEditor(["- [ ] thing"]);
|
||
cycleTaskStatus(
|
||
fake.editor,
|
||
settings({
|
||
cycleStatuses: {open: false, inProgress: false, completed: false, moved: false},
|
||
}),
|
||
);
|
||
expect(fake.getLines()).toEqual(["- [ ] thing"]);
|
||
});
|
||
});
|
||
|
||
describe("cycleTaskStatus – non-task lines", () => {
|
||
it("converts a plain text line into an open task", () => {
|
||
const fake = makeEditor(["just some text"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [ ] just some text"]);
|
||
});
|
||
|
||
it("preserves indentation when converting plain text", () => {
|
||
const fake = makeEditor([" hello"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual([" - [ ] hello"]);
|
||
});
|
||
|
||
it("turns a bullet list item into a task without changing its marker", () => {
|
||
const fake = makeEditor(["* shopping"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["* [ ] shopping"]);
|
||
});
|
||
|
||
it("turns an ordered list item into a task without changing its marker", () => {
|
||
const fake = makeEditor(["1. first"]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["1. [ ] first"]);
|
||
});
|
||
|
||
it("leaves an empty line as a bare task", () => {
|
||
const fake = makeEditor([""]);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [ ] "]);
|
||
});
|
||
|
||
it("converts non-task lines and cycles existing tasks within the same selection", () => {
|
||
const fake = makeEditor(["plain", "- [ ] task", "- next"], 0, 2);
|
||
cycleTaskStatus(fake.editor, settings());
|
||
expect(fake.getLines()).toEqual(["- [ ] plain", "- [/] task", "- [ ] next"]);
|
||
});
|
||
});
|
||
|
||
describe("createTask – unchanged behavior", () => {
|
||
it("does not modify a line that is already a task", () => {
|
||
const fake = makeEditor(["- [/] in progress"]);
|
||
createTask(fake.editor);
|
||
expect(fake.getLines()).toEqual(["- [/] in progress"]);
|
||
});
|
||
|
||
it("converts plain text into an open task", () => {
|
||
const fake = makeEditor(["plain"]);
|
||
createTask(fake.editor);
|
||
expect(fake.getLines()).toEqual(["- [ ] plain"]);
|
||
});
|
||
});
|