import { describe, expect, it, vi } from "vitest"; import { Capsule } from "../src/capsule.js"; import { Git } from "../src/git/index.js"; describe("Git", () => { it("runs clone with optional path and branch", async () => { const capsule = new Capsule("cap_1", { baseUrl: "https://api.example.com", }); const exec = vi.spyOn(capsule.commands, "exec").mockResolvedValue({ exit_code: 0, stdout: "", }); await expect( capsule.git.clone("https://example.com/repo.git", { branch: "main", path: "/work/repo", }), ).resolves.toMatchObject({ exit_code: 0 }); expect(exec).toHaveBeenCalledWith("git", { args: [ "clone", "--branch", "main", "https://example.com/repo.git", "/work/repo", ], }); }); it("runs repository commands in cwd", async () => { const capsule = new Capsule("cap_1", { baseUrl: "https://api.example.com", }); const git = new Git(capsule, { cwd: "/work/repo" }); const exec = vi.spyOn(capsule.commands, "exec").mockResolvedValue({ exit_code: 0, stdout: "main\n", }); await git.status(); await git.pull({ branch: "main", remote: "origin" }); await git.push({ branch: "main", remote: "origin" }); await git.log({ maxCount: 3 }); await git.branch(); await git.checkout("feature", { create: true }); await git.add(["src/a.ts", "src/b.ts"]); await git.commit("test commit"); expect(exec.mock.calls).toEqual([ ["git", { args: ["status", "--short"], cwd: "/work/repo" }], ["git", { args: ["pull", "origin", "main"], cwd: "/work/repo" }], ["git", { args: ["push", "origin", "main"], cwd: "/work/repo" }], ["git", { args: ["log", "--oneline", "-n", "3"], cwd: "/work/repo" }], ["git", { args: ["branch", "--show-current"], cwd: "/work/repo" }], ["git", { args: ["checkout", "-b", "feature"], cwd: "/work/repo" }], ["git", { args: ["add", "src/a.ts", "src/b.ts"], cwd: "/work/repo" }], ["git", { args: ["commit", "-m", "test commit"], cwd: "/work/repo" }], ]); }); it("rejects empty git add file lists", async () => { const capsule = new Capsule("cap_1", { baseUrl: "https://api.example.com", }); await expect(capsule.git.add([])).rejects.toThrow( "At least one file is required", ); }); it("checks out an existing branch without creating it", async () => { const capsule = new Capsule("cap_1", { baseUrl: "https://api.example.com", }); const exec = vi.spyOn(capsule.commands, "exec").mockResolvedValue({ exit_code: 0, stdout: "", }); await capsule.git.checkout("main"); expect(exec).toHaveBeenCalledWith("git", { args: ["checkout", "main"], }); }); it("normalizes a single string file argument in add", async () => { const capsule = new Capsule("cap_1", { baseUrl: "https://api.example.com", }); const exec = vi.spyOn(capsule.commands, "exec").mockResolvedValue({ exit_code: 0, stdout: "", }); await capsule.git.add("src/a.ts"); expect(exec).toHaveBeenCalledWith("git", { args: ["add", "src/a.ts"], }); }); });