use markdown2pdf::markdown::*;
use super::common::parse;
fn first_html_block(tokens: &[Token]) -> Option<String> {
tokens.iter().find_map(|t| match t {
Token::HtmlBlock(s) => Some(s.clone()),
_ => None,
})
}
#[test]
fn cdata_single_line() {
let tokens = parse("<![CDATA[foo]]>\n");
assert_eq!(
first_html_block(&tokens).as_deref(),
Some("<![CDATA[foo]]>\n"),
);
}
#[test]
fn cdata_multi_line() {
let input = "<![CDATA[\nline one\nline two\n]]>\n";
let tokens = parse(input);
assert_eq!(first_html_block(&tokens).as_deref(), Some(input));
}
#[test]
fn cdata_with_markdown_chars_left_literal() {
let input = "<![CDATA[\n*not emphasis*\n`not code`\n]]>\n";
let tokens = parse(input);
assert_eq!(first_html_block(&tokens).as_deref(), Some(input));
assert!(!tokens.iter().any(|t| matches!(t, Token::Emphasis { .. })));
}
#[test]
fn cdata_with_angle_brackets_and_ampersands_inside() {
let input = "<![CDATA[a < b && c > d]]>\n";
let tokens = parse(input);
assert_eq!(first_html_block(&tokens).as_deref(), Some(input));
}
#[test]
fn cdata_with_blank_lines_inside() {
let input = "<![CDATA[\nfirst\n\nsecond\n]]>\n";
let tokens = parse(input);
assert_eq!(first_html_block(&tokens).as_deref(), Some(input));
}
#[test]
fn cdata_followed_by_paragraph() {
let input = "<![CDATA[\nbody\n]]>\nokay\n";
let tokens = parse(input);
let block = first_html_block(&tokens).expect("expected HtmlBlock");
assert_eq!(block, "<![CDATA[\nbody\n]]>\n");
let text = Token::collect_all_text(&tokens);
assert!(text.contains("okay"), "got {:?}", text);
}
#[test]
fn cdata_with_one_space_indent() {
let input = " <![CDATA[foo]]>\n";
let block = first_html_block(&parse(input)).expect("expected HtmlBlock");
assert!(block.starts_with(" <!["), "got {:?}", block);
}
#[test]
fn cdata_with_three_space_indent() {
let input = " <![CDATA[foo]]>\n";
let block = first_html_block(&parse(input)).expect("expected HtmlBlock");
assert!(block.starts_with(" <!["), "got {:?}", block);
}
#[test]
fn four_space_indent_is_code_block_not_cdata() {
let tokens = parse(" <![CDATA[foo]]>\n");
assert!(first_html_block(&tokens).is_none());
assert!(tokens.iter().any(|t| matches!(t, Token::Code { block: true, .. })));
}
#[test]
fn cdata_not_at_line_start_is_inline_text() {
let tokens = parse("paragraph <![CDATA[foo]]>\n");
assert!(first_html_block(&tokens).is_none());
}
#[test]
fn cdata_inside_blockquote() {
let tokens = parse("> <![CDATA[foo]]>\n");
let Some(Token::BlockQuote(body)) = tokens.first() else {
panic!("expected BlockQuote, got {:?}", tokens);
};
assert!(
body.iter().any(|t| matches!(t, Token::HtmlBlock(_))),
"expected HtmlBlock inside BlockQuote, got {:?}",
body
);
}
#[test]
fn unterminated_cdata_falls_through() {
let tokens = parse("<![CDATA[never closes\nmore text\n");
assert!(first_html_block(&tokens).is_none());
}
#[test]
fn cdata_with_partial_terminator_inside() {
let input = "<![CDATA[contains ]] and ] but no closer until]]>\n";
let tokens = parse(input);
assert_eq!(first_html_block(&tokens).as_deref(), Some(input));
}