- Update generated types from new openapi.yaml (capsule stats, usage, metrics, pause/resume lifecycle, host/channel management, auth flow) - Add Capsule pause/resume/ping/getMetrics lifecycle methods - Add Capsule.waitForReady abort signal support - Add PtyManager.connect and PtySession disposal - Fix HttpClient empty-body response handling (content-length: 0) - Add streamProcess() to CommandManager for background process streams - Add integration tests for capsule lifecycle, git, and PTY features - Add unit tests for AsyncQueue error paths, PtySession.close, Git.checkout without create, Git.add single string, Notebook.execCell error case, and PtyStartOptions fields
107 lines
3.0 KiB
TypeScript
107 lines
3.0 KiB
TypeScript
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"],
|
|
});
|
|
});
|
|
});
|