mod support;
use moli_html2md::{Converter, Options};
use support::{Tree, rendered_html};
fn markdown_with(html: &str, options: Options) -> String {
let dom = Tree::parse(html);
let before = dom.clone();
let result = Converter::new(options).convert(&dom, dom.root);
assert_eq!(dom, before);
result
}
fn markdown(html: &str) -> String {
markdown_with(html, Options::default())
}
#[test]
fn inline_code_breaks_separate_words_without_formatting_markers() {
for html in [
"git",
"
statusgit",
"
statusgit",
] {
for preformatted_code in [false, true] {
let result = markdown_with(
html,
Options {
preformatted_code,
..Options::default()
},
);
assert_eq!(result, "`git status`", "{html}");
assert_eq!(
rendered_html(&result),
"
status
git status
git
status";
assert_eq!(markdown(html), "`git status`");
let result = markdown_with(
html,
Options {
preformatted_code: true,
..Options::default()
},
);
assert_eq!(result, "`git status`");
assert_eq!(
rendered_html(&result),
"git status
git
statusafter",
"before`git` `status`after",
),
("before
git
after", "before `git` after"),
] {
assert_eq!(markdown(html), expected, "{html}");
}
let result = markdown_with(
"beforegit
statusafter",
Options {
preformatted_code: true,
..Options::default()
},
);
assert_eq!(
rendered_html(&result),
"beforegit statusafter
git
status";
for (max_depth, expected) in [(3, "`gitstatus`"), (4, "`git status`")] {
assert_eq!(
markdown_with(
html,
Options {
max_depth,
..Options::default()
},
),
expected
);
}
}
#[test]
fn pre_keeps_raw_text_and_line_endings() {
let result = markdown("git\n status");
assert_eq!(result, "```\ngit\n status\n```");
assert_eq!(
rendered_html(&result),
"git\n status\n\n"
);
}
#[test]
fn preformatted_examples_keep_inline_values_and_separate_display_lines() {
for (source, expected) in [
(
"const answer = ;", "const answer = 42;", ), ( "
", "TypeScript\nfunction identity() {}", ), ( "TypeScript
function identity() {}
", "first()\nsecond()", ), ("
- first()
- second()
first", "first\nsecond"), ] { let result = markdown(source); assert_eq!( rendered_html(&result), format!("
second
{expected}\n\n"),
"{source}: {result}"
);
}
}
#[test]
fn empty_wrappers_do_not_add_lines_to_preformatted_examples() {
for (source, expected) in [
("print(42)", "print(42)"), ( "
", "print(42)", ), ( "print(42)
first", "first\nsecond\nthird", ), ("secondthird
\nprint(42)", "\nprint(42)"),
] {
let result = markdown(source);
assert_eq!(
rendered_html(&result),
format!("{expected}\n\n"),
"{source}: {result}"
);
}
}
#[test]
fn nested_emphasis_closes_with_markdown_before_a_word() {
for (html, expected, expected_html) in [
(
"xy",
"***x***y",
"xy
\n", ), ( "xy", "***x***y", "xy
\n", ), ( "abcd", "a**b*c***d", "abcd
\n", ), ( "abcd", "a*b**c***d", "abcd
\n", ), ( "xyz", "***x*y**z", "xyz
\n", ), ( "xyz", "***x**y*z", "xyz
\n", ), ] { let result = markdown(html); assert_eq!(result, expected, "{html}"); assert_eq!(rendered_html(&result), expected_html, "{html}"); } } #[test] fn nested_emphasis_still_uses_html_after_literal_punctuation() { for text in ["word!", "word*", "word`", "word)", "日本語。"] { for (outer, inner) in [("em", "strong"), ("strong", "em")] { let html = format!("<{outer}><{inner}>{text}{inner}>{outer}>after"); let result = markdown(&html); assert!(result.contains(&format!("<{outer}>")), "{result}"); assert_eq!(rendered_html(&result), format!("{html}
\n")); } } } #[test] fn closing_runs_stop_at_links_code_images_and_other_markers() { for (html, expected_html) in [ ( "xy", "xy
\n", ), ( "xy",
"xy
y
xy
xy
abcd
\n" ); for text in ["x", "x!", "x*"] { for (outer, inner) in [("em", "strong"), ("strong", "em")] { let html = format!( "before<{outer}><{inner}>{text}{inner}>b<{inner}>c{inner}>{outer}>after" ); assert_eq!( rendered_html(&markdown(&html)), format!("{html}
\n"), "{html}" ); } } }