Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/strata/__serial__/draft.test.ts

Raw
import { describe, expect, it } from "vitest";
import { carryDraft } from "../draft.js";
import type { Draft, Hunk, Snapshot } from "../types.js";

function hunk(id: string, offset = 0): Hunk {
	return {
		id,
		path: "src/change.ts",
		header: `@@ -${offset + 1},2 +${offset + 1},2 @@ function change()`,
		lines: [
			{ kind: "add", text: "next", newLine: offset + 1 },
			{
				kind: "context",
				text: "same",
				oldLine: offset + 2,
				newLine: offset + 2,
			},
		],
	};
}

function snapshot(hunks: Hunk[]): Snapshot {
	return {
		id: "snapshot",
		repoRoot: "/project",
		source: { kind: "working" },
		base: "base",
		head: "head",
		hunks,
		skipped: [],
	};
}

const draft: Draft = {
	reviewed: ["original"],
	findings: [
		{
			id: "finding",
			hunkId: "original",
			side: "new",
			line: 1,
			endLine: 2,
			severity: "major",
			text: "Human range comment",
		},
	],
	notes: "Preserve these notes",
};

describe("review continuity", () => {
	it("maps uniquely unchanged content and range coordinates after a line shift", () => {
		const carried = carryDraft(
			snapshot([hunk("original")]),
			snapshot([hunk("shifted", 10)]),
			draft,
		);
		expect(carried.orphaned).toEqual([]);
		expect(carried.draft).toEqual({
			...draft,
			reviewed: ["shifted"],
			findings: [
				{ ...draft.findings[0], hunkId: "shifted", line: 11, endLine: 12 },
			],
		});
	});

	it.each(["previous", "next"] as const)(
		"does not transfer ambiguous %s hunks",
		(side) => {
			const previous = [hunk("original")];
			const next = [hunk("shifted", 10)];
			if (side === "previous") previous.push(hunk("duplicate", 20));
			else next.push(hunk("duplicate", 20));
			const carried = carryDraft(snapshot(previous), snapshot(next), draft);
			expect(carried.draft).toEqual({
				reviewed: [],
				findings: [],
				notes: draft.notes,
			});
			expect(carried.orphaned).toEqual(draft.findings);
		},
	);

	it("does not transfer changed content or function context", () => {
		for (const changed of [
			{ ...hunk("new"), header: "@@ -1,2 +1,2 @@ function other()" },
			{
				...hunk("new"),
				lines: [{ kind: "add" as const, text: "different", newLine: 1 }],
			},
		]) {
			expect(
				carryDraft(snapshot([hunk("original")]), snapshot([changed]), draft)
					.draft.reviewed,
			).toEqual([]);
		}
	});
});