test: flush microtasks instead of real sleeps in plugin-runner tests

Replace real-timer waits with a deterministic bounded microtask flush for
the fire-and-forget task lifecycle hook chain (FN-5048: no slow tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-07-03 09:53:17 -07:00
parent a318267976
commit 2a844514a1

View File

@@ -32,6 +32,19 @@ vi.mock("../logger.js", () => ({
},
}));
/*
FNXC:PluginRunnerTests 2026-07-02-17:20:
Task lifecycle handlers are fire-and-forget (`void this.invokeHookSafe(...)`), but the mock
`invokeHook` seam resolves through awaited microtasks, never real timers. Flush a bounded number
of microtask turns deterministically instead of paying real `setTimeout` wall-clock sleeps
(FN-5048: prefer fake timers/deterministic seams over real time waits — no slow tests).
*/
async function flushMicrotasks(turns = 4): Promise<void> {
for (let i = 0; i < turns; i++) {
await Promise.resolve();
}
}
describe("PluginRunner", () => {
let mockPluginLoader: {
loadAllPlugins: ReturnType<typeof vi.fn>;
@@ -1453,9 +1466,10 @@ describe("PluginRunner", () => {
if (createdHandler) {
createdHandler(mockTask);
}
// Let the fire-and-forget hook chain settle via microtasks (no real sleep).
await flushMicrotasks();
expect(mockPluginLoader.invokeHook).toHaveBeenCalledWith(
"onTaskCreated",
mockTask
@@ -1476,9 +1490,10 @@ describe("PluginRunner", () => {
if (movedHandler) {
movedHandler({ task: mockTask, from: "todo", to: "in-progress" });
}
// Let the fire-and-forget hook chain settle via microtasks (no real sleep).
await flushMicrotasks();
expect(mockPluginLoader.invokeHook).toHaveBeenCalledWith(
"onTaskMoved",
mockTask,
@@ -1513,9 +1528,10 @@ describe("PluginRunner", () => {
if (movedHandler) {
movedHandler({ task: mockTask, from: "in-progress", to: "done" });
}
// Let the fire-and-forget hook chain settle via microtasks (no real sleep).
await flushMicrotasks();
expect(mockPluginLoader.invokeHook).toHaveBeenCalledWith(
"onTaskCompleted",
mockTask
@@ -1545,9 +1561,10 @@ describe("PluginRunner", () => {
if (movedHandler) {
movedHandler({ task: mockTask, from: "todo", to: "in-progress" });
}
// Let the fire-and-forget hook chain settle via microtasks (no real sleep).
await flushMicrotasks();
expect(mockPluginLoader.invokeHook).not.toHaveBeenCalledWith(
"onTaskCompleted",
expect.anything()