import { afterEach, beforeEach, describe, expect, test, vi } from "@effect/vitest";import { join } from "node:path"; import { xdgDataHome } from "./index"; const ENV_KEYS = ["XDG_DATA_HOME", "LOCALAPPDATA", "APPDATA", "USERPROFILE", "HOME"] as const; function stubPlatform(platform: NodeJS.Platform) { Object.defineProperty(process, "platform", { value: platform, configurable: true });} function clearEnv() { for (const key of ENV_KEYS) vi.stubEnv(key, "");} describe("xdgDataHome", () => { const originalPlatform = process.platform; beforeEach(() => { clearEnv(); }); afterEach(() => { vi.unstubAllEnvs(); Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true, }); }); test("prefers XDG_DATA_HOME when set on any platform", () => { vi.stubEnv("XDG_DATA_HOME", "/custom/xdg"); stubPlatform("linux"); expect(xdgDataHome()).toBe("/custom/xdg"); stubPlatform("win32"); expect(xdgDataHome()).toBe("/custom/xdg"); stubPlatform("darwin"); expect(xdgDataHome()).toBe("/custom/xdg"); }); test("ignores empty / whitespace-only XDG_DATA_HOME", () => { vi.stubEnv("XDG_DATA_HOME", " "); vi.stubEnv("HOME", "/home/user"); stubPlatform("linux"); expect(xdgDataHome()).toBe(join("/home/user", ".local", "share")); }); test("trims whitespace around XDG_DATA_HOME", () => { vi.stubEnv("XDG_DATA_HOME", " /trimmed/xdg "); stubPlatform("linux"); expect(xdgDataHome()).toBe("/trimmed/xdg"); }); describe("on posix", () => { beforeEach(() => stubPlatform("linux")); test("falls back to $HOME/.local/share", () => { vi.stubEnv("HOME", "/home/user"); expect(xdgDataHome()).toBe(join("/home/user", ".local", "share")); }); test("defaults to ~/.local/share when HOME is unset", () => { expect(xdgDataHome()).toBe(join("~", ".local", "share")); }); }); describe("on windows", () => { beforeEach(() => stubPlatform("win32")); test("prefers LOCALAPPDATA", () => { vi.stubEnv("LOCALAPPDATA", "C:\\Users\\user\\AppData\\Local"); vi.stubEnv("APPDATA", "C:\\Users\\user\\AppData\\Roaming"); vi.stubEnv("USERPROFILE", "C:\\Users\\user"); expect(xdgDataHome()).toBe("C:\\Users\\user\\AppData\\Local"); }); test("falls back to APPDATA when LOCALAPPDATA is unset", () => { vi.stubEnv("APPDATA", "C:\\Users\\user\\AppData\\Roaming"); vi.stubEnv("USERPROFILE", "C:\\Users\\user"); expect(xdgDataHome()).toBe("C:\\Users\\user\\AppData\\Roaming"); }); test("falls back to USERPROFILE\\AppData\\Local when both are unset", () => { vi.stubEnv("USERPROFILE", "C:\\Users\\user"); // The helper uses node:path.join which normalizes separators to the // runtime platform, so on a POSIX test runner we can't assert the // exact separator — just that all three segments are present. const result = xdgDataHome(); expect(result).toContain("C:"); expect(result).toContain("Users"); expect(result).toContain("user"); expect(result).toContain("AppData"); expect(result).toContain("Local"); }); test("defaults USERPROFILE to ~ when everything is unset", () => { const result = xdgDataHome(); expect(result.startsWith("~")).toBe(true); expect(result).toContain("AppData"); expect(result).toContain("Local"); }); });});
import { afterEach, beforeEach, describe, expect, test, vi } from "@effect/vitest";
import { join } from "node:path";
import { xdgDataHome } from "./index";
const ENV_KEYS = ["XDG_DATA_HOME", "LOCALAPPDATA", "APPDATA", "USERPROFILE", "HOME"] as const;
function stubPlatform(platform: NodeJS.Platform) {
Object.defineProperty(process, "platform", { value: platform, configurable: true });
}
function clearEnv() {
for (const key of ENV_KEYS) vi.stubEnv(key, "");
}
describe("xdgDataHome", () => {
const originalPlatform = process.platform;
beforeEach(() => {
clearEnv();
});
afterEach(() => {
vi.unstubAllEnvs();
Object.defineProperty(process, "platform", {
value: originalPlatform,
configurable: true,
});
});
test("prefers XDG_DATA_HOME when set on any platform", () => {
vi.stubEnv("XDG_DATA_HOME", "/custom/xdg");
stubPlatform("linux");
expect(xdgDataHome()).toBe("/custom/xdg");
stubPlatform("win32");
expect(xdgDataHome()).toBe("/custom/xdg");
stubPlatform("darwin");
expect(xdgDataHome()).toBe("/custom/xdg");
});
test("ignores empty / whitespace-only XDG_DATA_HOME", () => {
vi.stubEnv("XDG_DATA_HOME", " ");
vi.stubEnv("HOME", "/home/user");
stubPlatform("linux");
expect(xdgDataHome()).toBe(join("/home/user", ".local", "share"));
});
test("trims whitespace around XDG_DATA_HOME", () => {
vi.stubEnv("XDG_DATA_HOME", " /trimmed/xdg ");
stubPlatform("linux");
expect(xdgDataHome()).toBe("/trimmed/xdg");
});
describe("on posix", () => {
beforeEach(() => stubPlatform("linux"));
test("falls back to $HOME/.local/share", () => {
vi.stubEnv("HOME", "/home/user");
expect(xdgDataHome()).toBe(join("/home/user", ".local", "share"));
});
test("defaults to ~/.local/share when HOME is unset", () => {
expect(xdgDataHome()).toBe(join("~", ".local", "share"));
});
});
describe("on windows", () => {
beforeEach(() => stubPlatform("win32"));
test("prefers LOCALAPPDATA", () => {
vi.stubEnv("LOCALAPPDATA", "C:\\Users\\user\\AppData\\Local");
vi.stubEnv("APPDATA", "C:\\Users\\user\\AppData\\Roaming");
vi.stubEnv("USERPROFILE", "C:\\Users\\user");
expect(xdgDataHome()).toBe("C:\\Users\\user\\AppData\\Local");
});
test("falls back to APPDATA when LOCALAPPDATA is unset", () => {
vi.stubEnv("APPDATA", "C:\\Users\\user\\AppData\\Roaming");
vi.stubEnv("USERPROFILE", "C:\\Users\\user");
expect(xdgDataHome()).toBe("C:\\Users\\user\\AppData\\Roaming");
});
test("falls back to USERPROFILE\\AppData\\Local when both are unset", () => {
vi.stubEnv("USERPROFILE", "C:\\Users\\user");
// The helper uses node:path.join which normalizes separators to the
// runtime platform, so on a POSIX test runner we can't assert the
// exact separator — just that all three segments are present.
const result = xdgDataHome();
expect(result).toContain("C:");
expect(result).toContain("Users");
expect(result).toContain("user");
expect(result).toContain("AppData");
expect(result).toContain("Local");
});
test("defaults USERPROFILE to ~ when everything is unset", () => {
const result = xdgDataHome();
expect(result.startsWith("~")).toBe(true);
expect(result).toContain("AppData");
expect(result).toContain("Local");
});
});
});