#[macro_use]
mod prelude;
use mdtablefix::{attach_orphan_specifiers, compress_fences};
use rstest::rstest;
#[test]
fn compresses_backtick_fences() {
let input = lines_vec!["````rust", "code", "````"];
let out = compress_fences(&input);
assert_eq!(out, lines_vec!["```rust", "code", "```"]);
}
#[test]
fn compresses_indented_backticks() {
let input = lines_vec![" `````foo,bar "];
let out = compress_fences(&input);
assert_eq!(out, lines_vec![" ```foo,bar"]);
}
#[test]
fn compresses_tilde_fences() {
let input = lines_vec!["~~~~rust", "code", "~~~~"];
let out = compress_fences(&input);
assert_eq!(out, lines_vec!["```rust", "code", "```"]);
}
#[test]
fn does_not_compress_mixed_fences() {
let input = lines_vec!["~~~rust", "code", "```"];
let out = compress_fences(&input);
assert_eq!(out, lines_vec!["```rust", "code", "```"]);
let input2 = lines_vec!["```rust", "code", "~~~"];
let out2 = compress_fences(&input2);
assert_eq!(out2, lines_vec!["```rust", "code", "```"]);
}
#[test]
fn leaves_other_lines_untouched() {
let input = lines_vec!["~~", "``text``"];
let out = compress_fences(&input);
assert_eq!(out, input);
}
#[test]
fn fixes_orphaned_specifier() {
let input = lines_vec!["Rust", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[test]
fn attaches_orphan_specifier_unit() {
let input = lines_vec!["Rust", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[test]
fn attaches_orphan_specifier_with_blank_line_unit() {
let input = lines_vec!["Rust", "", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[test]
fn fixes_orphaned_specifier_with_blank_line() {
let input = lines_vec!["Rust", "", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[test]
fn fixes_multiple_orphaned_specifiers() {
let input = lines_vec![
"Rust",
"```",
"fn main() {}",
"```",
"",
"Python",
"```",
"print('hi')",
"```",
];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(
out,
lines_vec![
"```rust",
"fn main() {}",
"```",
"",
"```python",
"print('hi')",
"```"
]
);
}
#[test]
fn does_not_attach_non_orphan_lines_before_fences() {
let input = lines_vec![
"Rust code",
"```",
"fn main() {}",
"```",
"rust!",
"```",
"println!(\"hi\");",
"```",
];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, input);
}
#[test]
fn does_not_overwrite_existing_fence() {
let input = lines_vec!["ruby", "```rust", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["ruby", "```rust", "fn main() {}", "```"]);
}
#[test]
fn does_not_attach_specifier_without_preceding_blank_line() {
let input = lines_vec!["intro", "Rust", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(
out,
lines_vec!["intro", "Rust", "```", "fn main() {}", "```"]
);
}
#[test]
fn attaches_orphan_specifier_with_symbols() {
let input = lines_vec!["C++", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```c++", "fn main() {}", "```"]);
}
#[test]
fn attaches_orphan_specifier_with_hyphen_and_dot() {
let input = lines_vec!["objective-c", "```", "int main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```objective-c", "int main() {}", "```"]);
}
#[test]
fn does_not_attach_specifier_with_trailing_period() {
let input = lines_vec!["rust.", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, input);
}
#[test]
fn does_not_attach_specifier_with_trailing_question_mark() {
let input = lines_vec!["rust?", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, input);
}
#[test]
fn attaches_orphan_specifier_preserves_indent() {
let input = lines_vec![" Rust", "", " ```", " fn main() {}", " ```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec![" ```rust", " fn main() {}", " ```"]);
}
#[test]
fn attaches_orphan_specifier_preserves_tab_indent() {
let input = lines_vec!["\tRust", "", "\t```", "\tfn main() {}", "\t```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["\t```rust", "\tfn main() {}", "\t```"]);
}
#[test]
fn attaches_orphan_specifier_mixed_indent() {
let input = lines_vec![" \tRust", "", " \t```", " \tfn main() {}", " \t```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec![" \t```rust", " \tfn main() {}", " \t```"]);
}
#[test]
fn attaches_orphan_specifier_uses_candidate_indent_when_fence_unindented() {
let input = lines_vec![" Rust", "", "```", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec![" ```rust", "fn main() {}", "```"]);
}
#[rstest]
#[case(lines_vec![" Rust", "", " ```", " fn main() {}", " ```"], lines_vec![" ```rust", " fn main() {}", " ```"])]
#[case(lines_vec![" Rust", "", " ```", " fn main() {}", " ```"], lines_vec![" ```rust", " fn main() {}", " ```"])]
fn attaches_orphan_specifier_with_mismatched_indent(
#[case] input: Vec<String>,
#[case] expected: Vec<String>,
) {
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, expected);
}
#[test]
fn attaches_orphan_specifier_allows_spaces() {
let input = lines_vec!["TOML, Ini", "```", "a=1", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```toml,ini", "a=1", "```"]);
}
#[rstest]
#[case("````null", "````")]
#[case("````NULL", "````")]
#[case("````Null", "````")]
#[case("````null ", "````")]
#[case("```` ", "````")]
#[case("````NULL ", "````")]
#[case("````Null ", "````")]
#[case("~~~~null", "~~~~")]
#[case("~~~~NULL", "~~~~")]
#[case("~~~~Null", "~~~~")]
#[case("~~~~null ", "~~~~")]
#[case("~~~~ ", "~~~~")]
#[case("~~~~NULL ", "~~~~")]
#[case("~~~~Null ", "~~~~")]
fn compresses_null_language_to_empty(#[case] open: &str, #[case] close: &str) {
let input = lines_vec![open, "code", close];
let out = compress_fences(&input);
assert_eq!(out, lines_vec!["```", "code", "```"]);
}
#[rstest]
#[case("```null")]
#[case("```NULL")]
#[case("```Null")]
#[case("```null ")]
#[case("```NULL ")]
#[case("```Null ")]
#[case("~~~~null")]
#[case("~~~~NULL")]
#[case("~~~~Null")]
#[case("~~~~null ")]
#[case("~~~~NULL ")]
#[case("~~~~Null ")]
fn attaches_orphan_specifier_when_null_language(#[case] fence: &str) {
let input = lines_vec!["Rust", fence, "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[test]
fn attaches_orphan_specifier_null_language_without_compression() {
let input = lines_vec!["Rust", "```null", "fn main() {}", "```"];
let out = attach_orphan_specifiers(&input);
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}
#[rstest]
#[case("``` ")]
#[case("~~~~ ")]
fn attaches_orphan_specifier_whitespace_language(#[case] fence: &str) {
let input = lines_vec!["Rust", fence, "fn main() {}", "```"];
let out = attach_orphan_specifiers(&compress_fences(&input));
assert_eq!(out, lines_vec!["```rust", "fn main() {}", "```"]);
}