# test.govlab/quality/core/loaders/source.loader.test.ts

> 64 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-govlab-quality-core-loaders-source-loader-test-ts
Source text: https://banes-lab.com/source/testing/test.govlab/quality/core/loaders/source.loader.test.ts.txt

Listed in [test.govlab/quality/core/loaders](https://banes-lab.com/api/source/testing/test.govlab/quality/core/loaders.md), after [test.govlab/quality/core/loaders/rule.loader.test.ts](https://banes-lab.com/source/testing/test.govlab/quality/core/loaders/rule.loader.test.ts.md) and before [test.govlab/quality/core/loaders/tool.loader.test.ts](https://banes-lab.com/source/testing/test.govlab/quality/core/loaders/tool.loader.test.ts.md).

## Contained in

- [test.govlab/quality/core/loaders](https://banes-lab.com/anatomy/testing/folder-testing-test-govlab-quality-core-loaders.md)

## Source

```typescript
import { afterAll, expect, test } from "vitest";
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
import {
    readFileSafe,
    readJsonField,
    readJsonFile,
    safeReaddir,
    safeStat,
    walkFiles,
} from "@govlab/quality/core/loaders/source.loader.ts";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { writeVerbatim } from "@govlab/canonical-write";

const dir = mkdtempSync(join(tmpdir(), "source-loader-"));
const JSON_FILE = join(dir, "manifest.json");
const TEXT_FILE = join(dir, "note.txt");
writeVerbatim(JSON_FILE, JSON.stringify({ name: "demo" }));
writeVerbatim(TEXT_FILE, "hello");

afterAll(() => {
    rmSync(dir, { force: true, recursive: true });
});

test("readFileSafe reads a file and answers empty text for a missing one", () => {
    expect(readFileSafe(TEXT_FILE)).toBe("hello");
    expect(readFileSafe(join(dir, "missing.txt"))).toBe("");
});

test("safeReaddir lists a folder and answers nothing for a missing one", () => {
    expect(
        safeReaddir(dir)
            .map((entry) => entry.name)
            .sort(),
    ).toStrictEqual(["manifest.json", "note.txt"]);
    expect(safeReaddir(join(dir, "absent"))).toStrictEqual([]);
});

test("readJsonField reads one key of a JSON file, answers undefined for a missing file and throws on malformed JSON", () => {
    expect(readJsonField(JSON_FILE, "name")).toBe("demo");
    expect(readJsonField(join(dir, "absent.json"), "name")).toBeUndefined();
    expect(() => readJsonField(TEXT_FILE, "name")).toThrow(SyntaxError);
});

test("safeStat reads an entry's stats and answers null for a missing one", () => {
    expect(safeStat(dir)?.isDirectory()).toBe(true);
    expect(safeStat(join(dir, "absent"))).toBeNull();
});

test("readJsonFile parses a JSON file and answers undefined for a missing one", () => {
    expect(readJsonFile(JSON_FILE)).toStrictEqual({ name: "demo" });
    expect(readJsonFile(join(dir, "absent.json"))).toBeUndefined();
});

test("walkFiles lists every file below a folder and skips an excluded folder", () => {
    const nested = join(dir, "walk");
    mkdirSync(join(nested, "kept"), { recursive: true });
    mkdirSync(join(nested, "skipped"), { recursive: true });
    writeVerbatim(join(nested, "kept", "a.txt"), "a");
    writeVerbatim(join(nested, "skipped", "b.txt"), "b");
    expect(walkFiles(nested, (full) => full.endsWith("skipped"))).toStrictEqual([join(nested, "kept", "a.txt")]);
});

test("walkFiles skips an excluded file as well as an excluded folder", () => {
    const nested = join(dir, "walk-files");
    mkdirSync(nested, { recursive: true });
    writeVerbatim(join(nested, "kept.ts"), "a");
    writeVerbatim(join(nested, "old.backup.js"), "b");
    expect(walkFiles(nested, (full) => full.endsWith(".backup.js"))).toStrictEqual([join(nested, "kept.ts")]);
});

test("readFileSafe rethrows a failure other than a missing file", () => {
    expect(() => readFileSafe(dir)).toThrow();
});
```
