obsidian-plugin-markdown-tasks/test/taskActions.test.ts
Felipe M. 486500fe20
Convert plain lines to tasks when cycling
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.
2026-05-06 08:13:00 +02:00

116 lines
3.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"]);
});
});