use html_compare_rs::assert_html_eq;
use pulldown_cmark::Parser;
use pulldown_html_ext::*;
use std::collections::HashMap;
fn render_with_config(input: &str, config: &HtmlConfig) -> String {
let mut output = String::new();
let handler = DefaultHtmlWriter::new(&mut output, config.clone());
let mut renderer = HtmlRenderer::new(handler);
let _ = renderer.run(Parser::new(input));
output
}
#[test]
#[ignore = "TODO: Fix/define escape_html handling in renderer"]
fn test_escape_html_option() {
let mut config = HtmlConfig::default();
config.html.escape_html = true;
assert_html_eq!(
render_with_config("<div>test</div>", &config),
"<p><div>test</div></p>"
);
config.html.escape_html = false;
assert_html_eq!(
render_with_config("<div>test</div>", &config),
"<p><div>test</div></p>"
);
}
#[test]
fn test_break_on_newline_option() {
let mut config = HtmlConfig::default();
config.html.break_on_newline = true;
assert_html_eq!(
render_with_config("Line 1\nLine 2", &config),
"<p>Line 1<br>Line 2</p>"
);
config.html.break_on_newline = false;
assert_html_eq!(
render_with_config("Line 1\nLine 2", &config),
"<p>Line 1\nLine 2</p>"
);
}
#[test]
fn test_xhtml_style_option() {
let mut config = HtmlConfig::default();
config.html.xhtml_style = false;
assert_html_eq!(
render_with_config("", &config),
"<p><img src=\"image.jpg\" alt=\"Alt\"></p>"
);
config.html.xhtml_style = true;
assert_html_eq!(
render_with_config("", &config),
"<p><img src=\"image.jpg\" alt=\"Alt\" /></p>"
);
}
#[test]
fn test_heading_id_option() {
let mut config = HtmlConfig::default();
config.elements.headings.add_ids = true;
assert_html_eq!(
render_with_config("# Test Heading", &config),
"<h1 id=\"heading-1\">Test Heading</h1>"
);
config.elements.headings.add_ids = false;
assert_html_eq!(
render_with_config("# Test Heading", &config),
"<h1>Test Heading</h1>"
);
}
#[test]
fn test_heading_id_prefix_option() {
let mut config = HtmlConfig::default();
config.elements.headings.id_prefix = "section-".to_string();
assert_html_eq!(
render_with_config("# Test Heading", &config),
"<h1 id=\"section-1\">Test Heading</h1>"
);
}
#[test]
fn test_heading_level_classes() {
let mut config = HtmlConfig::default();
let mut level_classes = HashMap::new();
level_classes.insert(1, "title".to_string());
level_classes.insert(2, "subtitle".to_string());
config.elements.headings.level_classes = level_classes;
assert_html_eq!(
render_with_config("# Heading 1\n## Heading 2", &config),
"<h1 id=\"heading-1\" class=\"title\">Heading 1</h1>\
<h2 id=\"heading-2\" class=\"subtitle\">Heading 2</h2>"
);
}
#[test]
fn test_link_options() {
let mut config = HtmlConfig::default();
config.elements.links.nofollow_external = true;
config.elements.links.open_external_blank = true;
assert_html_eq!(
render_with_config(
"[Internal](/test) and [External](https://example.com)",
&config
),
"<p><a href=\"/test\">Internal</a> and \
<a href=\"https://example.com\" rel=\"nofollow\" target=\"_blank\">External</a></p>"
);
}
#[test]
fn test_code_block_options() {
let mut config = HtmlConfig::default();
config.elements.code_blocks.default_language = Some("text".to_string());
assert_html_eq!(
render_with_config("```python\nprint('hello')\n```", &config),
"<pre><code class=\"language-python\">print('hello')</code></pre>"
);
assert_html_eq!(
render_with_config("```\nhello\n```", &config),
"<pre><code class=\"language-text\">hello</code></pre>"
);
}
#[test]
fn test_custom_attributes() {
let mut config = HtmlConfig::default();
let mut element_attributes = HashMap::new();
let mut p_attrs = HashMap::new();
p_attrs.insert("class".to_string(), "content".to_string());
element_attributes.insert("p".to_string(), p_attrs);
let mut pre_attrs = HashMap::new();
pre_attrs.insert("data-type".to_string(), "code".to_string());
element_attributes.insert("pre".to_string(), pre_attrs);
config.attributes.element_attributes = element_attributes;
assert_html_eq!(
render_with_config("Regular paragraph\n\n```\nCode block\n```", &config),
"<p class=\"content\">Regular paragraph</p>\
<pre data-type=\"code\"><code>Code block</code></pre>"
);
}
#[test]
fn test_mixed_config_blog_style() {
let mut config = HtmlConfig::default();
config.html.break_on_newline = false;
config.elements.headings.add_ids = true;
config.elements.links.open_external_blank = true;
config.elements.links.nofollow_external = false;
let mut heading_classes = HashMap::new();
heading_classes.insert(1, "post-title".to_string());
config.elements.headings.level_classes = heading_classes;
let input = "# Blog Post Title\n\
Some text with an [external link](https://example.com).\n\n\
Multiple paragraphs look better\n\
without forced line breaks.";
assert_html_eq!(
render_with_config(input, &config),
"<h1 id=\"heading-1\" class=\"post-title\">Blog Post Title</h1>\
<p>Some text with an <a href=\"https://example.com\" target=\"_blank\">external link</a>.</p>\
<p>Multiple paragraphs look better\nwithout forced line breaks.</p>"
);
}
#[test]
fn test_mixed_config_documentation_style() {
let mut config = HtmlConfig::default();
config.elements.headings.id_prefix = "doc-".to_string();
config.elements.code_blocks.default_language = Some("text".to_string());
config.elements.links.nofollow_external = true;
config.elements.links.open_external_blank = false;
let mut element_attrs = HashMap::new();
let mut pre_attrs = HashMap::new();
pre_attrs.insert("class".to_string(), "documentation-code".to_string());
element_attrs.insert("pre".to_string(), pre_attrs);
config.attributes.element_attributes = element_attrs;
let input = "# Documentation\n\
Check the [reference](https://example.com).\n\n\
```python\ndef example():\n pass\n```\n\n\
```\nPlain text example\n```";
assert_html_eq!(
render_with_config(input, &config),
"<h1 id=\"doc-1\">Documentation</h1>\
<p>Check the <a href=\"https://example.com\" rel=\"nofollow\">reference</a>.</p>\
<pre class=\"documentation-code\"><code class=\"language-python\">def example():\n pass</code></pre>\
<pre class=\"documentation-code\"><code class=\"language-text\">Plain text example</code></pre>"
);
}
#[test]
fn test_mixed_config_presentation_style() {
let mut config = HtmlConfig::default();
config.html.xhtml_style = true;
config.html.break_on_newline = true;
let mut heading_classes = HashMap::new();
heading_classes.insert(1, "slide-title".to_string());
heading_classes.insert(2, "slide-subtitle".to_string());
config.elements.headings.level_classes = heading_classes;
let mut element_attrs = HashMap::new();
let mut p_attrs = HashMap::new();
p_attrs.insert("class".to_string(), "slide-content".to_string());
element_attrs.insert("p".to_string(), p_attrs);
config.attributes.element_attributes = element_attrs;
let input = "# Slide Title\n\
## Subtitle\n\n\
Content line 1\n\
Content line 2\n\n\
";
assert_html_eq!(
render_with_config(input, &config),
"<h1 id=\"heading-1\" class=\"slide-title\">Slide Title</h1>\
<h2 id=\"heading-2\" class=\"slide-subtitle\">Subtitle</h2>\
<p class=\"slide-content\">Content line 1<br />Content line 2</p>\
<p class=\"slide-content\"><img src=\"image.jpg\" alt=\"Diagram\" /></p>"
);
}