test.build/core/persistence/folder.persistence.test.ts

test.build/core/persistence/folder.persistence.test.ts is a file in Codebase Testing. 42 lines of code and 0 definitions.

import { describe, expect, it } from "vitest";
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync } from "node:fs";
import { join } from "node:path";
import { syncFolder } from "@banes-lab/build-scripts/core/persistence/folder.persistence.ts";
import { tmpdir } from "node:os";
import { writeVerbatim } from "@govlab/canonical-write";

const CHANGED = "changed.txt";

const tree = function tree(): { from: string; root: string; to: string } {
    const root = mkdtempSync(join(tmpdir(), "folder-sync-"));
    const from = join(root, "from");
    const to = join(root, "to");
    mkdirSync(join(from, "nested"), { recursive: true });
    mkdirSync(join(to, "gone"), { recursive: true });
    writeVerbatim(join(from, "nested", "kept.txt"), "kept");
    writeVerbatim(join(from, CHANGED), "new");
    writeVerbatim(join(from, "skipped.txt"), "skipped");
    writeVerbatim(join(to, CHANGED), "old");
    writeVerbatim(join(to, "gone", "stale.txt"), "stale");
    return { from, root, to };
};

describe("syncFolder", () => {
    it("copies new and changed files, removes stale ones and their emptied folders, and honors the admit filter", async () => {
        const { from, root, to } = tree();
        const sync = await syncFolder(from, to, (path) => !path.endsWith("skipped.txt"));
        expect(sync).toStrictEqual({ copied: 2, removed: 1 });
        expect(readFileSync(join(to, "nested", "kept.txt"), "utf8")).toBe("kept");
        expect(readFileSync(join(to, CHANGED), "utf8")).toBe("new");
        expect(existsSync(join(to, "skipped.txt"))).toBe(false);
        expect(existsSync(join(to, "gone"))).toBe(false);
        rmSync(root, { force: true, recursive: true });
    });

    it("leaves an unchanged file untouched on a second run", async () => {
        const { from, root, to } = tree();
        await syncFolder(from, to);
        const before = statSync(join(to, CHANGED)).mtimeMs;
        const again = await syncFolder(from, to);
        const after = statSync(join(to, CHANGED)).mtimeMs;
        rmSync(root, { force: true, recursive: true });
        expect(again).toStrictEqual({ copied: 0, removed: 0 });
        expect(after).toBe(before);
    });
});