feat: strengthen task workflow and compaction recovery
This commit is contained in:
+43
-3
@@ -170,9 +170,49 @@ test("loads the latest valid mutation snapshot from a session branch", () => {
|
||||
assert.deepEqual(state.list().map((task) => task.name), ["First", "Second"]);
|
||||
});
|
||||
|
||||
test("rejects multiline names while allowing multiline descriptions", () => {
|
||||
test("supports optional descriptions and rejects invalid provided values", () => {
|
||||
const state = new TaskState();
|
||||
assert.throws(() => state.add([{ name: "Bad\nname", description: "Valid" }]), /single line/);
|
||||
state.add([{ name: "Valid", description: "Line one\nLine two" }]);
|
||||
assert.equal(state.list()[0]?.description, "Line one\nLine two");
|
||||
assert.throws(() => state.add([{ name: "Blank description", description: " " }]), /must not be empty/);
|
||||
state.add([
|
||||
{ name: "No description" },
|
||||
{ name: "Detailed", description: "Line one\nLine two" },
|
||||
]);
|
||||
assert.equal(state.list()[0]?.description, undefined);
|
||||
assert.equal(state.list()[1]?.description, "Line one\nLine two");
|
||||
});
|
||||
|
||||
test("set append rejects force and still requires at least one task", () => {
|
||||
const state = new TaskState();
|
||||
assert.throws(() => state.set("append", [], undefined), /tasks must not be empty/);
|
||||
assert.throws(() => state.set("append", [{ name: "Task" }], false), /force is allowed only in replace mode/);
|
||||
assert.deepEqual(state.snapshot(), { tasks: [], nextId: 1 });
|
||||
});
|
||||
|
||||
test("set replace is atomic, guarded, and resets IDs", () => {
|
||||
const state = new TaskState();
|
||||
state.add([{ name: "Old", status: "in-progress" }]);
|
||||
const before = state.snapshot();
|
||||
|
||||
assert.throws(() => state.set("replace", [{ name: "New" }]), /requires force/);
|
||||
assert.throws(
|
||||
() => state.set("replace", [{ name: "Invalid parent", parentId: 1 }], true),
|
||||
/parentId is not allowed in replace mode/,
|
||||
);
|
||||
assert.deepEqual(state.snapshot(), before);
|
||||
|
||||
const replaced = state.set("replace", [{ name: "New", children: [{ name: "Child" }] }], true);
|
||||
assert.deepEqual(replaced.map((task) => task.id), [1, 2]);
|
||||
assert.deepEqual(state.list().map((task) => task.name), ["New", "Child"]);
|
||||
assert.equal(state.snapshot().nextId, 3);
|
||||
|
||||
state.set("replace", [], true);
|
||||
assert.deepEqual(state.snapshot(), { tasks: [], nextId: 1 });
|
||||
});
|
||||
|
||||
test("set replace does not require force after all existing tasks are done", () => {
|
||||
const state = new TaskState();
|
||||
state.add([{ name: "Done", status: "done" }]);
|
||||
state.set("replace", [{ name: "Fresh" }]);
|
||||
assert.deepEqual(state.list().map((task) => [task.id, task.name]), [[1, "Fresh"]]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user