feat(FN-4990): complete Step 2 — recompute currentStep after lost work reset
Fusion-Task-Id: FN-4990 Fusion-Task-Lineage: 167a6011-d246-45bd-ad7a-1f2fe8b99323
This commit is contained in:
committed by
gsxdsm
parent
f9f8ca04b9
commit
7bcffa5a58
@@ -0,0 +1,62 @@
|
|||||||
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import "./executor-test-helpers.js";
|
||||||
|
import { TaskExecutor } from "../executor.js";
|
||||||
|
import type { Task } from "@fusion/core";
|
||||||
|
import { createMockStore, mockedExecSync, resetExecutorMocks } from "./executor-test-helpers.js";
|
||||||
|
|
||||||
|
describe("TaskExecutor.resetStepsIfWorkLost", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
resetExecutorMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resets completed steps and recomputes currentStep when branch has no unique commits", async () => {
|
||||||
|
const store = createMockStore();
|
||||||
|
const task: Task = {
|
||||||
|
id: "FN-4990",
|
||||||
|
title: "Reset steps",
|
||||||
|
description: "desc",
|
||||||
|
column: "in-progress",
|
||||||
|
dependencies: [],
|
||||||
|
steps: [
|
||||||
|
{ name: "Step 1", status: "done" },
|
||||||
|
{ name: "Step 2", status: "done" },
|
||||||
|
{ name: "Step 3", status: "done" },
|
||||||
|
{ name: "Step 4", status: "pending" },
|
||||||
|
{ name: "Step 5", status: "pending" },
|
||||||
|
],
|
||||||
|
currentStep: 3,
|
||||||
|
log: [],
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
branch: "fusion/fn-4990",
|
||||||
|
};
|
||||||
|
|
||||||
|
store.getTask.mockImplementation(async () => task);
|
||||||
|
store.updateStep.mockImplementation(async (_taskId: string, stepIndex: number, status: Task["steps"][number]["status"]) => {
|
||||||
|
task.steps[stepIndex].status = status;
|
||||||
|
return task;
|
||||||
|
});
|
||||||
|
store.updateTask.mockImplementation(async (_taskId: string, updates: Partial<Task>) => {
|
||||||
|
Object.assign(task, updates);
|
||||||
|
return task;
|
||||||
|
});
|
||||||
|
|
||||||
|
mockedExecSync.mockImplementation((cmd: string) => {
|
||||||
|
if (cmd.includes("git merge-base")) return "abc123\n";
|
||||||
|
if (cmd.includes("git rev-parse")) return "abc123\n";
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
|
||||||
|
const executor = new TaskExecutor(store as any, "/tmp/test");
|
||||||
|
await (executor as any).resetStepsIfWorkLost(task);
|
||||||
|
|
||||||
|
expect(task.steps[0].status).toBe("pending");
|
||||||
|
expect(task.steps[1].status).toBe("pending");
|
||||||
|
expect(task.steps[2].status).toBe("pending");
|
||||||
|
expect(task.currentStep).toBe(0);
|
||||||
|
expect(store.logEntry).toHaveBeenCalledWith(
|
||||||
|
task.id,
|
||||||
|
expect.stringContaining("currentStep"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -9417,6 +9417,23 @@ Backward compat fallback: if JSON is unavailable, you may still begin output wit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const refreshedTask = await this.store.getTask(task.id);
|
||||||
|
const prevCurrentStep = refreshedTask.currentStep;
|
||||||
|
if (refreshedTask.steps.length > 0) {
|
||||||
|
const firstPendingStep = refreshedTask.steps.findIndex((s) => s.status === "pending");
|
||||||
|
const newCurrentStep = firstPendingStep >= 0 ? firstPendingStep : 0;
|
||||||
|
if (newCurrentStep !== prevCurrentStep) {
|
||||||
|
await this.store.updateTask(task.id, { currentStep: newCurrentStep });
|
||||||
|
executorLog.log(
|
||||||
|
`${task.id}: reset currentStep to ${newCurrentStep} after lost-work reset (was ${prevCurrentStep})`,
|
||||||
|
);
|
||||||
|
await this.store.logEntry(
|
||||||
|
task.id,
|
||||||
|
`Reset currentStep to ${newCurrentStep} after lost-work step reset (was ${prevCurrentStep})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await this.store.logEntry(
|
await this.store.logEntry(
|
||||||
task.id,
|
task.id,
|
||||||
`Reset ${completedSteps.length} step(s) to pending — branch had no commits (uncommitted work lost with worktree)`,
|
`Reset ${completedSteps.length} step(s) to pending — branch had no commits (uncommitted work lost with worktree)`,
|
||||||
|
|||||||
Reference in New Issue
Block a user