feat(FN-3234): refactor test-changed script and add workflow tests
This merge refactors the test-changed script and adds new CLI tests (FN-3234), keeping automation on the full-suite path. It includes a new test file for the root test command, updates to the CI workflow, and documentation improvements. Fusion-Task-Id: FN-3234
This commit is contained in:
@@ -103,11 +103,12 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
||||
});
|
||||
|
||||
it("keeps contributing docs aligned with verification and slow-lane contracts", () => {
|
||||
expect(contributingContent).toContain("pnpm test` must be runnable in a clean worktree without requiring a prior `pnpm build`.");
|
||||
expect(contributingContent).toContain("pnpm test:full` 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("2. `pnpm test:full`");
|
||||
expect(contributingContent).toContain("3. `pnpm build`");
|
||||
expect(contributingContent).toContain("`pnpm test` now uses a changed-only entrypoint");
|
||||
|
||||
expect(contributingContent).toContain("pnpm test:slow-cli");
|
||||
expect(contributingContent).toContain("test:pre-release");
|
||||
@@ -154,6 +155,35 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("PR checks workflow (.github/workflows/pr-checks.yml)", () => {
|
||||
let workflow: any;
|
||||
let content: string;
|
||||
let steps: any[];
|
||||
|
||||
beforeAll(() => {
|
||||
const result = loadWorkflow("pr-checks.yml");
|
||||
workflow = result.parsed;
|
||||
content = result.content;
|
||||
steps = workflow.jobs?.checks?.steps ?? [];
|
||||
});
|
||||
|
||||
it("is valid YAML", () => {
|
||||
expect(workflow).toBeDefined();
|
||||
expect(typeof workflow).toBe("object");
|
||||
});
|
||||
|
||||
it("runs on pull requests targeting main", () => {
|
||||
expect(workflow.on?.pull_request?.branches).toContain("main");
|
||||
});
|
||||
|
||||
it("runs explicit full-suite tests (not changed-only root test)", () => {
|
||||
const testStep = steps.find((step: any) => step.name?.includes("Test"));
|
||||
expect(testStep).toBeDefined();
|
||||
expect(testStep.run).toBe("pnpm test:full");
|
||||
expect(content).not.toContain("run: pnpm test\n");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Version & Release workflow (.github/workflows/version.yml)", () => {
|
||||
let workflow: any;
|
||||
let content: string;
|
||||
|
||||
@@ -114,19 +114,18 @@ describe("Scoped @fusion/* packages publishing config", () => {
|
||||
describe("Workspace bootstrap script contract", () => {
|
||||
const rootPkg = loadRootPackageJson();
|
||||
|
||||
it("keeps root test self-sufficient (no implicit pre-build dependency)", () => {
|
||||
const testScript = rootPkg.scripts?.test;
|
||||
expect(testScript).toBeDefined();
|
||||
expect(testScript).toContain("pnpm -r");
|
||||
expect(testScript).not.toContain("pnpm build");
|
||||
it("makes root test changed-only while keeping explicit full-suite command", () => {
|
||||
expect(rootPkg.scripts?.test).toBe("node scripts/test-changed.mjs");
|
||||
expect(rootPkg.scripts?.["test:full"]).toContain("pnpm -r --workspace-concurrency=2 test");
|
||||
expect(rootPkg.scripts?.["test:full"]).not.toContain("pnpm build");
|
||||
});
|
||||
|
||||
it("defines verify:workspace in lint -> test -> build order", () => {
|
||||
it("defines verify:workspace in lint -> test:full -> build order", () => {
|
||||
const verifyScript = rootPkg.scripts?.["verify:workspace"];
|
||||
expect(verifyScript).toBe("pnpm lint && pnpm test && pnpm build");
|
||||
expect(verifyScript).toBe("pnpm lint && pnpm test:full && pnpm build");
|
||||
|
||||
const lintIdx = verifyScript.indexOf("pnpm lint");
|
||||
const testIdx = verifyScript.indexOf("pnpm test");
|
||||
const testIdx = verifyScript.indexOf("pnpm test:full");
|
||||
const buildIdx = verifyScript.indexOf("pnpm build");
|
||||
|
||||
expect(lintIdx).toBeGreaterThanOrEqual(0);
|
||||
|
||||
57
packages/cli/src/__tests__/root-test-command.test.ts
Normal file
57
packages/cli/src/__tests__/root-test-command.test.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
decideExecutionPlan,
|
||||
resolveAffectedPackages,
|
||||
shouldForceFullSuite,
|
||||
} from "../../../../scripts/test-changed.mjs";
|
||||
|
||||
describe("root test command changed-only planning", () => {
|
||||
it("uses changed mode when package-only changes are detected", () => {
|
||||
const packageMap = new Map([
|
||||
["core", "@fusion/core"],
|
||||
["engine", "@fusion/engine"],
|
||||
]);
|
||||
|
||||
const plan = decideExecutionPlan({
|
||||
forceFullSuite: false,
|
||||
comparisonBase: "abc123",
|
||||
changedFiles: ["packages/core/src/store.ts", "packages/engine/src/index.ts"],
|
||||
packageNameByDir: packageMap,
|
||||
});
|
||||
|
||||
expect(plan).toEqual({ mode: "changed", packages: ["@fusion/core", "@fusion/engine"] });
|
||||
});
|
||||
|
||||
it("falls back to full suite when shared test infra changes", () => {
|
||||
const plan = decideExecutionPlan({
|
||||
forceFullSuite: false,
|
||||
comparisonBase: "abc123",
|
||||
changedFiles: ["scripts/test-with-lock.mjs"],
|
||||
packageNameByDir: new Map([["core", "@fusion/core"]]),
|
||||
});
|
||||
|
||||
expect(plan).toEqual({ mode: "full", reason: "shared-infra-changed" });
|
||||
});
|
||||
|
||||
it("falls back to full suite when comparison base cannot be resolved", () => {
|
||||
const plan = decideExecutionPlan({
|
||||
forceFullSuite: false,
|
||||
comparisonBase: null,
|
||||
changedFiles: null,
|
||||
packageNameByDir: new Map(),
|
||||
});
|
||||
|
||||
expect(plan).toEqual({ mode: "full", reason: "missing-comparison-base" });
|
||||
});
|
||||
|
||||
it("treats unknown package directories as full-suite fallback", () => {
|
||||
const resolved = resolveAffectedPackages(["packages/unknown/src/index.ts"], new Map());
|
||||
expect(resolved).toBeNull();
|
||||
});
|
||||
|
||||
it("marks root workflow/config changes as full-suite triggers", () => {
|
||||
expect(shouldForceFullSuite([".github/workflows/ci.yml"])).toBe(true);
|
||||
expect(shouldForceFullSuite(["package.json"])).toBe(true);
|
||||
expect(shouldForceFullSuite(["packages/core/src/store.ts"])).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user