import { describe, expect, test } from "bun:test";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { ContentRegistry } from "../core/content.ts";
import { resolveConfig } from "../core/config.ts";
import {
markdownLoader,
parseFrontmatter,
renderMarkdown,
} from "../views/markdown.ts";
/**
* Tests of the markdown loader and of the content collections.
*/
describe("markdown", () => {
test("parses the frontmatter", () => {
const { frontmatter, body } = parseFrontmatter(
"---\ntitle: Hello\ndraft: false\ncount: 3\ntags:\n - a\n - b\n---\n\nBody",
);
expect(frontmatter.title).toBe("Hello");
expect(frontmatter.draft).toBe(false);
expect(frontmatter.count).toBe(3);
expect(frontmatter.tags).toEqual(["a", "b"]);
expect(body.trim()).toBe("Body");
});
test("renders the inline markup", () => {
expect(renderMarkdown("**bold** and *italic*")).toContain(
"bold",
);
expect(renderMarkdown("`code`")).toContain("code");
expect(renderMarkdown("[link](/x)")).toContain('link');
});
test("renders the blocks", () => {
const html = renderMarkdown(
"# Title\n\nA paragraph.\n\n- one\n- two\n\n> quoted\n\n```js\nconst a = 1;\n```",
);
expect(html).toContain("
A paragraph.
"); expect(html).toContain(""); expect(html).toContain(''); }); }); describe("content collections", () => { test("loads the entries of a collection", async () => { const dir = await mkdtemp(join(tmpdir(), "muddle-content-")); await writeFile( join(dir, "first.md"), "---\ntitle: First\n---\n\nHello **world**", "utf8", ); await writeFile( join(dir, "second.md"), "---\ntitle: Second\n---\n\nSecond note", "utf8", ); const registry = new ContentRegistry( resolveConfig({ root: dir, collections: [ { name: "notes", dir: ".", loader: markdownLoader(), schema: { required: ["title"] }, }, ], }), ); await registry.load(); const entries = registry.entries("notes"); expect(entries).toHaveLength(2); expect(entries[0]?.id).toBe("first"); expect(entries[0]?.frontmatter.title).toBe("First"); expect(entries[0]?.body).toContain("world"); expect(registry.get("notes", "second")?.frontmatter.title).toBe("Second"); await rm(dir, { recursive: true, force: true }); }); test("rejects an invalid frontmatter", async () => { const dir = await mkdtemp(join(tmpdir(), "muddle-content-")); await writeFile( join(dir, "broken.md"), "---\ndraft: true\n---\n\nBody", "utf8", ); const registry = new ContentRegistry( resolveConfig({ root: dir, collections: [ { name: "notes", dir: ".", loader: markdownLoader(), schema: { required: ["title"] }, }, ], }), ); await expect(registry.load()).rejects.toThrow("title is required"); await rm(dir, { recursive: true, force: true }); }); });