test(FN-2358): harden clean-worktree CI verification tests

- Assert contributing docs explicitly state that pnpm test must run without prior build outputs
- Add CI workflow test coverage to keep docs and verify:workspace ordering aligned
- Expand Vitest workspace alias assertions to include @fusion/test-utils and src-only replacements
- Validate real symbol imports from workspace packages when dist directories are absent
This commit is contained in:
Fusion
2026-04-23 16:32:01 -07:00
committed by gsxdsm
parent 58b69e7310
commit 82b4c696d8
3 changed files with 43 additions and 8 deletions

View File

@@ -23,12 +23,14 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
let workflow: any;
let content: string;
let ciSteps: any[];
let contributingContent: string;
beforeAll(() => {
const result = loadWorkflow("ci.yml");
workflow = result.parsed;
content = result.content;
ciSteps = workflow.jobs?.ci?.steps ?? [];
contributingContent = readFileSync(join(workspaceRoot, "docs", "contributing.md"), "utf-8");
});
const findStepByRun = (runSnippet: string) => ciSteps.find((step) => typeof step.run === "string" && step.run.includes(runSnippet));
@@ -74,6 +76,14 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
expect(buildExeIdx).toBeGreaterThan(verifyIdx);
});
it("keeps contributing docs aligned with the clean-worktree verification contract", () => {
expect(contributingContent).toContain("pnpm test` must be runnable in a clean worktree without requiring a prior `pnpm build`.");
expect(contributingContent).toContain("`pnpm verify:workspace` is the canonical pre-merge gate");
expect(contributingContent).toContain("1. `pnpm lint`");
expect(contributingContent).toContain("2. `pnpm test`");
expect(contributingContent).toContain("3. `pnpm build`");
});
it("includes binary build step", () => {
expect(content).toContain("build:exe");
});

View File

@@ -64,17 +64,27 @@ describe("CLI Vitest workspace resolution", () => {
find: String(/^@fusion\/engine$/),
replacement: join(workspaceRoot, "packages", "engine", "src", "index.ts"),
},
{
find: String(/^@fusion\/dashboard\/planning$/),
replacement: join(workspaceRoot, "packages", "dashboard", "src", "planning.ts"),
},
{
find: String(/^@fusion\/dashboard$/),
replacement: join(workspaceRoot, "packages", "dashboard", "src", "index.ts"),
},
{
find: String(/^@fusion\/dashboard\/planning$/),
replacement: join(workspaceRoot, "packages", "dashboard", "src", "planning.ts"),
find: String(/^@fusion\/test-utils$/),
replacement: join(workspaceRoot, "packages", "core", "src", "__test-utils__", "workspace.ts"),
},
]),
);
for (const entry of normalized) {
expect(entry.replacement).toContain(`${join("packages", "")}`);
expect(entry.replacement).toContain(`${join("src", "")}`);
expect(entry.replacement).not.toContain(`${join("dist", "")}`);
}
const coreGhCliIndex = normalized.findIndex((entry) => entry.find === String(/^@fusion\/core\/gh-cli$/));
const coreIndex = normalized.findIndex((entry) => entry.find === String(/^@fusion\/core$/));
const planningIndex = normalized.findIndex((entry) => entry.find === String(/^@fusion\/dashboard\/planning$/));
@@ -86,11 +96,25 @@ describe("CLI Vitest workspace resolution", () => {
expect(dashboardIndex).toBeGreaterThan(planningIndex);
});
it("resolves internal workspace imports during CLI tests when dist outputs are absent", async () => {
await expect(import("@fusion/core")).resolves.toBeTruthy();
await expect(import("@fusion/core/gh-cli")).resolves.toBeTruthy();
await expect(import("@fusion/engine")).resolves.toBeTruthy();
await expect(import("@fusion/dashboard")).resolves.toBeTruthy();
await expect(import("@fusion/dashboard/planning")).resolves.toBeTruthy();
it("resolves non-mocked symbols from internal workspace packages when dist outputs are absent", async () => {
const [{ tempWorkspace }, { PRIORITY_EXECUTE }, { createRuntimeLogger }, { parseAgentResponse }] = await Promise.all([
import("@fusion/test-utils"),
import("@fusion/engine"),
import("@fusion/dashboard"),
import("@fusion/dashboard/planning"),
]);
expect(typeof tempWorkspace).toBe("function");
expect(typeof PRIORITY_EXECUTE).toBe("number");
expect(typeof createRuntimeLogger).toBe("function");
expect(parseAgentResponse('{"type":"question","data":{"id":"q","type":"confirm","question":"Ok?","description":"desc"}}')).toEqual({
type: "question",
data: {
id: "q",
type: "confirm",
question: "Ok?",
description: "desc",
},
});
}, 30_000);
});