test(infra): dedupe dotenv fixture setup and cover fallback-only load

This commit is contained in:
Peter Steinberger
2026-02-21 19:34:23 +00:00
parent c394c5fa99
commit 2042a69211

View File

@@ -31,46 +31,69 @@ async function withIsolatedEnvAndCwd(run: () => Promise<void>) {
}
}
type DotEnvFixture = {
base: string;
cwdDir: string;
stateDir: string;
};
async function withDotEnvFixture(run: (fixture: DotEnvFixture) => Promise<void>) {
const base = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-dotenv-test-"));
const cwdDir = path.join(base, "cwd");
const stateDir = path.join(base, "state");
process.env.OPENCLAW_STATE_DIR = stateDir;
await fs.mkdir(cwdDir, { recursive: true });
await fs.mkdir(stateDir, { recursive: true });
await run({ base, cwdDir, stateDir });
}
describe("loadDotEnv", () => {
it("loads ~/.openclaw/.env as fallback without overriding CWD .env", async () => {
await withIsolatedEnvAndCwd(async () => {
const base = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-dotenv-test-"));
const cwdDir = path.join(base, "cwd");
const stateDir = path.join(base, "state");
await withDotEnvFixture(async ({ cwdDir, stateDir }) => {
await writeEnvFile(path.join(stateDir, ".env"), "FOO=from-global\nBAR=1\n");
await writeEnvFile(path.join(cwdDir, ".env"), "FOO=from-cwd\n");
process.env.OPENCLAW_STATE_DIR = stateDir;
process.chdir(cwdDir);
delete process.env.FOO;
delete process.env.BAR;
await writeEnvFile(path.join(stateDir, ".env"), "FOO=from-global\nBAR=1\n");
await writeEnvFile(path.join(cwdDir, ".env"), "FOO=from-cwd\n");
loadDotEnv({ quiet: true });
process.chdir(cwdDir);
delete process.env.FOO;
delete process.env.BAR;
loadDotEnv({ quiet: true });
expect(process.env.FOO).toBe("from-cwd");
expect(process.env.BAR).toBe("1");
expect(process.env.FOO).toBe("from-cwd");
expect(process.env.BAR).toBe("1");
});
});
});
it("does not override an already-set env var from the shell", async () => {
await withIsolatedEnvAndCwd(async () => {
const base = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-dotenv-test-"));
const cwdDir = path.join(base, "cwd");
const stateDir = path.join(base, "state");
await withDotEnvFixture(async ({ cwdDir, stateDir }) => {
process.env.FOO = "from-shell";
process.env.OPENCLAW_STATE_DIR = stateDir;
process.env.FOO = "from-shell";
await writeEnvFile(path.join(stateDir, ".env"), "FOO=from-global\n");
await writeEnvFile(path.join(cwdDir, ".env"), "FOO=from-cwd\n");
await writeEnvFile(path.join(stateDir, ".env"), "FOO=from-global\n");
await writeEnvFile(path.join(cwdDir, ".env"), "FOO=from-cwd\n");
process.chdir(cwdDir);
process.chdir(cwdDir);
loadDotEnv({ quiet: true });
loadDotEnv({ quiet: true });
expect(process.env.FOO).toBe("from-shell");
});
});
});
expect(process.env.FOO).toBe("from-shell");
it("loads fallback state .env when CWD .env is missing", async () => {
await withIsolatedEnvAndCwd(async () => {
await withDotEnvFixture(async ({ cwdDir, stateDir }) => {
await writeEnvFile(path.join(stateDir, ".env"), "FOO=from-global\n");
process.chdir(cwdDir);
delete process.env.FOO;
loadDotEnv({ quiet: true });
expect(process.env.FOO).toBe("from-global");
});
});
});
});