use insta::assert_snapshot;
use mdtablefix::process::WRAP_COLS;
use rstest::rstest;
use super::*;
#[test]
fn test_wrap_paragraph_with_link() {
let input = lines_vec to provide a familiar, ",
"declarative API for routing, extractors, and middleware."
)];
let output = process_stream(&input);
assert!(
output
.iter()
.any(|line| line.contains("[Actix Web](https://actix.rs/)")),
"link should not be broken across lines"
);
}
#[test]
fn test_wrap_paragraph_with_image_link() {
let input = lines_vec embedded in ",
"a sentence that should wrap without splitting the link."
)];
let output = process_stream(&input);
assert!(
output
.iter()
.any(|line| line.contains("")),
"image link should not be broken across lines",
);
}
#[test]
fn test_wrap_paragraph_with_nested_link() {
let input = lines_vec/guide) for details on",
" nightly features and usage."
)];
let output = process_stream(&input);
assert!(
output
.iter()
.any(|line| line.contains("(https://example.com/rust(nightly)/guide)")),
"link with nested parentheses should remain intact",
);
}
#[test]
fn test_wrap_link_with_trailing_punctuation() {
let input = lines_vec.",
)];
let output = process_stream(&input);
assert_eq!(output, input);
}
#[test]
fn test_wrap_long_link_trailing_punctuation() {
let input = lines_vec.",
];
let expected = lines_vec.",
];
let output = process_stream(&input);
assert_eq!(output, expected);
}
#[test]
fn test_wrap_link_multiple_trailing_punctuation() {
let input = lines_vec!? Additional words are added so this line ",
"exceeds the eighty character limit for wrapping."
)];
let output = process_stream(&input);
assert!(output.iter().any(|l| l.contains("[link](foo.md)!?")));
assert!(!output.iter().any(|l| l.trim() == "!?"));
}
#[rstest]
#[case(
concat!(
"Reference [doc](bar.md): an extended line that ensures the wrapping ",
"logic triggers because it exceeds eighty characters easily."
),
"[doc](bar.md):",
":"
)]
#[case(
concat!(
"See [note](baz.md)... this is another line with more than enough ",
"content to exceed the default width."
),
"[note](baz.md)...",
"..."
)]
#[case(
concat!(
"Alert [warn](warn.md); pay attention to the guidelines as they are ",
"critical for understanding."
),
"[warn](warn.md);",
";"
)]
fn test_wrap_link_various_wrapped_trailing_punctuation(
#[case] input_line: &str,
#[case] expected_link_with_punct: &str,
#[case] orphan_punct: &str,
) {
let input = lines_vec![input_line];
let output = process_stream(&input);
assert!(
output.iter().any(|l| l.contains(expected_link_with_punct)),
"expected {expected_link_with_punct:?} in {output:?}",
);
assert!(
!output.iter().any(|l| l.trim() == orphan_punct),
"punctuation {orphan_punct:?} was orphaned in {output:?}",
);
}
#[rstest]
#[case(
concat!(
"\"[Quoted link](quote.md)\" is important for understanding the ",
"overall design because it provides context to the guidelines."
),
"\"[Quoted link](quote.md)"
)]
#[case(
"([Parenthesized link](paren.md)) is here.",
"([Parenthesized link](paren.md)"
)]
fn test_wrap_link_leading_punctuation(#[case] input_line: &str, #[case] expected_prefix: &str) {
let input = lines_vec![input_line];
let output = process_stream(&input);
assert!(
output.iter().any(|l| l.starts_with(expected_prefix)),
"expected a line starting with {expected_prefix:?} in {output:?}",
);
assert!(
!output.iter().any(|l| l.trim() == "\""),
"stray quote was orphaned in {output:?}",
);
}
#[rstest]
#[case(
concat!(
"\"[Link](foo.md)!\" demonstrates punctuation around a link and ",
"includes plenty of extra words to exceed the wrapping limit."
),
"[Link](foo.md)!\""
)]
#[case(
"([Another](bar.md)?) should remain on one line.",
"([Another](bar.md)?)"
)]
fn test_wrap_link_leading_and_trailing_punctuation(
#[case] input_line: &str,
#[case] expected_link_with_punct: &str,
) {
let input = lines_vec![input_line];
let output = process_stream(&input);
assert!(
output.iter().any(|l| l.contains(expected_link_with_punct)),
"expected {expected_link_with_punct:?} in {output:?}",
);
assert!(
!output.iter().any(|l| l.trim() == "\""),
"stray quote was orphaned in {output:?}",
);
}
#[test]
fn test_wrap_empty_url_link_is_not_split() {
let input = lines_vec![concat!(
"Inspect the placeholder []() inside a long paragraph that easily ",
"exceeds the eighty character wrap threshold for prose reflow."
)];
let output = process_stream(&input);
assert!(
output.iter().any(|l| l.contains("[]()")),
"empty-URL link should remain intact in {output:?}",
);
assert!(
!output.iter().any(|l| l.trim_start().starts_with("()")),
"the URL parentheses must not lead a wrapped line in {output:?}",
);
}
#[test]
fn test_wrap_link_with_unbalanced_parens_is_not_split() {
let input = lines_vec for additional ",
"context that pushes this paragraph beyond the eighty character limit."
)];
let output = process_stream(&input);
assert!(
output
.iter()
.any(|l| l.contains("[example](https://example.com/path(fragment)")),
"unbalanced-paren link should stay intact in {output:?}",
);
}
#[test]
fn test_wrap_link_at_exact_wrap_boundary_is_not_split() {
const WORD: &str = "Word ";
let prefix = WORD.repeat(WRAP_COLS / WORD.len());
assert_eq!(prefix.len() % WRAP_COLS, 0);
let link = "[boundary](https://example.com/wrap-boundary-test)";
let punct = ".";
let input = lines_vec![format!(
"{prefix}{link}{punct} trailing text to force wrapping here."
)];
let output = process_stream(&input);
let link_with_punct = format!("{link}{punct}");
assert!(
output.iter().any(|l| l == &link_with_punct),
"link with punctuation should appear as its own complete line at the wrap boundary; got \
{output:?}",
);
assert!(
!output.iter().any(|l| l.trim() == punct),
"trailing punctuation must not be orphaned onto its own line; got {output:?}",
);
}
#[rstest]
#[case(
"long_link_trailing_period",
lines_vec.",
)]
)]
#[case(
"multiple_trailing_marks",
lines_vec!? Additional words are added so this line ",
"exceeds the eighty character limit for wrapping."
)]
)]
#[case(
"colon_after_link",
lines_vec: an extended line that ensures the wrapping ",
"logic triggers because it exceeds eighty characters easily."
)]
)]
#[case(
"leading_quote_before_link",
lines_vec\" is important for understanding the ",
"overall design because it provides context to the guidelines."
)]
)]
#[case(
"leading_and_trailing_punctuation",
lines_vec!\" demonstrates punctuation around a link and ",
"includes plenty of extra words to exceed the wrapping limit."
)]
)]
fn snapshot_link_punctuation_wrapping(#[case] name: &str, #[case] input: Vec<String>) {
let rendered = process_stream(&input).join("\n");
insta::with_settings!({
description => format!("link punctuation wrapping: {name}"),
omit_expression => true,
}, {
assert_snapshot!(name, rendered);
});
}