Files
llmx/codex-cli/tests/config.test.tsx
Ilan Bigio 59a180ddec Initial commit
Signed-off-by: Ilan Bigio <ilan@openai.com>
2025-04-16 12:56:08 -04:00

107 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type * as fsType from "fs";
import { loadConfig, saveConfig } from "../src/utils/config.js"; // parent import first
import { tmpdir } from "os";
import { join } from "path";
import { test, expect, beforeEach, afterEach, vi } from "vitest";
// Inmemory FS store
let memfs: Record<string, string> = {};
// Mock out the parts of "fs" that our config module uses:
vi.mock("fs", async () => {
// now `real` is the actual fs module
const real = (await vi.importActual("fs")) as typeof fsType;
return {
...real,
existsSync: (path: string) => memfs[path] !== undefined,
readFileSync: (path: string) => {
if (memfs[path] === undefined) {
throw new Error("ENOENT");
}
return memfs[path];
},
writeFileSync: (path: string, data: string) => {
memfs[path] = data;
},
mkdirSync: () => {
// noop in inmemory store
},
rmSync: (path: string) => {
// recursively delete any key under this prefix
const prefix = path.endsWith("/") ? path : path + "/";
for (const key of Object.keys(memfs)) {
if (key === path || key.startsWith(prefix)) {
delete memfs[key];
}
}
},
};
});
let testDir: string;
let testConfigPath: string;
let testInstructionsPath: string;
beforeEach(() => {
memfs = {}; // reset inmemory store
testDir = tmpdir(); // use the OS temp dir as our "cwd"
testConfigPath = join(testDir, "config.json");
testInstructionsPath = join(testDir, "instructions.md");
});
afterEach(() => {
memfs = {};
});
test("loads default config if files don't exist", () => {
const config = loadConfig(testConfigPath, testInstructionsPath, {
disableProjectDoc: true,
});
expect(config).toEqual({
model: "o4-mini",
instructions: "",
});
});
test("saves and loads config correctly", () => {
const testConfig = {
model: "test-model",
instructions: "test instructions",
};
saveConfig(testConfig, testConfigPath, testInstructionsPath);
// Our inmemory fs should now contain those keys:
expect(memfs[testConfigPath]).toContain(`"model": "test-model"`);
expect(memfs[testInstructionsPath]).toBe("test instructions");
const loadedConfig = loadConfig(testConfigPath, testInstructionsPath, {
disableProjectDoc: true,
});
expect(loadedConfig).toEqual(testConfig);
});
test("loads user instructions + project doc when codex.md is present", () => {
// 1) seed memfs: a config JSON, an instructions.md, and a codex.md in the cwd
const userInstr = "here are user instructions";
const projectDoc = "# Project Title\n\nSome projectspecific doc";
// first, make config so loadConfig will see storedConfig
memfs[testConfigPath] = JSON.stringify({ model: "mymodel" }, null, 2);
// then user instructions:
memfs[testInstructionsPath] = userInstr;
// and now our fake codex.md in the cwd:
const codexPath = join(testDir, "codex.md");
memfs[codexPath] = projectDoc;
// 2) loadConfig without disabling projectdoc, but with cwd=testDir
const cfg = loadConfig(testConfigPath, testInstructionsPath, {
cwd: testDir,
});
// 3) assert we got both pieces concatenated
expect(cfg.model).toBe("mymodel");
expect(cfg.instructions).toBe(
userInstr + "\n\n--- project-doc ---\n\n" + projectDoc,
);
});