Two issues made docs/api hard to read: 1. The site's custom Markdown parser only recognized `- ` bullets, so the README's `* ` bullets rendered as a single run-on paragraph with literal asterisks. Extended the parser (and tests) to accept the full CommonMark bullet set: `-`, `*`, `+`. 2. The shared .markdown-content container is 88rem wide. Comfortable for /algo's wide tables but uncomfortable for monospace prose, which prefers ~80ch. Added a .api-docs modifier class on the /docs/api page that drops max-width to 60rem, allows table cells to wrap, and slightly downsizes headings.
187 lines
5 KiB
Elixir
187 lines
5 KiB
Elixir
defmodule Microwaveprop.MarkdownTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Microwaveprop.Markdown
|
|
|
|
describe "headings" do
|
|
test "renders h1" do
|
|
assert Markdown.to_html!("# Hello") =~ "<h1>Hello</h1>"
|
|
end
|
|
|
|
test "renders h2 through h6" do
|
|
for level <- 2..6 do
|
|
hashes = String.duplicate("#", level)
|
|
assert Markdown.to_html!("#{hashes} Title") =~ "<h#{level}>Title</h#{level}>"
|
|
end
|
|
end
|
|
|
|
test "caps at h6 for excessive hashes" do
|
|
assert Markdown.to_html!("####### Too many") =~ "<h6>"
|
|
end
|
|
end
|
|
|
|
describe "paragraphs" do
|
|
test "renders simple paragraph" do
|
|
assert Markdown.to_html!("Hello world") =~ "<p>Hello world</p>"
|
|
end
|
|
|
|
test "joins multi-line paragraphs" do
|
|
result = Markdown.to_html!("Line one\nLine two")
|
|
assert result =~ "<p>Line one Line two</p>"
|
|
end
|
|
|
|
test "separates paragraphs by blank lines" do
|
|
result = Markdown.to_html!("Para one\n\nPara two")
|
|
assert result =~ "<p>Para one</p>"
|
|
assert result =~ "<p>Para two</p>"
|
|
end
|
|
end
|
|
|
|
describe "fenced code blocks" do
|
|
test "renders code block" do
|
|
md = "```\nfoo\nbar\n```"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<pre><code>foo\nbar</code></pre>"
|
|
end
|
|
|
|
test "renders code block with language" do
|
|
md = "```elixir\nIO.puts(\"hi\")\n```"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ ~s(<code class="language-elixir">)
|
|
end
|
|
|
|
test "escapes HTML in code blocks" do
|
|
md = "```\n<script>alert('xss')</script>\n```"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<script>"
|
|
refute result =~ "<script>"
|
|
end
|
|
end
|
|
|
|
describe "tables" do
|
|
test "renders table with header" do
|
|
md = "| A | B |\n|---|---|\n| 1 | 2 |"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<thead>"
|
|
assert result =~ "<th>A</th>"
|
|
assert result =~ "<td>1</td>"
|
|
end
|
|
end
|
|
|
|
describe "lists" do
|
|
test "renders unordered list" do
|
|
md = "- one\n- two\n- three"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<ul>"
|
|
assert result =~ "<li>one</li>"
|
|
assert result =~ "<li>two</li>"
|
|
assert result =~ "<li>three</li>"
|
|
end
|
|
|
|
test "renders ordered list" do
|
|
md = "1. first\n2. second"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<ol>"
|
|
assert result =~ "<li>first</li>"
|
|
assert result =~ "<li>second</li>"
|
|
end
|
|
|
|
test "renders unordered list with * bullets" do
|
|
result = Markdown.to_html!("* one\n* two")
|
|
assert result =~ "<ul>"
|
|
assert result =~ "<li>one</li>"
|
|
assert result =~ "<li>two</li>"
|
|
end
|
|
|
|
test "renders unordered list with + bullets" do
|
|
result = Markdown.to_html!("+ alpha\n+ beta")
|
|
assert result =~ "<ul>"
|
|
assert result =~ "<li>alpha</li>"
|
|
assert result =~ "<li>beta</li>"
|
|
end
|
|
|
|
test "single-line bullet (binary < 2 bytes prefix safety)" do
|
|
assert Markdown.to_html!("*") =~ "<p>"
|
|
end
|
|
end
|
|
|
|
describe "inline formatting" do
|
|
test "renders bold with **" do
|
|
assert Markdown.to_html!("**bold**") =~ "<strong>bold</strong>"
|
|
end
|
|
|
|
test "renders bold with __" do
|
|
assert Markdown.to_html!("__bold__") =~ "<strong>bold</strong>"
|
|
end
|
|
|
|
test "renders italic with *" do
|
|
assert Markdown.to_html!("*italic*") =~ "<em>italic</em>"
|
|
end
|
|
|
|
test "renders inline code" do
|
|
assert Markdown.to_html!("`code`") =~ "<code>code</code>"
|
|
end
|
|
|
|
test "renders links" do
|
|
assert Markdown.to_html!("[text](http://example.com)") =~ ~s(<a href="http://example.com">text</a>)
|
|
end
|
|
end
|
|
|
|
describe "list continuation" do
|
|
test "continues unordered list items with indentation" do
|
|
md = "- item one\n continued\n- item two"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<li>item one continued</li>"
|
|
assert result =~ "<li>item two</li>"
|
|
end
|
|
end
|
|
|
|
describe "table without separator" do
|
|
test "renders table body only when no separator row" do
|
|
md = "| A | B |"
|
|
result = Markdown.to_html!(md)
|
|
assert result =~ "<tbody>"
|
|
refute result =~ "<thead>"
|
|
end
|
|
end
|
|
|
|
describe "CRLF handling" do
|
|
test "normalizes CRLF to LF" do
|
|
result = Markdown.to_html!("Hello\r\nworld")
|
|
assert result =~ "<p>Hello world</p>"
|
|
end
|
|
end
|
|
|
|
describe "empty input" do
|
|
test "handles empty string" do
|
|
assert Markdown.to_html!("") == ""
|
|
end
|
|
end
|
|
|
|
describe "horizontal rules" do
|
|
test "renders --- as hr" do
|
|
assert Markdown.to_html!("---") =~ "<hr />"
|
|
end
|
|
|
|
test "renders *** as hr" do
|
|
assert Markdown.to_html!("***") =~ "<hr />"
|
|
end
|
|
|
|
test "renders ___ as hr" do
|
|
assert Markdown.to_html!("___") =~ "<hr />"
|
|
end
|
|
end
|
|
|
|
describe "HTML escaping" do
|
|
test "escapes angle brackets in paragraphs" do
|
|
result = Markdown.to_html!("x < y > z")
|
|
assert result =~ "<"
|
|
assert result =~ ">"
|
|
end
|
|
|
|
test "escapes ampersands" do
|
|
result = Markdown.to_html!("a & b")
|
|
assert result =~ "&"
|
|
end
|
|
end
|
|
end
|