use rstest::rstest;
use super::*;
#[rstest]
#[case(vec!["Heading".into(), "===".into()], vec!["# Heading".into()])]
#[case(vec!["Heading".into(), "----".into()], vec!["## Heading".into()])]
#[case(
vec!["- item".into(), String::new(), "Heading".into(), "---".into()],
vec!["- item".into(), String::new(), "## Heading".into()]
)]
#[case(vec![" Heading".into(), " ---".into()], vec![" ## Heading".into()])]
#[case(vec![" Heading".into(), " ---".into()], vec![" ## Heading".into()])]
#[case(vec!["Title ".into(), "=====".into()], vec!["# Title".into()])]
#[case(vec![" Heading".into(), " ====".into()], vec![" # Heading".into()])]
#[case(vec!["Heading".into(), "---- ".into()], vec!["## Heading".into()])]
#[case(
vec!["> Quote".into(), "> ----".into()],
vec!["> ## Quote".into()]
)]
#[case(
vec![">> Title".into(), ">> ----".into()],
vec![">> ## Title".into()]
)]
#[case(
vec![" > Title".into(), " > -----".into()],
vec![" > ## Title".into()]
)]
fn converts_setext_headings(#[case] input: Vec<String>, #[case] expected: Vec<String>) {
assert_eq!(convert_setext_headings(&input), expected);
}
#[rstest]
#[case(vec!["```".into(), "Heading".into(), "---".into(), "```".into()])]
#[case(vec!["Not a heading".into(), "--".into()])]
#[case(vec!["- Item".into(), "-----".into()])]
#[case(vec!["- Bar".into(), " ---".into()])]
#[case(vec![String::new(), "---".into()])]
#[case(vec!["> Quote".into(), "-----".into()])]
#[case(vec!["- item".into(), " continuation".into(), "---".into()])]
#[case(vec!["- item".into(), "lazy continuation".into(), "---".into()])]
#[case(vec![" 1. item".into(), " wrapped".into(), "lazy continuation".into(), "-----".into()])]
#[case(vec!["- item".into(), String::new(), " continuation".into(), "---".into()])]
#[case(vec!["Heading".into(), "-==".into()])]
fn leaves_non_headings_untouched(#[case] lines: Vec<String>) {
assert_eq!(convert_setext_headings(&lines), lines);
}
#[rstest]
#[case(vec!["# aa".into(), "===".into()])]
#[case(vec!["## aa".into(), "---".into()])]
#[case(vec!["### aa".into(), "===".into()])]
#[case(vec!["#### aa".into(), "---".into()])]
#[case(vec!["##### aa".into(), "===".into()])]
#[case(vec!["###### aa".into(), "---".into()])]
#[case(vec!["# aa #".into(), "===".into()])]
#[case(vec!["## aa ##".into(), "---".into()])]
#[case(vec!["###### aa ######".into(), "---".into()])]
#[case(vec!["> ## aa".into(), "> ---".into()])]
#[case(vec![">> # aa".into(), ">> ===".into()])]
#[case(vec![" ### aa".into(), " ---".into()])]
#[case(vec!["---".into(), "---".into()])]
#[case(vec!["***".into(), "---".into()])]
#[case(vec!["___".into(), "---".into()])]
#[case(vec!["- - -".into(), "---".into()])]
#[case(vec!["| --- | --- |".into(), "---".into()])]
#[case(vec!["|---|---|".into(), "---".into()])]
#[case(vec!["> | --- | --- |".into(), "> ---".into()])]
#[case(vec![">> |:--|--:|".into(), ">> ---".into()])]
#[case(vec![" | --- | --- |".into(), " ---".into()])]
#[case(vec!["* item".into(), "-----".into()])]
#[case(vec![" - item".into(), " ---".into()])]
#[case(vec!["1. item".into(), "---".into()])]
#[case(vec!["1) item".into(), "---".into()])]
#[case(vec!["- [x] task".into(), "---".into()])]
#[case(vec!["[^1]: note".into(), "---".into()])]
#[case(vec!["[label]: https://example.com".into(), "---".into()])]
#[case(vec!["<!-- markdownlint-disable MD013 -->".into(), "---".into()])]
#[case(vec![" code".into(), " ---".into()])]
#[case(vec![" code".into(), " ===".into()])]
#[case(vec!["\tcode".into(), "\t---".into()])]
#[case(vec!["> code".into(), "> ---".into()])]
#[case(vec![">> code".into(), ">> ===".into()])]
#[case(vec![" > code".into(), " > ---".into()])]
#[case(vec![" > code".into(), " > ---".into()])]
#[case(vec![" > code".into(), " > ---".into()])]
fn refuses_underlines_below_a_block_start(#[case] lines: Vec<String>) {
assert_eq!(convert_setext_headings(&lines), lines);
}
#[rstest]
#[case("code", 0)]
#[case(" code", 3)]
#[case(" code", 4)]
#[case("\tcode", 4)]
#[case("> code", 0)]
#[case("> code", 2)]
#[case("> code", 4)]
#[case(" > code", 0)]
#[case(" > code", 4)]
#[case(" > code", 4)]
#[case(" > code", 4)]
#[case(" > code", 4)]
#[case(">> # aa", 0)]
#[case(">> code", 4)]
fn measures_content_indentation(#[case] line: &str, #[case] expected: usize) {
assert_eq!(content_indent_width(line), expected);
}
#[rstest]
#[case("## aa", false)]
#[case("# aa #", false)]
#[case("---", false)]
#[case("***", false)]
#[case("- item", false)]
#[case("1. item", false)]
#[case("> quote", false)]
#[case("[^1]: note", false)]
#[case("[label]: https://example.com", false)]
#[case("<!-- markdownlint-disable MD013 -->", false)]
#[case("```", false)]
#[case("~~~", false)]
#[case("| --- | --- |", false)]
#[case("|---|---|", false)]
#[case("--- | ---", false)]
#[case("|:--|--:|", false)]
#[case("| a | b |", false)]
#[case("| a | b", false)]
#[case("| | |", false)]
#[case("plain paragraph", true)]
#[case("2024 revenue", true)]
#[case("Text with > inside", true)]
#[case("Text with > inside | here", true)]
fn classifies_setext_text(#[case] payload: &str, #[case] expected: bool) {
let matcher = LinkReferenceMatcher::production();
assert_eq!(
is_setext_text(
payload,
is_setext_text_line(payload, &ClassifyCtx::default()),
matcher,
),
expected
);
}
#[rstest]
#[case(vec!["2024 revenue".into(), "===".into()], vec!["# 2024 revenue".into()])]
fn converts_digit_prefixed_paragraphs(#[case] input: Vec<String>, #[case] expected: Vec<String>) {
assert_eq!(convert_setext_headings(&input), expected);
}