import { join } from "node:path"; import { afterEach, describe, expect, test, vi } from "vitest"; const mockHomedir = vi.hoisted(() => vi.fn(() => "/home/testuser")); vi.mock("node:os", () => ({ homedir: mockHomedir, default: { homedir: mockHomedir }, })); import { expandHomePath } from "../src/expand-home"; const FAKE_HOME = "/home/testuser"; afterEach(() => { mockHomedir.mockClear(); }); describe("expandHomePath", () => { describe("~ expansion", () => { test("bare ~ expands to homedir()", () => { expect(expandHomePath("~")).toBe(FAKE_HOME); }); test("~/path expands to homedir()/path", () => { expect(expandHomePath("~/dev/project")).toBe( join(FAKE_HOME, "dev/project"), ); }); test("~/path/* expands to homedir()/path/*", () => { expect(expandHomePath("~/dev/*")).toBe(join(FAKE_HOME, "dev/*")); }); test("~\\ (Windows separator) expands to homedir() + rest", () => { expect(expandHomePath("~\\dev\\project")).toBe( join(FAKE_HOME, "dev\\project"), ); }); test("~username (no separator) is not expanded (no-op)", () => { expect(expandHomePath("~username")).toBe("~username"); }); }); describe("$HOME expansion", () => { test("bare $HOME expands to homedir()", () => { expect(expandHomePath("$HOME")).toBe(FAKE_HOME); }); test("$HOME/path expands to homedir()/path", () => { expect(expandHomePath("$HOME/dev/project")).toBe( join(FAKE_HOME, "dev/project"), ); }); test("$HOME/path/* expands to homedir()/path/*", () => { expect(expandHomePath("$HOME/dev/*")).toBe(join(FAKE_HOME, "dev/*")); }); test("$HOME\\ (Windows separator) expands to homedir() + rest", () => { expect(expandHomePath("$HOME\\dev\\project")).toBe( join(FAKE_HOME, "dev\\project"), ); }); test("$HOMEDIR (no separator) is not expanded (no-op)", () => { expect(expandHomePath("$HOMEDIR")).toBe("$HOMEDIR"); }); }); describe("no-op patterns", () => { test("absolute path is unchanged", () => { expect(expandHomePath("/usr/local/bin")).toBe("/usr/local/bin"); }); test("relative path is unchanged", () => { expect(expandHomePath("dev/project")).toBe("dev/project"); }); test("glob-only pattern is unchanged", () => { expect(expandHomePath("*")).toBe("*"); }); test("empty string is unchanged", () => { expect(expandHomePath("")).toBe(""); }); test("bash command pattern starting with a word is unchanged", () => { expect(expandHomePath("git push *")).toBe("git push *"); }); }); });