mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:51:36 +00:00
refactor(test): use env snapshots in setup hooks
This commit is contained in:
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { captureEnv } from "../test-utils/env.js";
|
||||||
|
|
||||||
const note = vi.hoisted(() => vi.fn());
|
const note = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
@@ -13,21 +14,17 @@ import { noteSessionLockHealth } from "./doctor-session-locks.js";
|
|||||||
|
|
||||||
describe("noteSessionLockHealth", () => {
|
describe("noteSessionLockHealth", () => {
|
||||||
let root: string;
|
let root: string;
|
||||||
let prevStateDir: string | undefined;
|
let envSnapshot: ReturnType<typeof captureEnv>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
note.mockReset();
|
note.mockReset();
|
||||||
prevStateDir = process.env.OPENCLAW_STATE_DIR;
|
envSnapshot = captureEnv(["OPENCLAW_STATE_DIR"]);
|
||||||
root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-doctor-locks-"));
|
root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-doctor-locks-"));
|
||||||
process.env.OPENCLAW_STATE_DIR = root;
|
process.env.OPENCLAW_STATE_DIR = root;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (prevStateDir === undefined) {
|
envSnapshot.restore();
|
||||||
delete process.env.OPENCLAW_STATE_DIR;
|
|
||||||
} else {
|
|
||||||
process.env.OPENCLAW_STATE_DIR = prevStateDir;
|
|
||||||
}
|
|
||||||
await fs.rm(root, { recursive: true, force: true });
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import { captureEnv } from "../test-utils/env.js";
|
||||||
import {
|
import {
|
||||||
consumeRestartSentinel,
|
consumeRestartSentinel,
|
||||||
formatRestartSentinelMessage,
|
formatRestartSentinelMessage,
|
||||||
@@ -12,21 +13,17 @@ import {
|
|||||||
} from "./restart-sentinel.js";
|
} from "./restart-sentinel.js";
|
||||||
|
|
||||||
describe("restart sentinel", () => {
|
describe("restart sentinel", () => {
|
||||||
let prevStateDir: string | undefined;
|
let envSnapshot: ReturnType<typeof captureEnv>;
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
prevStateDir = process.env.OPENCLAW_STATE_DIR;
|
envSnapshot = captureEnv(["OPENCLAW_STATE_DIR"]);
|
||||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sentinel-"));
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sentinel-"));
|
||||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
process.env.OPENCLAW_STATE_DIR = tempDir;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (prevStateDir) {
|
envSnapshot.restore();
|
||||||
process.env.OPENCLAW_STATE_DIR = prevStateDir;
|
|
||||||
} else {
|
|
||||||
delete process.env.OPENCLAW_STATE_DIR;
|
|
||||||
}
|
|
||||||
await fs.rm(tempDir, { recursive: true, force: true });
|
await fs.rm(tempDir, { recursive: true, force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { captureEnv } from "../test-utils/env.js";
|
||||||
import type { UpdateCheckResult } from "./update-check.js";
|
import type { UpdateCheckResult } from "./update-check.js";
|
||||||
|
|
||||||
vi.mock("./openclaw-root.js", () => ({
|
vi.mock("./openclaw-root.js", () => ({
|
||||||
@@ -38,12 +39,7 @@ describe("update-startup", () => {
|
|||||||
let suiteRoot = "";
|
let suiteRoot = "";
|
||||||
let suiteCase = 0;
|
let suiteCase = 0;
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
let prevStateDir: string | undefined;
|
let envSnapshot: ReturnType<typeof captureEnv>;
|
||||||
let prevNodeEnv: string | undefined;
|
|
||||||
let prevVitest: string | undefined;
|
|
||||||
let hadStateDir = false;
|
|
||||||
let hadNodeEnv = false;
|
|
||||||
let hadVitest = false;
|
|
||||||
|
|
||||||
let resolveOpenClawPackageRoot: (typeof import("./openclaw-root.js"))["resolveOpenClawPackageRoot"];
|
let resolveOpenClawPackageRoot: (typeof import("./openclaw-root.js"))["resolveOpenClawPackageRoot"];
|
||||||
let checkUpdateStatus: (typeof import("./update-check.js"))["checkUpdateStatus"];
|
let checkUpdateStatus: (typeof import("./update-check.js"))["checkUpdateStatus"];
|
||||||
@@ -62,17 +58,12 @@ describe("update-startup", () => {
|
|||||||
vi.setSystemTime(new Date("2026-01-17T10:00:00Z"));
|
vi.setSystemTime(new Date("2026-01-17T10:00:00Z"));
|
||||||
tempDir = path.join(suiteRoot, `case-${++suiteCase}`);
|
tempDir = path.join(suiteRoot, `case-${++suiteCase}`);
|
||||||
await fs.mkdir(tempDir);
|
await fs.mkdir(tempDir);
|
||||||
hadStateDir = Object.prototype.hasOwnProperty.call(process.env, "OPENCLAW_STATE_DIR");
|
envSnapshot = captureEnv(["OPENCLAW_STATE_DIR", "NODE_ENV", "VITEST"]);
|
||||||
prevStateDir = process.env.OPENCLAW_STATE_DIR;
|
|
||||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
process.env.OPENCLAW_STATE_DIR = tempDir;
|
||||||
|
|
||||||
hadNodeEnv = Object.prototype.hasOwnProperty.call(process.env, "NODE_ENV");
|
|
||||||
prevNodeEnv = process.env.NODE_ENV;
|
|
||||||
process.env.NODE_ENV = "test";
|
process.env.NODE_ENV = "test";
|
||||||
|
|
||||||
// Ensure update checks don't short-circuit in test mode.
|
// Ensure update checks don't short-circuit in test mode.
|
||||||
hadVitest = Object.prototype.hasOwnProperty.call(process.env, "VITEST");
|
|
||||||
prevVitest = process.env.VITEST;
|
|
||||||
delete process.env.VITEST;
|
delete process.env.VITEST;
|
||||||
|
|
||||||
// Perf: load mocked modules once (after timers/env are set up).
|
// Perf: load mocked modules once (after timers/env are set up).
|
||||||
@@ -91,21 +82,7 @@ describe("update-startup", () => {
|
|||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
if (hadStateDir) {
|
envSnapshot.restore();
|
||||||
process.env.OPENCLAW_STATE_DIR = prevStateDir;
|
|
||||||
} else {
|
|
||||||
delete process.env.OPENCLAW_STATE_DIR;
|
|
||||||
}
|
|
||||||
if (hadNodeEnv) {
|
|
||||||
process.env.NODE_ENV = prevNodeEnv;
|
|
||||||
} else {
|
|
||||||
delete process.env.NODE_ENV;
|
|
||||||
}
|
|
||||||
if (hadVitest) {
|
|
||||||
process.env.VITEST = prevVitest;
|
|
||||||
} else {
|
|
||||||
delete process.env.VITEST;
|
|
||||||
}
|
|
||||||
resetUpdateAvailableStateForTest();
|
resetUpdateAvailableStateForTest();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,22 @@ describe("env test utils", () => {
|
|||||||
expect(process.env[key]).toBe(prev);
|
expect(process.env[key]).toBe(prev);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("withEnv can delete a key only inside callback", () => {
|
||||||
|
const key = "OPENCLAW_ENV_TEST_SYNC_DELETE";
|
||||||
|
const prev = process.env[key];
|
||||||
|
process.env[key] = "outer";
|
||||||
|
|
||||||
|
const seen = withEnv({ [key]: undefined }, () => process.env[key]);
|
||||||
|
|
||||||
|
expect(seen).toBeUndefined();
|
||||||
|
expect(process.env[key]).toBe("outer");
|
||||||
|
if (prev === undefined) {
|
||||||
|
delete process.env[key];
|
||||||
|
} else {
|
||||||
|
process.env[key] = prev;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("withEnvAsync restores values when callback throws", async () => {
|
it("withEnvAsync restores values when callback throws", async () => {
|
||||||
const key = "OPENCLAW_ENV_TEST_ASYNC";
|
const key = "OPENCLAW_ENV_TEST_ASYNC";
|
||||||
const prev = process.env[key];
|
const prev = process.env[key];
|
||||||
@@ -63,4 +79,20 @@ describe("env test utils", () => {
|
|||||||
expect(seen).toBe("inside");
|
expect(seen).toBe("inside");
|
||||||
expect(process.env[key]).toBe(prev);
|
expect(process.env[key]).toBe(prev);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("withEnvAsync can delete a key only inside callback", async () => {
|
||||||
|
const key = "OPENCLAW_ENV_TEST_ASYNC_DELETE";
|
||||||
|
const prev = process.env[key];
|
||||||
|
process.env[key] = "outer";
|
||||||
|
|
||||||
|
const seen = await withEnvAsync({ [key]: undefined }, async () => process.env[key]);
|
||||||
|
|
||||||
|
expect(seen).toBeUndefined();
|
||||||
|
expect(process.env[key]).toBe("outer");
|
||||||
|
if (prev === undefined) {
|
||||||
|
delete process.env[key];
|
||||||
|
} else {
|
||||||
|
process.env[key] = prev;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user