diff --git a/src/infra/home-dir.test.ts b/src/infra/home-dir.test.ts index f1f721cd7fe..3096dd1b0b4 100644 --- a/src/infra/home-dir.test.ts +++ b/src/infra/home-dir.test.ts @@ -3,37 +3,64 @@ import { describe, expect, it } from "vitest"; import { expandHomePrefix, resolveEffectiveHomeDir, resolveRequiredHomeDir } from "./home-dir.js"; describe("resolveEffectiveHomeDir", () => { - it("prefers OPENCLAW_HOME over HOME and USERPROFILE", () => { - const env = { - OPENCLAW_HOME: "/srv/openclaw-home", - HOME: "/home/other", - USERPROFILE: "C:/Users/other", - } as NodeJS.ProcessEnv; - - expect(resolveEffectiveHomeDir(env, () => "/fallback")).toBe( - path.resolve("/srv/openclaw-home"), - ); + it.each([ + { + name: "prefers OPENCLAW_HOME over HOME and USERPROFILE", + env: { + OPENCLAW_HOME: " /srv/openclaw-home ", + HOME: "/home/other", + USERPROFILE: "C:/Users/other", + } as NodeJS.ProcessEnv, + homedir: () => "/fallback", + expected: "/srv/openclaw-home", + }, + { + name: "falls back to HOME", + env: { HOME: " /home/alice " } as NodeJS.ProcessEnv, + expected: "/home/alice", + }, + { + name: "falls back to USERPROFILE when HOME is blank", + env: { + HOME: " ", + USERPROFILE: " C:/Users/alice ", + } as NodeJS.ProcessEnv, + expected: "C:/Users/alice", + }, + { + name: "falls back to homedir when env values are blank", + env: { + OPENCLAW_HOME: " ", + HOME: " ", + USERPROFILE: "\t", + } as NodeJS.ProcessEnv, + homedir: () => " /fallback ", + expected: "/fallback", + }, + ])("$name", ({ env, homedir, expected }) => { + expect(resolveEffectiveHomeDir(env, homedir)).toBe(path.resolve(expected)); }); - it("falls back to HOME then USERPROFILE then homedir", () => { - expect(resolveEffectiveHomeDir({ HOME: "/home/alice" } as NodeJS.ProcessEnv)).toBe( - path.resolve("/home/alice"), - ); - expect(resolveEffectiveHomeDir({ USERPROFILE: "C:/Users/alice" } as NodeJS.ProcessEnv)).toBe( - path.resolve("C:/Users/alice"), - ); - expect(resolveEffectiveHomeDir({} as NodeJS.ProcessEnv, () => "/fallback")).toBe( - path.resolve("/fallback"), - ); - }); - - it("expands OPENCLAW_HOME when set to ~", () => { - const env = { - OPENCLAW_HOME: "~/svc", - HOME: "/home/alice", - } as NodeJS.ProcessEnv; - - expect(resolveEffectiveHomeDir(env)).toBe(path.resolve("/home/alice/svc")); + it.each([ + { + name: "expands ~/ using HOME", + env: { + OPENCLAW_HOME: "~/svc", + HOME: "/home/alice", + } as NodeJS.ProcessEnv, + expected: "/home/alice/svc", + }, + { + name: "expands ~\\\\ using USERPROFILE", + env: { + OPENCLAW_HOME: "~\\svc", + HOME: " ", + USERPROFILE: "C:/Users/alice", + } as NodeJS.ProcessEnv, + expected: "C:/Users/alice\\svc", + }, + ])("$name", ({ env, expected }) => { + expect(resolveEffectiveHomeDir(env)).toBe(path.resolve(expected)); }); }); @@ -64,14 +91,35 @@ describe("resolveRequiredHomeDir", () => { }); describe("expandHomePrefix", () => { - it("expands tilde using effective home", () => { - const value = expandHomePrefix("~/x", { - env: { OPENCLAW_HOME: "/srv/openclaw-home" } as NodeJS.ProcessEnv, - }); - expect(value).toBe(`${path.resolve("/srv/openclaw-home")}/x`); - }); - - it("keeps non-tilde values unchanged", () => { - expect(expandHomePrefix("/tmp/x")).toBe("/tmp/x"); + it.each([ + { + name: "expands ~/ using effective home", + input: "~/x", + opts: { + env: { OPENCLAW_HOME: "/srv/openclaw-home" } as NodeJS.ProcessEnv, + }, + expected: `${path.resolve("/srv/openclaw-home")}/x`, + }, + { + name: "expands exact ~ using explicit home", + input: "~", + opts: { home: " /srv/openclaw-home " }, + expected: path.resolve("/srv/openclaw-home"), + }, + { + name: "expands ~\\\\ using resolved env home", + input: "~\\x", + opts: { + env: { HOME: "/home/alice" } as NodeJS.ProcessEnv, + }, + expected: `${path.resolve("/home/alice")}\\x`, + }, + { + name: "keeps non-tilde values unchanged", + input: "/tmp/x", + expected: "/tmp/x", + }, + ])("$name", ({ input, opts, expected }) => { + expect(expandHomePrefix(input, opts)).toBe(expected); }); });