import { describe, expect, test } from "bun:test"; import { extractHints, extractSection, slugify } from "../src/markdown"; describe("slugify", () => { test("follows GitHub's algorithm", () => { expect(slugify("Exercise 3.1 — `move`")).toBe("exercise-31--move"); expect(slugify("Why this module")).toBe("why-this-module"); expect(slugify("Rules as functions `State → State`")).toBe("rules-as-functions-state--state"); expect(slugify("**Bold** and [a link](http://x.y)")).toBe("bold-and-a-link"); }); }); const sample = `# Top intro ## First one ### Middle middle body \`\`\`sh # not a heading \`\`\` #### Deeper deep body ### Sibling sibling body ## Last end `; describe("extractSection", () => { test("returns only the middle section, including deeper headings", () => { const s = extractSection(sample, "middle"); expect(s).not.toBeNull(); expect(s!.startsWith("### Middle")).toBe(true); expect(s).toContain("# not a heading"); expect(s).toContain("deep body"); expect(s).not.toContain("sibling body"); expect(s).not.toContain("one"); }); test("returns null for an unknown anchor", () => { expect(extractSection(sample, "nope")).toBeNull(); }); test("a section runs to the end of file when nothing follows", () => { expect(extractSection(sample, "last")).toBe("## Last\n\nend"); }); }); describe("extractHints", () => { const md = `## Hints
Exercise 3.1 (move) — nudge Think about direction.
Exercise 3.1 (move) — stronger hint Add the delta.
Exercise 3.2 (inBounds) — nudge Other.
`; test("returns matching blocks in order with trimmed labels", () => { const h = extractHints(md, "Exercise 3.1 (move)"); expect(h.map((x) => x.label)).toEqual(["nudge", "stronger hint"]); expect(h[0]!.body).toBe("Think about direction."); }); test("returns [] when nothing matches", () => { expect(extractHints(md, "Exercise 9.9")).toEqual([]); }); });