markdownMermaid.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import assert from "node:assert/strict";
  2. import fs from "node:fs/promises";
  3. import os from "node:os";
  4. import path from "node:path";
  5. import test from "node:test";
  6. import {
  7. buildMermaidRuntimeHtml,
  8. createMarkdownRenderer,
  9. } from "../src/actions/_shared/markdown.js";
  10. import { clearTemplateCache } from "../src/actions/_shared/template-cache.js";
  11. import { renderMarkdownWithTemplate } from "../src/actions/renderMarkdownWithTemplate/index.js";
  12. test("mermaid fences render as mermaid blocks and track render state", () => {
  13. const renderer = createMarkdownRenderer({ resources: {} });
  14. const html = renderer("```mermaid\nflowchart LR\nA-->B\n```");
  15. assert.equal(
  16. html,
  17. '<pre class="mermaid">flowchart LR\nA--&gt;B</pre>',
  18. );
  19. assert.deepEqual(renderer.getLastRenderState(), { hasMermaid: true });
  20. renderer("Regular paragraph");
  21. assert.deepEqual(renderer.getLastRenderState(), { hasMermaid: false });
  22. });
  23. test("mermaid runtime html uses defaults and respects overrides", () => {
  24. const defaultRuntime = buildMermaidRuntimeHtml({ opts: { markdown: {} } });
  25. assert.equal(
  26. defaultRuntime.includes(
  27. 'src="https://cdn.jsdelivr.net/npm/mermaid@11.13.0/dist/mermaid.min.js"',
  28. ),
  29. true,
  30. );
  31. assert.equal(defaultRuntime.includes('"startOnLoad":false'), true);
  32. const customRuntime = buildMermaidRuntimeHtml({
  33. opts: {
  34. markdown: {
  35. mermaid: {
  36. initialize: { theme: "forest" },
  37. scriptSrc: "/static/vendor/mermaid.min.js",
  38. },
  39. },
  40. },
  41. });
  42. assert.equal(
  43. customRuntime.includes('src="/static/vendor/mermaid.min.js"'),
  44. true,
  45. );
  46. assert.equal(customRuntime.includes('"theme":"forest"'), true);
  47. });
  48. test("renderMarkdownWithTemplate injects mermaid runtime only when needed", async t => {
  49. const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "rhedyn-mermaid-"));
  50. const templateDir = path.join(tempDir, "templates");
  51. const outDir = path.join(tempDir, "dist");
  52. const partialDir = path.join(tempDir, "partials");
  53. const mermaidMarkdownPath = path.join(tempDir, "diagram.md");
  54. const plainMarkdownPath = path.join(tempDir, "plain.md");
  55. const mermaidOutputPath = path.join(outDir, "diagram.html");
  56. const plainOutputPath = path.join(outDir, "plain.html");
  57. t.after(async () => {
  58. await fs.rm(tempDir, { force: true, recursive: true });
  59. });
  60. await fs.mkdir(templateDir, { recursive: true });
  61. await fs.mkdir(partialDir, { recursive: true });
  62. await fs.writeFile(
  63. path.join(templateDir, "page.hbs"),
  64. "<html><body>{{{content}}}</body></html>",
  65. "utf8",
  66. );
  67. await fs.writeFile(
  68. mermaidMarkdownPath,
  69. "```mermaid\nflowchart LR\nA-->B\n```",
  70. "utf8",
  71. );
  72. await fs.writeFile(plainMarkdownPath, "Plain paragraph.", "utf8");
  73. clearTemplateCache();
  74. const meta = {
  75. opts: {
  76. markdown: {},
  77. outDir: outDir,
  78. runDir: tempDir,
  79. },
  80. resources: {},
  81. };
  82. await renderMarkdownWithTemplate({
  83. config: {
  84. defaultTemplate: "page",
  85. fileOutputPath: mermaidOutputPath,
  86. filePath: mermaidMarkdownPath,
  87. partialDirs: [partialDir],
  88. templateDirs: [templateDir],
  89. },
  90. meta,
  91. });
  92. await renderMarkdownWithTemplate({
  93. config: {
  94. defaultTemplate: "page",
  95. fileOutputPath: plainOutputPath,
  96. filePath: plainMarkdownPath,
  97. partialDirs: [partialDir],
  98. templateDirs: [templateDir],
  99. },
  100. meta,
  101. });
  102. const mermaidHtml = await fs.readFile(mermaidOutputPath, "utf8");
  103. const plainHtml = await fs.readFile(plainOutputPath, "utf8");
  104. assert.equal(/class=(?:"mermaid"|mermaid)/.test(mermaidHtml), true);
  105. assert.equal(mermaidHtml.includes("mermaid.initialize"), true);
  106. assert.equal(mermaidHtml.includes("cdn.jsdelivr.net/npm/mermaid@11.13.0"), true);
  107. assert.equal(plainHtml.includes("mermaid.initialize"), false);
  108. assert.equal(plainHtml.includes("cdn.jsdelivr.net/npm/mermaid@11.13.0"), false);
  109. });