import { expect } from "@std/expect"; import { describe, test } from "@std/testing/bdd"; import { convertMdxToMarkdown } from "./convert"; import { getHomePage, getProductPages } from "./utils"; describe("convertMdxToMarkdown", () => { test("serializes Details regardless of the props that follow summary", () => { const markdown = convertMdxToMarkdown({ metadata: { title: "t" }, content: '
\n\nAnswer.\n\n
', slug: "t", href: "/t", } as Parameters[0]); expect(markdown).toContain("Q?"); expect(markdown).toContain("Answer."); }); test("the home page keeps every FAQ entry in its markdown representation", () => { const home = getHomePage(); const markdown = convertMdxToMarkdown(home); for (const entry of home.metadata.faq ?? []) { expect(markdown).toContain(`${entry.question}`); } }); test("unwraps Subtle and Actions instead of dropping their copy", () => { const markdown = convert( '\n A\n\n\n

\nPaid plans from $30/mo.\n

', ); expect(markdown).toContain("[A](/a)"); expect(markdown).toContain("Paid plans from $30/mo."); expect(markdown).not.toContain("<"); }); test("a self-closing component with props does not swallow what follows", () => { const markdown = convert( '\n\n## Kept\n\n09:41', ); expect(markdown).toContain("## Kept"); expect(markdown).not.toContain("Demo"); }); test("keeps SrOnly copy and drops the tag", () => { const markdown = convert( '\n\n\n\nThe alert as it lands in Slack.\n\n', ); expect(markdown).toContain("The alert as it lands in Slack."); expect(markdown).not.toContain("<"); }); test("renders LogoCloud and Quote from the customers data", () => { const markdown = convert('\n\n'); expect(markdown).toContain("[Cal.com](https://status.cal.com)"); expect(markdown).toContain("[Twenty](/customers/twenty)"); expect(markdown).toContain( "> “Open-source CRM needs an open-source status page.", ); expect(markdown).toContain("Félix Malfait, Co-founder @twentycrm"); }); test("the main pages leave no JSX behind", () => { for (const page of [getHomePage(), ...getProductPages()]) { const markdown = convertMdxToMarkdown(page); expect(markdown).not.toMatch(/<\/?(?!(details|summary)>)[A-Za-z]/); } }); test("a demo removed after a list leaves one blank line, not two", () => { const markdown = convert( '
\n\n- item\n\n\n\n\n\n\nText\n\n\n\n
', ); expect(markdown).toContain("- item\n\nText"); }); test("drops br and the blank lines around it", () => { const markdown = convert("a\n\n

\n\n
\n\nb"); expect(markdown).toContain("a\n\nb"); }); test("an inline br keeps the word boundary", () => { expect(convert("Before
After")).toContain("Before\nAfter"); }); test("the main pages have no runs of blank lines", () => { for (const page of [getHomePage(), ...getProductPages()]) { expect(convertMdxToMarkdown(page)).not.toMatch(/\n[ \t]*\n[ \t]*\n/); } }); test("drops Eyebrow labels", () => { const markdown = convert("09:41\n\n## Kept"); expect(markdown).toContain("## Kept"); expect(markdown).not.toContain("09:41"); }); test("every section heading of the main pages survives conversion", () => { for (const page of [getHomePage(), ...getProductPages()]) { const count = (text: string) => text.match(/^## /gm)?.length ?? 0; expect(count(convertMdxToMarkdown(page))).toBe(count(page.content)); } }); }); function convert(content: string) { return convertMdxToMarkdown({ metadata: { title: "t" }, content, slug: "t", href: "/t", } as Parameters[0]); }