test.rules/rules/eslint/no-raw-file-write.eslint.rule.test.ts

test.rules/rules/eslint/no-raw-file-write.eslint.rule.test.ts is a file in Codebase Testing. 79 lines of code and 0 definitions.

import { describe, expect, it } from "vitest";
import { Linter } from "eslint";
import { absolutePath } from "@ssot/paths";
import { sep } from "node:path";
import wrapper from "@ssot/govlab/rules/eslint/no-raw-file-write.eslint.rule.ts";

const rule = wrapper.plugins["govlab-write"].rules["no-raw-file-write"];

const OWNER = "text.persistence.ts";
const WRITERS = ["writeCanonicalJson", "writeVerbatim"];

const linter = new Linter();
const config: Linter.Config[] = [
    {
        files: ["**/*.ts"],
        languageOptions: { ecmaVersion: 2025, sourceType: "module" },
        plugins: { t: { rules: { r: rule } } },
        rules: { "t/r": ["error", { modules: [OWNER], writers: WRITERS }] },
    },
];

const MEMBER = absolutePath("app.member").split(sep).join("/");
const SRC = `${MEMBER}/core/registries/probe.registry.ts`;
const OWNER_SRC = `${MEMBER}/core/persistence/${OWNER}`;

const idsFor = function idsFor(code: string, filename: string = SRC): string[] {
    return linter
        .verify(code, config, filename)
        .map((message) => message.messageId)
        .filter((id): id is string => typeof id === "string");
};

const EPHEMERAL_ROOT = `const dir = mkdtempSync(join(tmpdir(), "probe-"));\n`;

describe("the raw file-write primitive", () => {
    it("reports a raw write outside the owner module", () => {
        expect(idsFor(`writeFileSync("doc-arch/out.json", JSON.stringify(data, null, 4));`)).toContain("bypass");
    });

    it("reports a helper that forwards its caller's target and content", () => {
        const helper = `export const save = (target, content) => { writeFileSync(target, content); };`;
        expect(idsFor(helper)).toEqual(["bypass"]);
    });

    it("leaves a raw write to a self-governed member that names its own write gate", () => {
        const governed = `${absolutePath("app.coordination").split(sep).join("/")}/tools/core/runners/probe.runner.ts`;
        expect(idsFor(`writeFileSync(target, written, "utf8");`, governed)).toEqual([]);
    });

    it("stays quiet on the primitive inside the owner module", () => {
        expect(
            idsFor(`export const save = (target, content) => { writeFileSync(target, content); };`, OWNER_SRC),
        ).toEqual([]);
    });
});

describe("the owner's writers", () => {
    it("reports a formatter-supported output whose filename carries no generated marker", () => {
        expect(idsFor(`await writeCanonicalJson("doc-arch/out.json", data);`)).toEqual(["marker"]);
    });

    it("stays quiet on a marked output", () => {
        expect(idsFor(`await writeCanonicalJson("doc-arch/out.generated.json", data);`)).toEqual([]);
    });

    it("stays quiet on a call that no declared writer names", () => {
        expect(idsFor(`await writeGeneratedMarkdown("doc-arch/out.md", text);`)).toEqual([]);
    });
});

describe("ephemeral output", () => {
    it("stays quiet on a raw write whose target roots at an ephemeral directory", () => {
        expect(idsFor(`${EPHEMERAL_ROOT}writeFileSync(join(dir, "out.json"), JSON.stringify(data, null, 4));`)).toEqual(
            [],
        );
    });

    it("follows the ephemeral root through an intermediate directory binding", () => {
        const nested = `${EPHEMERAL_ROOT}const inner = join(dir, "nested");\n`;
        expect(idsFor(`${nested}writeFileSync(join(inner, "out.json"), body);`)).toEqual([]);
    });

    it("follows the ephemeral root through a later assignment", () => {
        const assigned = `let dir;\nsetup(() => { dir = mkdtempSync(join(tmpdir(), "probe-")); });\n`;
        expect(idsFor(`${assigned}writeFileSync(join(dir, "out.json"), body);`)).toEqual([]);
    });

    it("still reports a committed write in a file that also uses an ephemeral directory", () => {
        expect(idsFor(`${EPHEMERAL_ROOT}writeFileSync("doc-arch/out.json", body);`)).toContain("bypass");
    });
});

describe("serialized JSON", () => {
    it("reports an indent other than four", () => {
        expect(idsFor(`const text = JSON.stringify(data, null, 2);`)).toEqual(["spacing"]);
    });
});