auto-print / files / test / config.test.ts
config.test.ts
a6d0aed2 2026-10-24 Pavel Safronov | 1 | import assert from "node:assert/strict"; |
| 2 | import fs from "node:fs"; | |
| 3 | import os from "node:os"; | |
| 4 | import path from "node:path"; | |
| 5 | import { describe, it } from "node:test"; | |
| 6 | import { loadConfig } from "../src/config.ts"; | |
| 7 | ||
| 8 | function writeConfig(content: unknown): string { | |
| 9 | const dir = fs.mkdtempSync(path.join(os.tmpdir(), "auto-print-test-")); | |
| 10 | const file = path.join(dir, "books.json"); | |
| 11 | fs.writeFileSync(file, JSON.stringify(content)); | |
| 12 | return file; | |
| 13 | } | |
| 14 | ||
| 15 | describe("loadConfig", () => { | |
| 16 | it("resolves paths against the config file's folder and fills in the defaults", () => { | |
| 17 | const file = writeConfig({ | |
| 18 | outDir: "../out", | |
| 19 | defaults: { author: "A. Writer" }, | |
| 20 | books: [{ slug: "one", title: "One", source: "../one.md", cover: "covers/one.jpg", front: ["Dedication"] }], | |
| 21 | }); | |
| 22 | const dir = path.dirname(file); | |
| 23 | const config = loadConfig(file); | |
| 24 | assert.equal(config.outDir, path.resolve(dir, "../out")); | |
| 25 | assert.deepEqual(config.books[0], { | |
| 26 | slug: "one", | |
| 27 | title: "One", | |
| 28 | source: path.resolve(dir, "../one.md"), | |
| 29 | cover: path.join(dir, "covers/one.jpg"), | |
| 30 | front: ["Dedication"], | |
| 31 | back: [], | |
| 32 | author: "A. Writer", | |
| 33 | language: "en-US", | |
| 34 | section: "Writing", | |
| 35 | formats: ["epub", "docx", "pdf", "kpf"], | |
| 36 | chapterBreaks: false, | |
| 37 | }); | |
| 38 | }); | |
| 39 | ||
| 40 | it("puts the output next to the config file by default, and lets a book override the defaults", () => { | |
| 41 | const file = writeConfig({ | |
| 42 | defaults: { author: "A. Writer", formats: ["epub"] }, | |
| 43 | books: [{ slug: "one", title: "One", source: "one.md", author: "B. Writer", section: null, chapterBreaks: true }], | |
| 44 | }); | |
| 45 | const config = loadConfig(file); | |
| 46 | assert.equal(config.outDir, path.join(path.dirname(file), "auto-print-out")); | |
| 47 | assert.equal(config.books[0]?.author, "B. Writer"); | |
| 48 | assert.equal(config.books[0]?.section, null); | |
| 49 | assert.equal(config.books[0]?.chapterBreaks, true); | |
| 50 | assert.deepEqual(config.books[0]?.formats, ["epub"]); | |
| 51 | }); | |
| 52 | ||
| 53 | it("explains what is wrong", () => { | |
| 54 | const book = { slug: "one", title: "One", source: "one.md", author: "A" }; | |
| 55 | assert.throws(() => loadConfig("/no/such/books.json"), /Config file not found/); | |
| 56 | assert.throws(() => loadConfig(writeConfig({ books: [{ ...book, author: undefined }] })), /needs an "author"/); | |
| 57 | assert.throws(() => loadConfig(writeConfig({ books: [book, book] })), /slug "one" is used twice/); | |
| 58 | assert.throws(() => loadConfig(writeConfig({ books: [{ ...book, source: ["a.md"] }] })), /needs "slug", "title" and "source"/); | |
| 59 | assert.throws(() => loadConfig(writeConfig({ books: [{ ...book, formats: ["mobi"] }] })), /unknown format "mobi"/); | |
| 60 | assert.throws(() => loadConfig(writeConfig({ books: [{ ...book, front: "Dedication" }] })), /"front" must be a list/); | |
| 61 | }); | |
| 62 | }); |