import { afterEach, beforeEach, describe, expect, test } from "vitest"; import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync, } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import { listDirectoryEntries } from "../../src/tui/utils/list-directory-entries.js"; describe("listDirectoryEntries", () => { let tempRoot: string; beforeEach(() => { tempRoot = mkdtempSync(path.join(tmpdir(), "xo-file-picker-")); }); afterEach(() => { if (existsSync(tempRoot)) { rmSync(tempRoot, { recursive: true, force: true }); } }); test("includes parent entry and sorts directories before files", () => { mkdirSync(path.join(tempRoot, "beta-dir")); mkdirSync(path.join(tempRoot, "alpha-dir")); writeFileSync(path.join(tempRoot, "zebra.json"), "{}"); writeFileSync(path.join(tempRoot, "apple.txt"), "x"); const childDir = path.join(tempRoot, "child"); mkdirSync(childDir); writeFileSync(path.join(childDir, "nested.json"), "{}"); const rootResult = listDirectoryEntries(tempRoot); expect(rootResult.error).toBeUndefined(); expect(rootResult.entries.map((entry) => entry.name)).toEqual([ "..", "alpha-dir", "beta-dir", "child", "apple.txt", "zebra.json", ]); const childResult = listDirectoryEntries(childDir); expect(childResult.entries[0]).toMatchObject({ name: "..", kind: "parent", absolutePath: tempRoot, }); expect(childResult.entries.slice(1).map((entry) => entry.name)).toEqual([ "nested.json", ]); }); test("filters files by extension when extensions are provided", () => { writeFileSync(path.join(tempRoot, "template.json"), "{}"); writeFileSync(path.join(tempRoot, "readme.md"), "# hi"); writeFileSync(path.join(tempRoot, "UPPER.JSON"), "{}"); const result = listDirectoryEntries(tempRoot, { extensions: ["json"] }); expect(result.error).toBeUndefined(); expect(result.entries.map((entry) => entry.name)).toEqual([ "..", "template.json", "UPPER.JSON", ]); }); test("shows all files when extensions are omitted", () => { writeFileSync(path.join(tempRoot, "a.json"), "{}"); writeFileSync(path.join(tempRoot, "b.txt"), "x"); const result = listDirectoryEntries(tempRoot); expect(result.entries.map((entry) => entry.name)).toEqual([ "..", "a.json", "b.txt", ]); }); test("omits parent entry at filesystem root", () => { const rootResult = listDirectoryEntries(path.parse(tempRoot).root); expect(rootResult.error).toBeUndefined(); expect(rootResult.entries.some((entry) => entry.kind === "parent")).toBe( false, ); }); test("returns error for missing directory without throwing", () => { const missingPath = path.join(tempRoot, "does-not-exist"); const result = listDirectoryEntries(missingPath); expect(result.entries).toEqual([]); expect(result.error).toContain("Directory does not exist"); }); test("returns error when path is a file", () => { const filePath = path.join(tempRoot, "file.txt"); writeFileSync(filePath, "hello"); const result = listDirectoryEntries(filePath); expect(result.entries).toEqual([]); expect(result.error).toContain("Not a directory"); }); });