mc-publish/tests/unit/utils/io/file-info.spec.ts
2024-01-15 15:12:09 +03:00

320 lines
10 KiB
TypeScript

import { statSync } from "node:fs";
import mockFs from "mock-fs";
import { zipContent } from "../../../utils/zip-utils";
import {
FileInfo,
fileEquals,
findFiles,
findFilesSync,
readAllText,
readAllTextSync,
readAllZippedText,
readFile,
readFileSync,
readZippedFile,
} from "@/utils/io/file-info";
beforeEach(async () => {
mockFs({
"path/to": {
"test.txt": "test",
"test.json": JSON.stringify({ foo: 42 }),
"test.zip": await zipContent("test", "test.txt"),
},
});
});
afterEach(() => {
mockFs.restore();
});
describe("FileInfo", () => {
describe("constructor", () => {
test("constructs a new instance with the given path", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.path).toBe("path/to/test.txt");
});
});
describe("of", () => {
test("constructs a new instance from the given path", () => {
const info = FileInfo.of("test.txt");
expect(info).toBeInstanceOf(FileInfo);
expect(info.path).toBe("test.txt");
});
test("returns the same instance for a FileInfo object", () => {
const info1 = new FileInfo("test.txt");
const info2 = FileInfo.of(info1);
expect(info2).toBe(info1);
});
});
describe("name", () => {
test("returns the file name", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.name).toBe("test.txt");
});
});
describe("directoryName", () => {
test("returns the directory name of the file", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.directoryName).toBe("path/to");
});
});
describe("path", () => {
test("returns the file path", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.path).toBe("path/to/test.txt");
});
});
describe("exists", () => {
test("returns true for existing files", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.exists).toBe(true);
});
test("returns false for non-existing files", () => {
const info = new FileInfo("path/to/not-test.txt");
expect(info.exists).toBe(false);
});
});
describe("size", () => {
test("returns the file size", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.size).toBe(statSync("path/to/test.txt").size);
});
test("throws if the file does not exist", () => {
const info = new FileInfo("path/to/not-test.txt");
expect(() => info.size).toThrow();
});
});
describe("stream", () => {
test("creates a readable stream", () => new Promise(resolve => {
const info = new FileInfo("path/to/test.txt");
const stream = info.stream();
expect(stream).toBeDefined();
expect(stream.readable).toBe(true);
stream.close(resolve);
}));
});
describe("buffer", () => {
test("returns a promise that resolves to a buffer", async () => {
const info = new FileInfo("path/to/test.txt");
const buffer = await info.buffer();
expect(Buffer.isBuffer(buffer)).toBe(true);
expect(buffer.toString()).toBe("test");
});
test("throws if the file does not exist", async () => {
const info = new FileInfo("path/to/not-test.txt");
await expect(info.buffer()).rejects.toThrow();
});
});
describe("text", () => {
test("returns a promise that resolves to a string", async () => {
const info = new FileInfo("path/to/test.txt");
const text = await info.text();
expect(text).toBe("test");
});
test("throws if the file does not exist", async () => {
const info = new FileInfo("path/to/not-test.txt");
await expect(info.text()).rejects.toThrow();
});
});
describe("json", () => {
test("returns a promise that resolves to a json object", async () => {
const info = new FileInfo("path/to/test.json");
const json = await info.json();
expect(json).toEqual({ foo: 42 });
});
test("throws if the file does not exist", async () => {
const info = new FileInfo("path/to/not-test.json");
await expect(info.json()).rejects.toThrow();
});
});
describe("toString", () => {
test("returns the file path", () => {
const info = new FileInfo("path/to/test.txt");
expect(info.toString()).toBe("path/to/test.txt");
});
});
test("should be converted to JSON as a file path string", () => {
const info = new FileInfo("path/to/test.txt");
expect(JSON.stringify(info)).toBe("\"path/to/test.txt\"");
});
});
describe("fileEquals", () => {
test("returns true for equal file paths", () => {
expect(fileEquals("path/to/test.txt", "path/to/test.txt")).toBe(true);
expect(fileEquals(FileInfo.of("path/to/test.txt"), "path/to/test.txt")).toBe(true);
expect(fileEquals("path/to/test.txt", FileInfo.of("path/to/test.txt"))).toBe(true);
expect(fileEquals(FileInfo.of("path/to/test.txt"), FileInfo.of("path/to/test.txt"))).toBe(true);
});
test("returns false for different file paths", () => {
expect(fileEquals("path/to/test.txt", "path/to/not-test.txt")).toBe(false);
expect(fileEquals(FileInfo.of("path/to/test.txt"), "path/to/not-test.txt")).toBe(false);
expect(fileEquals("path/to/test.txt", FileInfo.of("path/to/not-test.txt"))).toBe(false);
expect(fileEquals(FileInfo.of("path/to/test.txt"), FileInfo.of("path/to/not-test.txt"))).toBe(false);
});
});
describe("findFiles", () => {
test("returns matching files for given pattern", async () => {
const files = await findFiles("path/to/test.*");
const paths = files.map(file => file.path);
expect(paths).toEqual(expect.arrayContaining([
"path/to/test.txt",
"path/to/test.json",
]));
});
test("respects the order of the given patterns", async () => {
const paths = ["path/to/test.json", "path/to/test.txt"];
const variants = [paths, [...paths].reverse()];
for (const variant of variants) {
const files = await findFiles(variant);
expect(files.map(x => x.path)).toEqual(variant);
}
});
});
describe("findFilesSync", () => {
test("returns matching files for given pattern", () => {
const files = findFilesSync("path/to/test.*");
const paths = files.map(file => file.path);
expect(paths).toEqual(expect.arrayContaining([
"path/to/test.txt",
"path/to/test.json",
]));
});
test("respects the order of the given patterns", () => {
const paths = ["path/to/test.json", "path/to/test.txt"];
const variants = [paths, [...paths].reverse()];
for (const variant of variants) {
const files = findFilesSync(variant);
expect(files.map(x => x.path)).toEqual(variant);
}
});
});
describe("readFile", () => {
test("reads the contents of the first matching file", async () => {
const content = await readFile("path/to/*.txt");
expect(Buffer.isBuffer(content)).toBe(true);
expect(content.toString()).toEqual("test");
});
test("throws if no files were found", async () => {
await expect(readFile("path/from/*.txt")).rejects.toThrow(/path\/from\/\*\.txt/);
});
});
describe("readFileSync", () => {
test("reads the contents of the first matching file", () => {
const content = readFileSync("path/to/*.txt");
expect(Buffer.isBuffer(content)).toBe(true);
expect(content.toString()).toEqual("test");
});
test("throws if no files were found", () => {
expect(() => readFileSync("path/from/*.txt")).toThrow(/path\/from\/\*\.txt/);
});
});
describe("readAllText", () => {
test("reads the contents of the first matching file as text", async () => {
const content = await readAllText("path/to/*.txt");
expect(content).toEqual("test");
});
test("throws if no files were found", async () => {
await expect(readAllText("path/from/*.txt")).rejects.toThrow(/path\/from\/\*\.txt/);
});
});
describe("readAllTextSync", () => {
test("reads the contents of the first matching file as text", () => {
const content = readAllTextSync("path/to/*.txt");
expect(content).toEqual("test");
});
test("throws if no files were found", () => {
expect(() => readAllTextSync("path/from/*.txt")).toThrow(/path\/from\/\*\.txt/);
});
});
describe("readZippedFile", () => {
test("reads the contents of the first matching file", async () => {
const content = await readZippedFile("path/to/*.zip", "test.txt");
expect(Buffer.isBuffer(content)).toBe(true);
expect(content.toString()).toEqual("test");
});
test("throws if no files were found", async () => {
await expect(readZippedFile("path/from/*.zip", "")).rejects.toThrow(/path\/from\/\*\.zip/);
});
test("throws if the entry does not exist within the zip", async () => {
await expect(readZippedFile("path/to/test.zip", "not-test.txt")).rejects.toThrow(/Entry not found/);
});
});
describe("readAllZippedText", () => {
test("reads the contents of the first matching file", async () => {
const content = await readAllZippedText("path/to/*.zip", "test.txt");
expect(content).toEqual("test");
});
test("throws if no files were found", async () => {
await expect(readAllZippedText("path/from/*.zip", "")).rejects.toThrow(/path\/from\/\*\.zip/);
});
test("throws if the entry does not exist within the zip", async () => {
await expect(readAllZippedText("path/to/test.zip", "not-test.txt")).rejects.toThrow(/Entry not found/);
});
});