use rumdl_lib::lint_context::LintContext;
use rumdl_lib::rule::Rule;
use rumdl_lib::rules::MD052ReferenceLinkImages;
#[test]
fn test_valid_reference_link() {
let rule = MD052ReferenceLinkImages::new();
let content = "[example][id]\n\n[id]: http://example.com";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_valid_reference_links_multiple() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is a [link][ref1] and another [link][ref2].
[ref1]: http://example.com/1
[ref2]: http://example.com/2"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_invalid_reference_link() {
let rule = MD052ReferenceLinkImages::new();
let content = "[example][id]\n\n[other]: http://example.com";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'id' not found");
}
#[test]
fn test_missing_multiple_definitions() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[link1][ref1]
[link2][ref2]
[link3][ref3]
[ref1]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 2);
}
#[test]
fn test_invalid_reference_image() {
let rule = MD052ReferenceLinkImages::new();
let content = "![example][id]\n\n[other]: http://example.com/image.jpg";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'id' not found");
}
#[test]
fn test_valid_reference_image() {
let rule = MD052ReferenceLinkImages::new();
let content = "![example][id]\n\n[id]: http://example.com/image.jpg";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_case_insensitive() {
let rule = MD052ReferenceLinkImages::new();
let content = "[example][ID]\n\n[id]: http://example.com";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_case_insensitive_mixed() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[Link 1][REF]
[Link 2][Ref]
[Link 3][ref]
[ReF]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_full_reference_link() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is a [full reference link][label].
[label]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_full_reference_link_missing() {
let rule = MD052ReferenceLinkImages::new();
let content = "This is a [full reference link][label].";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'label' not found");
}
#[test]
fn test_collapsed_reference_link() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is a [collapsed reference][] link.
[collapsed reference]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_collapsed_reference_link_missing() {
let rule = MD052ReferenceLinkImages::new();
let content = "This is a [collapsed reference][] link.";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'collapsed reference' not found");
}
#[test]
fn test_shortcut_reference() {
let rule = MD052ReferenceLinkImages::new();
let content = "[example]\n\n[example]: http://example.com";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_invalid_shortcut_reference() {
let rule = MD052ReferenceLinkImages::new();
let content = "[example]\n\n[other]: http://example.com";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 0, "Shortcut references are not checked by default");
}
#[test]
fn test_shortcut_vs_inline_link() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is an [inline link](http://example.com) and a [shortcut].
[shortcut]: http://example.com/shortcut"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_multiple_references_same_definition() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"First [reference][same]
Second [reference][same]
Third [reference][same]
[same]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_multiple_references_same_undefined() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"First [reference][missing]
Second [reference][missing]
Third [reference][missing]"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'missing' not found");
}
#[test]
fn test_escaped_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is \[not a link\] and neither is \[this\].
These are real links: [link1][ref1] and [link2][ref2]
But this \[text][undefined] has [undefined] as a reference link.
[ref1]: http://example.com/1
[ref2]: http://example.com/2
[undefined]: http://example.com/undefined"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_partially_escaped_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is \[escaped text][ref] where [ref] needs definition.
[ref]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_escaped_brackets_with_undefined_ref() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is \[escaped][undefined] but undefined is not defined."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 0);
let content2 = r#"This is \[escaped] and [undefined] but undefined is not defined."#;
let ctx2 = LintContext::new(content2, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result2 = rule.check(&ctx2).unwrap();
assert_eq!(result2.len(), 0, "Shortcut references are not checked by default");
}
#[test]
fn test_escaped_image_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is \![not an image][ref] and neither is \![this][ref].
This is a real image: ![image][ref]
[ref]: http://example.com/image.jpg"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_references_at_beginning() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[ref1]: http://example.com/1
[ref2]: http://example.com/2
# Document
Using [link1][ref1] and [link2][ref2]."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_references_in_middle() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"# Document
Using [link1][ref1] here.
[ref1]: http://example.com/1
[ref2]: http://example.com/2
And [link2][ref2] here."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_references_at_end() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"# Document
Using [link1][ref1] and [link2][ref2].
More text here.
[ref1]: http://example.com/1
[ref2]: http://example.com/2"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_mixed_reference_types() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"Full: [text][full]
Collapsed: [collapsed][]
Shortcut: [shortcut]
Image: ![alt][image]
[full]: http://example.com/full
[collapsed]: http://example.com/collapsed
[shortcut]: http://example.com/shortcut
[image]: http://example.com/image.jpg"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_code_blocks_ignored() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"```
[undefined][ref] should be ignored in code blocks
```
[real][ref] should be checked
[ref]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_inline_links_not_checked() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[Inline link](http://example.com) should not be checked.
 should not be checked.
But [reference][undefined] should be checked."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'undefined' not found");
}
#[test]
fn test_list_items_excluded() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"- [x] This is a task list item
* [ ] Another task list item
+ [X] Yet another one
But this [reference][undefined] should still be checked."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
}
#[test]
fn test_complex_document() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"# Document Title
This document has [valid links][link1] and ![valid images][img1].
## Section with undefined references
Here's an [undefined link][broken] and an ![undefined image][missing].
```markdown
[This][should] be ignored in code blocks
```
## Mixed references
- Full reference: [Full][ref1]
- Collapsed: [ref2][]
- Shortcut: [ref3]
- Case insensitive: [Link][REF4]
[link1]: http://example.com/link1
[img1]: http://example.com/image1.jpg
[ref1]: http://example.com/ref1
[ref2]: http://example.com/ref2
[ref3]: http://example.com/ref3
[ref4]: http://example.com/ref4"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 2);
let messages: Vec<String> = result.iter().map(|w| w.message.clone()).collect();
assert!(messages.contains(&"Reference 'broken' not found".to_string()));
assert!(messages.contains(&"Reference 'missing' not found".to_string()));
}
#[test]
fn test_empty_content() {
let rule = MD052ReferenceLinkImages::new();
let content = "";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_no_references() {
let rule = MD052ReferenceLinkImages::new();
let content = "# Just a heading\n\nSome regular text\n\n> A blockquote";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_empty_reference_label() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is a [link text][] reference.
[link text]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_empty_reference_label_undefined() {
let rule = MD052ReferenceLinkImages::new();
let content = "This is a [link text][] reference.";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].message, "Reference 'link text' not found");
}
#[test]
fn test_reference_with_special_chars() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"Link with [special-chars_123][ref-with_special.chars].
[ref-with_special.chars]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_reference_in_nested_structures() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"> Blockquote with [reference][ref1]
> > Nested blockquote with [another][ref2]
- List item with [reference][ref3]
- Nested list with [reference][ref4]
| Table | With [reference][ref5] |
|-------|------------------------|
| Cell | [reference][ref6] |
[ref1]: http://example.com/1
[ref2]: http://example.com/2
[ref3]: http://example.com/3
[ref4]: http://example.com/4
[ref5]: http://example.com/5
[ref6]: http://example.com/6"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_reference_definitions_with_titles() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[link1][ref1] and [link2][ref2] and [link3][ref3].
[ref1]: http://example.com "Title in double quotes"
[ref2]: http://example.com 'Title in single quotes'
[ref3]: http://example.com (Title in parentheses)"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_multiline_reference_links() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is a [multiline
link text][ref] that spans lines.
[ref]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_adjacent_reference_links() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[link1][ref1][link2][ref2] with no space between.
[ref1]: http://example.com/1
[ref2]: http://example.com/2"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_reference_definition_indentation() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[link1][ref1] [link2][ref2] [link3][ref3] [link4][ref4]
[ref1]: http://example.com/1
[ref2]: http://example.com/2
[ref3]: http://example.com/3
[ref4]: http://example.com/4"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_reference_definition_too_indented() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[link][ref]
[ref]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"4-space-indented reference definition is inside a code block and should not be recognized"
);
assert!(
result[0].message.contains("ref"),
"Should report undefined reference 'ref'"
);
}
#[test]
fn test_output_example_section_ignored() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"[valid][ref]
## Output Example
[undefined][example] should be ignored in output sections.
## Regular Section
[undefined2][missing] should be caught here.
[ref]: http://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
for (i, warning) in result.iter().enumerate() {
println!("Warning {}: {} at line {}", i, warning.message, warning.line);
}
assert_eq!(result.len(), 2); let messages: Vec<String> = result.iter().map(|w| w.message.clone()).collect();
assert!(messages.contains(&"Reference 'example' not found".to_string()));
assert!(messages.contains(&"Reference 'missing' not found".to_string()));
}
#[test]
fn test_shortcut_reference_with_nested_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This is [`Union[T, None]`] text.
[`union[t, none]`]: https://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should handle nested brackets in shortcut references"
);
}
#[test]
fn test_reference_definition_with_nested_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"See [`dataclasses.InitVar`] for details.
[`dataclasses.initvar`]: https://docs.python.org/3/library/dataclasses.html#dataclasses.InitVar"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should handle nested brackets in reference definitions"
);
}
#[test]
fn test_complex_nested_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"The [`typing.Optional[T]`] type is equivalent to [`Union[T, None]`].
For arrays use [`List[int]`] or [`Array[str, 10]`].
[`typing.optional[t]`]: https://example.com/optional
[`union[t, none]`]: https://example.com/union
[`list[int]`]: https://example.com/list
[`array[str, 10]`]: https://example.com/array"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty(), "Should handle all complex nested bracket cases");
}
#[test]
fn test_undefined_reference_with_nested_brackets() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"This [`Dict[str, Any]`] is undefined.
[`list[int]`]: https://example.com"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Type annotations should not be flagged as undefined references"
);
}
#[test]
fn test_issue_81_toml_code_block_not_parsed() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"## Adding new examples
1. Create a new Rust file under `src`.
2. Add the binary definition to the `Cargo.toml` file, the list is ordered alphabetically by example name:
```toml
[[bin]]
name = "tracing-subscriber"
path = "src/tracing_subscriber.rs"
test = false
```
3. Add any required dependencies to the `Cargo.toml` file."#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag [[bin]] in TOML code block as undefined reference (issue #81)"
);
}
#[test]
fn test_mkdocs_backtick_wrapped_auto_references() {
let rule = MD052ReferenceLinkImages::new();
let content = "[`module.Class`][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag [`module.Class`][] as undefined reference in MkDocs mode (issue #97). Got: {result:?}"
);
let content = "[`module.Class`][ref]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag [`module.Class`][ref] as undefined reference in MkDocs mode (issue #97). Got: {result:?}"
);
let content = "[`api/endpoint`][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag [`api/endpoint`][] as undefined reference in MkDocs mode (issue #97). Got: {result:?}"
);
let content = "See [`module.func`][], [`package.Class`][], and [`api/endpoint`][] for details.";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag multiple backtick-wrapped auto-references in MkDocs mode (issue #97). Got: {result:?}"
);
let content = "[`module.Class`][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should flag [`module.Class`][] as undefined reference in Standard mode (no auto-refs). Got: {result:?}"
);
let content = "[undefined_reference][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should still flag [undefined_reference][] as undefined in MkDocs mode. Got: {result:?}"
);
let content = "![`module.Class`][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag backtick-wrapped image references in MkDocs mode (issue #97). Got: {result:?}"
);
let content = "[`str`][]";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag [`str`][] as undefined reference in MkDocs mode (issue #97 example). Got: {result:?}"
);
let content = "See [`str`][], [`int`][], and [`bool`][] for details.";
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::MkDocs, None);
let result = rule.check(&ctx).unwrap();
assert!(
result.is_empty(),
"Should not flag single-word backtick-wrapped identifiers in MkDocs mode (issue #97). Got: {result:?}"
);
}
#[test]
fn test_issue_114_code_block_in_quote() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"```rust
#[derive(Debug)]
struct Ok;
```
> ```rust
> #[derive(Debug)]
> struct NotOk;
> ```
"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should not flag [derive(Debug)] inside code blocks (even in block quotes) as undefined references. Got: {result:?}"
);
}
#[test]
fn test_code_block_in_quote_various_patterns() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"Regular code block:
```rust
let x = vec![1, 2, 3];
```
> Code block in quote:
> ```rust
> let y = vec![4, 5, 6];
> #[derive(Debug)]
> struct Foo;
> ```
> Another blockquote
> ```python
> data = {"key": [1, 2, 3]}
> ```
"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should not flag brackets inside code blocks within blockquotes. Got: {result:?}"
);
}
#[test]
fn test_actual_reference_in_quote_outside_code() {
let rule = MD052ReferenceLinkImages::new();
let content = r#"> This is a [reference] in a blockquote
>
> ```rust
> #[derive(Debug)]
> struct Foo;
> ```
"#;
let ctx = LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Shortcut references are not checked by default, and code block content should be ignored. Got: {result:?}"
);
}