1import type { FileDiffMetadata } from "@pierre/diffs";
2import { EnvironmentId, type ReviewDiffFileContentsResult } from "@t3tools/contracts";
3import * as Cause from "effect/Cause";
4import { AsyncResult } from "effect/reactivity";
5import { describe, expect, it, vi } from "vite-plus/test";
6
7import { createGitDiffFileContentsLoader } from "./diffFileContents";
8
9const SOURCE = {
10 environmentId: EnvironmentId.make("environment-1"),
11 cwd: "/workspace",
12 sourceKind: "branch-range" as const,
13 baseRef: "main",
14 headRef: "feature",
15 cacheKey: "comparison-1",
16};
17
18function fileDiff(type: FileDiffMetadata["type"] = "rename-changed"): FileDiffMetadata {
19 return {
20 type,
21 prevName: "src/old-name.ts",
22 name: "src/new-name.ts",
23 } as FileDiffMetadata;
24}
25
26describe("createGitDiffFileContentsLoader", () => {
27 it("loads both sides with normalized paths and comparison-scoped cache keys", async () => {
28 const getDiffFileContents = vi.fn(async () =>
29 AsyncResult.success({ oldContents: "before\n", newContents: "after\n" }),
30 );
31 const load = createGitDiffFileContentsLoader(getDiffFileContents, SOURCE);
32
33 await expect(load(fileDiff())).resolves.toEqual({
34 oldFile: {
35 name: "src/old-name.ts",
36 contents: "before\n",
37 cacheKey: "comparison-1:old:src/old-name.ts",
38 },
39 newFile: {
40 name: "src/new-name.ts",
41 contents: "after\n",
42 cacheKey: "comparison-1:new:src/new-name.ts",
43 },
44 });
45 expect(getDiffFileContents).toHaveBeenCalledWith({
46 environmentId: "environment-1",
47 input: {
48 cwd: "/workspace",
49 sourceKind: "branch-range",
50 changeType: "rename-changed",
51 baseRef: "main",
52 headRef: "feature",
53 oldPath: "src/old-name.ts",
54 newPath: "src/new-name.ts",
55 },
56 });
57 });
58
59 it("loads a pure rename from its one shared file", async () => {
60 const getDiffFileContents = vi.fn(async () =>
61 AsyncResult.success({ oldContents: "same\n", newContents: "same\n" }),
62 );
63 const load = createGitDiffFileContentsLoader(getDiffFileContents, SOURCE);
64
65 await expect(load(fileDiff("rename-pure"))).resolves.toMatchObject({
66 oldFile: null,
67 newFile: { name: "src/new-name.ts", contents: "same\n" },
68 });
69 });
70
71 it("passes command failures through to Pierre's expansion handling", async () => {
72 const failure = new Error("revision is not available locally");
73 const getDiffFileContents = vi.fn(async () =>
74 AsyncResult.failure<ReviewDiffFileContentsResult, Error>(Cause.fail(failure)),
75 );
76 const load = createGitDiffFileContentsLoader(getDiffFileContents, SOURCE);
77
78 await expect(load(fileDiff())).rejects.toBe(failure);
79 });
80});