auto-print / files / test / config.test.ts
config.test.ts
| 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 | }); |