import { readFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { test } from "node:test"; import assert from "node:assert/strict"; import { renderSettingsExample, renderSettingsMarkdown } from "./settingsDocs"; // Run with: node_modules/.bin/tsx --test common/lib/settingsDocs.test.ts // // settings.json.example and SETTINGS.md are GENERATED from the settings schema // (common/bin/settings-example.ts). This is what keeps them generated: a hand // edit to either file, or a schema change without a regenerate, fails here. const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", ".."); for (const [name, render] of [ ["settings.json.example", renderSettingsExample], ["SETTINGS.md", renderSettingsMarkdown], ] as const) { test(`${name} is what the schema generates`, () => { const committed = readFileSync(path.join(REPO, name), "utf8"); assert.equal( committed, render(), `${name} is stale: run pnpm --filter yt-dlp-transcript-common exec tsx bin/settings-example.ts`, ); }); } test("the example parses back to the defaults", async () => { const { siteSettingsSchema, defaultSiteSettings } = await import("./settingsSchema"); const parsed = siteSettingsSchema.parse(JSON.parse(renderSettingsExample())); assert.deepEqual(parsed, defaultSiteSettings()); }); // EVERY FIELD, NOT ONLY THE 32 TOP-LEVEL ONES. The *_FIELD_DOCS records are // complete by type (FieldDocs requires one entry per key); these two check // the wiring — that every object-valued block has a key table, and that a // block's table names every key its default actually carries. test("every object-valued block has a nested key table", async () => { const { defaultSiteSettings } = await import("./settingsSchema"); const { blockTables } = await import("./settingsDocs"); const d = defaultSiteSettings() as Record; const tables = blockTables(defaultSiteSettings()) as Record; for (const [key, value] of Object.entries(d)) { if (value === null || typeof value !== "object") continue; assert.ok((tables[key]?.length ?? 0) > 0, `${key} has no key table`); } }); test("a block table documents every key its default carries", async () => { const { defaultSiteSettings } = await import("./settingsSchema"); const { blockTables } = await import("./settingsDocs"); const d = defaultSiteSettings() as Record; for (const [key, list] of Object.entries(blockTables(defaultSiteSettings()))) { const first = list?.[0]; if (!first?.defaults || key === "autoQueue") continue; const value = d[key] as Record; for (const field of Object.keys(value)) { assert.ok(field in first.docs, `${key}.${field} is undocumented`); } } });