115 lines
3.3 KiB
TypeScript
115 lines
3.3 KiB
TypeScript
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");
|
|
});
|
|
});
|