test(FN-5094): complete Step 4 — add inline attribution coverage

Fusion-Task-Id: FN-5094
Fusion-Task-Lineage: c6c9710c-51fe-40e9-bfad-bfb6d589c7f4
This commit is contained in:
Fusion (runfusion.ai)
2026-05-18 21:26:58 -07:00
committed by gsxdsm
parent a25ef82e13
commit 12d718166c
2 changed files with 50 additions and 20 deletions

View File

@@ -396,29 +396,37 @@ describe("branch-conflicts", () => {
});
});
it("assertCleanBranchAtBase passes when no foreign task commits exist", async () => {
it.each([
{
name: "passes when attribution comes from subject token",
log: "aaa111\u001ffeat(FN-4068): own\u001f\n",
expectForeign: false,
},
{
name: "passes when attribution comes from trailer token",
log: "aaa111\u001ffeat: own\u001fFusion-Task-Id: FN-4068\n",
expectForeign: false,
},
{
name: "throws when commit is attributed to a foreign task",
log: "bbb222\u001ffeat(FN-4386): foreign\u001fFusion-Task-Id: FN-4386\n",
expectForeign: true,
},
])("assertCleanBranchAtBase $name", async ({ log, expectForeign }) => {
mockedExecSync.mockImplementation((cmd: string | string[]) => {
const command = typeof cmd === "string" ? cmd : cmd[0];
if (command.includes("git log --format=%H%x1f%s%x1f%b 'main..fusion/fn-4068'")) {
return Buffer.from("aaa111\u001ffeat(FN-4068): own\u001fFusion-Task-Id: FN-4068\n");
return Buffer.from(log);
}
throw new Error(`Unexpected command: ${command}`);
});
await expect(assertCleanBranchAtBase("/tmp/repo", "fusion/fn-4068", "main", "FN-4068")).resolves.toBeUndefined();
});
it("assertCleanBranchAtBase throws BranchCrossContaminationError for foreign commits", async () => {
mockedExecSync.mockImplementation((cmd: string | string[]) => {
const command = typeof cmd === "string" ? cmd : cmd[0];
if (command.includes("git log --format=%H%x1f%s%x1f%b 'main..fusion/fn-4068'")) {
return Buffer.from("bbb222\u001ffeat(FN-4386): foreign\u001fFusion-Task-Id: FN-4386\n");
}
throw new Error(`Unexpected command: ${command}`);
});
await expect(assertCleanBranchAtBase("/tmp/repo", "fusion/fn-4068", "main", "FN-4068"))
.rejects.toBeInstanceOf(BranchCrossContaminationError);
const assertion = assertCleanBranchAtBase("/tmp/repo", "fusion/fn-4068", "main", "FN-4068");
if (expectForeign) {
await expect(assertion).rejects.toBeInstanceOf(BranchCrossContaminationError);
return;
}
await expect(assertion).resolves.toBeUndefined();
});
it("lists canonical and sibling recovery candidates with worktrees and stranded commits", async () => {

View File

@@ -65,7 +65,29 @@ describeIfGit("classifyOwnedLandedEvidence", () => {
}
});
it("does not return no-changes-finalized when aheadCount has foreign deltas", async () => {
it.each([
{
name: "foreign trailer token",
message: "feat: foreign trailer",
trailer: "Fusion-Task-Id: FN-OTHER",
taskId: "FN-TARGET",
expectForeign: true,
},
{
name: "foreign subject token",
message: "feat(FN-OTHER): foreign subject",
trailer: "notes",
taskId: "FN-TARGET",
expectForeign: true,
},
{
name: "own subject and trailer tokens",
message: "feat(FN-TARGET): own",
trailer: "Fusion-Task-Id: FN-TARGET",
taskId: "FN-TARGET",
expectForeign: false,
},
])("does not return no-changes-finalized when aheadCount includes $name", async ({ message, trailer, taskId, expectForeign }) => {
const repo = mkdtempSync(join(tmpdir(), "fusion-owned-landed-classify-"));
try {
git(repo, "git init -b main");
@@ -75,18 +97,18 @@ describeIfGit("classifyOwnedLandedEvidence", () => {
git(repo, "git checkout -b fusion/fn-target");
writeFileSync(join(repo, "foreign.txt"), "foreign\n", "utf-8");
git(repo, "git add foreign.txt && git commit -m 'feat(FN-OTHER): foreign' -m 'Fusion-Task-Id: FN-OTHER'");
git(repo, `git add foreign.txt && git commit -m ${JSON.stringify(message)} -m ${JSON.stringify(trailer)}`);
git(repo, "git checkout main");
const classification = await classifyOwnedLandedEvidence(
repo,
{ id: "FN-TARGET", branch: "fusion/fn-target" } as Task,
{ id: taskId, branch: "fusion/fn-target" } as Task,
{ mergeTargetBranch: "main" },
);
expect(classification.kind).toBe("unproven");
if (classification.kind === "unproven") {
expect(classification.reason).toBe("no-owned-commit-foreign-deltas");
expect(classification.reason).toBe(expectForeign ? "no-owned-commit-foreign-deltas" : "missing-evidence");
}
} finally {
rmSync(repo, { recursive: true, force: true });