test / root.test.ts
import { promises as fs } from "fs";
import * as path from "path";
import { describe, expect, it } from "vitest";
import { resolveRoot } from "../src/root";
import { makeRoot } from "./helpers";
const throwingChat = () => {
throw new Error("not attached");
};
describe("resolveRoot", () => {
it("prefers the setting over the chat directory", async () => {
const setting = await makeRoot();
const chat = await makeRoot();
expect(await resolveRoot(setting, () => chat)).toBe(setting);
});
it("falls back to the chat directory for an empty or whitespace setting", async () => {
const chat = await makeRoot();
expect(await resolveRoot("", () => chat)).toBe(chat);
expect(await resolveRoot(" ", () => chat)).toBe(chat);
});
it("errors mentioning the setting when neither is available", async () => {
await expect(resolveRoot("", throwingChat)).rejects.toThrow('"Working directory"');
});
it("expands ~ and ~/sub using the home directory", async () => {
const home = await makeRoot();
await fs.mkdir(path.join(home, "sub"));
const fake = () => home;
expect(await resolveRoot("~", throwingChat, fake)).toBe(home);
expect(await resolveRoot("~/sub", throwingChat, fake)).toBe(path.join(home, "sub"));
});
it("rejects a relative path", async () => {
await expect(resolveRoot("some/relative", throwingChat)).rejects.toThrow(
'read-write: "Working directory" setting must be an absolute path to an existing directory (got: some/relative)',
);
});
it("rejects a nonexistent path", async () => {
const dir = await makeRoot();
const bad = path.join(dir, "nope");
await expect(resolveRoot(bad, throwingChat)).rejects.toThrow(`(got: ${bad})`);
});
it("rejects a path that is a file", async () => {
const dir = await makeRoot();
const file = path.join(dir, "f.txt");
await fs.writeFile(file, "x");
await expect(resolveRoot(file, throwingChat)).rejects.toThrow('"Working directory" setting must be');
});
it("does not fall back to the chat directory when the setting is invalid", async () => {
const chat = await makeRoot();
await expect(resolveRoot("/definitely/not/here", () => chat)).rejects.toThrow(
'"Working directory" setting must be',
);
});
it("returns the realpath of a symlinked directory", async () => {
const dir = await makeRoot();
const link = path.join(await makeRoot(), "link");
await fs.symlink(dir, link);
expect(await resolveRoot(link, throwingChat)).toBe(dir);
});
});
test / root.test.ts
import { promises as fs } from "fs";
import * as path from "path";
import { describe, expect, it } from "vitest";
import { resolveRoot } from "../src/root";
import { makeRoot } from "./helpers";
const throwingChat = () => {
throw new Error("not attached");
};
describe("resolveRoot", () => {
it("prefers the setting over the chat directory", async () => {
const setting = await makeRoot();
const chat = await makeRoot();
expect(await resolveRoot(setting, () => chat)).toBe(setting);
});
it("falls back to the chat directory for an empty or whitespace setting", async () => {
const chat = await makeRoot();
expect(await resolveRoot("", () => chat)).toBe(chat);
expect(await resolveRoot(" ", () => chat)).toBe(chat);
});
it("errors mentioning the setting when neither is available", async () => {
await expect(resolveRoot("", throwingChat)).rejects.toThrow('"Working directory"');
});
it("expands ~ and ~/sub using the home directory", async () => {
const home = await makeRoot();
await fs.mkdir(path.join(home, "sub"));
const fake = () => home;
expect(await resolveRoot("~", throwingChat, fake)).toBe(home);
expect(await resolveRoot("~/sub", throwingChat, fake)).toBe(path.join(home, "sub"));
});
it("rejects a relative path", async () => {
await expect(resolveRoot("some/relative", throwingChat)).rejects.toThrow(
'read-write: "Working directory" setting must be an absolute path to an existing directory (got: some/relative)',
);
});
it("rejects a nonexistent path", async () => {
const dir = await makeRoot();
const bad = path.join(dir, "nope");
await expect(resolveRoot(bad, throwingChat)).rejects.toThrow(`(got: ${bad})`);
});
it("rejects a path that is a file", async () => {
const dir = await makeRoot();
const file = path.join(dir, "f.txt");
await fs.writeFile(file, "x");
await expect(resolveRoot(file, throwingChat)).rejects.toThrow('"Working directory" setting must be');
});
it("does not fall back to the chat directory when the setting is invalid", async () => {
const chat = await makeRoot();
await expect(resolveRoot("/definitely/not/here", () => chat)).rejects.toThrow(
'"Working directory" setting must be',
);
});
it("returns the realpath of a symlinked directory", async () => {
const dir = await makeRoot();
const link = path.join(await makeRoot(), "link");
await fs.symlink(dir, link);
expect(await resolveRoot(link, throwingChat)).toBe(dir);
});
});