mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-05 12:29:37 +01:00
27 lines
2.1 KiB
TypeScript
27 lines
2.1 KiB
TypeScript
import { it, expect } from "vitest";
|
|
import { gradeDependencyCycle } from "./runtime-task-coordination.js";
|
|
function valid() {
|
|
const website = { id: "website", title: "Website", companyId: "company", status: "backlog", blockedBy: [] };
|
|
const design = { id: "design", title: "Design", companyId: "company", status: "backlog", blockedBy: [{ id: "website" }] };
|
|
return { scenarioId: "task-coordination.reject-dependency-cycle", origin: "http://fixture.invalid", companyId: "company", leadId: "ceo",
|
|
state: { task: website, design }, dependencyTasks: [structuredClone(website), structuredClone(design)], agents: [], tasks: [website, design],
|
|
links: ["/ACORN/issues/website", "/ACORN/issues/design"], reply: "Design already depends on Website. That would be circular. Choose which should go first.",
|
|
activity: [], runs: [], humanQueries: [] };
|
|
}
|
|
it("accepts an independently saved acyclic rejection", () => expect(gradeDependencyCycle(valid()).passed).toBe(true));
|
|
it("accepts natural actionable cycle explanation", () => { const o = valid(); o.reply = "Design already waits for Website. Adding the reverse edge would make a dependency cycle; tell me which task should go first."; expect(gradeDependencyCycle(o).passed).toBe(true); });
|
|
it("rejects missing dependency detail", () => expect(gradeDependencyCycle(undefined).passed).toBe(false));
|
|
it("rejects a plausible explanation with the cycle actually saved", () => {
|
|
const o = valid(); o.dependencyTasks[0]!.blockedBy = [{ id: "design" }]; expect(gradeDependencyCycle(o).passed).toBe(false);
|
|
});
|
|
it("rejects silently deleting the original prerequisite", () => {
|
|
const o = valid(); o.dependencyTasks[1]!.blockedBy = []; expect(gradeDependencyCycle(o).passed).toBe(false);
|
|
});
|
|
it("rejects a conflict with no actionable order decision", () => {
|
|
const o = valid(); o.reply = "Website and Design form a cycle."; expect(gradeDependencyCycle(o).passed).toBe(false);
|
|
});
|
|
|
|
it("accepts a saved acyclic rejection naming both tasks without mandatory chat hrefs", () => {
|
|
const o = valid(); o.links = []; expect(gradeDependencyCycle(o).passed).toBe(true);
|
|
});
|