use cmark_writer::{
CommonMarkWriter, HtmlAttribute, HtmlElement, HtmlWriter, HtmlWriterOptions, Node,
WriterOptions,
};
#[test]
fn test_derived_html_options() {
let cmark_options = WriterOptions {
strict: false,
indent_spaces: 2,
..Default::default()
};
let mut cmark_writer = CommonMarkWriter::with_options(cmark_options);
let html_element = HtmlElement {
tag: "div".to_string(),
attributes: vec![HtmlAttribute {
name: "class".to_string(),
value: "container".to_string(),
}],
children: vec![Node::Text("Content in HTML element".to_string())],
self_closing: false,
};
cmark_writer
.write(&Node::HtmlElement(html_element))
.unwrap();
let output = cmark_writer.into_string();
assert!(output.contains("<div class=\"container\">Content in HTML element</div>"));
}
#[test]
fn test_html_options_strict_mode() {
let options_strict = HtmlWriterOptions {
strict: true,
..Default::default()
};
let options_lenient = HtmlWriterOptions {
strict: false,
..Default::default()
};
let invalid_tag_element = HtmlElement {
tag: "invalid<tag>".to_string(),
attributes: vec![],
children: vec![Node::Text("Content".to_string())],
self_closing: false,
};
let mut strict_writer = HtmlWriter::with_options(options_strict);
let strict_result = strict_writer.write_node(&Node::HtmlElement(invalid_tag_element.clone()));
assert!(strict_result.is_err());
let mut lenient_writer = HtmlWriter::with_options(options_lenient);
let lenient_result = lenient_writer.write_node(&Node::HtmlElement(invalid_tag_element));
assert!(lenient_result.is_ok());
let output = lenient_writer.into_string();
assert!(output.contains("<invalid<tag>>"));
}
#[test]
fn test_code_block_language_class() {
let options_with_prefix = HtmlWriterOptions {
code_block_language_class_prefix: Some("lang-".to_string()),
..Default::default()
};
let options_without_prefix = HtmlWriterOptions {
code_block_language_class_prefix: None,
..Default::default()
};
let code_block = Node::CodeBlock {
language: Some("rust".to_string()),
content: "fn main() {\n println!(\"Hello\");\n}".to_string(),
block_type: Default::default(),
};
let mut writer_with_prefix = HtmlWriter::with_options(options_with_prefix);
writer_with_prefix.write_node(&code_block).unwrap();
let output_with_prefix = writer_with_prefix.into_string();
assert!(output_with_prefix.contains("class=\"lang-rust\""));
let mut writer_without_prefix = HtmlWriter::with_options(options_without_prefix);
writer_without_prefix.write_node(&code_block).unwrap();
let output_without_prefix = writer_without_prefix.into_string();
assert!(!output_without_prefix.contains("class="));
}
#[cfg(feature = "gfm")]
#[test]
fn test_gfm_html_filtering() {
let options = HtmlWriterOptions {
enable_gfm: true,
gfm_disallowed_html_tags: vec!["script".to_string()],
..Default::default()
};
let script_element = HtmlElement {
tag: "script".to_string(),
attributes: vec![],
children: vec![Node::Text("alert('test');".to_string())],
self_closing: false,
};
let mut writer = HtmlWriter::with_options(options);
writer
.write_node(&Node::HtmlElement(script_element))
.unwrap();
let output = writer.into_string();
assert!(output.contains("<script>"));
println!("Output: {}", output);
assert!(output.contains("alert('test');"));
}
#[test]
fn test_nested_html_structures() {
let mut writer = HtmlWriter::new();
let nested_element = HtmlElement {
tag: "div".to_string(),
attributes: vec![HtmlAttribute {
name: "class".to_string(),
value: "outer".to_string(),
}],
children: vec![Node::HtmlElement(HtmlElement {
tag: "div".to_string(),
attributes: vec![HtmlAttribute {
name: "class".to_string(),
value: "inner".to_string(),
}],
children: vec![Node::Paragraph(vec![Node::Text(
"Paragraph inside HTML".to_string(),
)])],
self_closing: false,
})],
self_closing: false,
};
writer
.write_node(&Node::HtmlElement(nested_element))
.unwrap();
let output = writer.into_string();
assert!(output.contains("<div class=\"outer\">"));
assert!(output.contains("<div class=\"inner\">"));
assert!(output.contains("<p>Paragraph inside HTML</p>"));
assert!(output.contains("</div></div>"));
}