use rumdl_lib::rule::Rule;
use rumdl_lib::rules::MD044ProperNames;
#[test]
fn test_correct_names() {
let names = vec!["JavaScript".to_string(), "TypeScript".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "# Guide to JavaScript and TypeScript\n\nJavaScript is awesome!";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_incorrect_names() {
let names = vec!["JavaScript".to_string(), "TypeScript".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "# Guide to javascript and typescript\n\njavascript is awesome!";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 3);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "# Guide to JavaScript and TypeScript\n\nJavaScript is awesome!");
}
#[test]
fn test_code_block_excluded() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false); let content = "# JavaScript Guide\n\n```javascript\nconst x = 'javascript';\n```";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_code_block_included() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, true); let content = "# JavaScript Guide\n\n```javascript\nconst x = 'javascript';\n```";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert!(!result.is_empty(), "Should detect 'javascript' in the code block");
let fixed = rule.fix(&ctx).unwrap();
assert!(
fixed.contains("const x = 'JavaScript';"),
"Should replace 'javascript' with 'JavaScript' in code blocks"
);
}
#[test]
fn test_indented_code_block() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false); let content = "# JavaScript Guide\n\n const x = 'javascript';\n console.log(x);";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
if !result.is_empty() {
eprintln!("Test failed - found violations:");
for warning in &result {
eprintln!(" Line {}: {}", warning.line, warning.message);
}
eprintln!("Code blocks detected: {:?}", ctx.code_blocks);
eprintln!("Content: {content:?}");
let mut byte_pos = 0;
for (i, line) in content.lines().enumerate() {
eprintln!(
"Line {}: byte_pos={}, in_code_block={}, content={:?}",
i + 1,
byte_pos,
ctx.is_in_code_block_or_span(byte_pos),
line
);
byte_pos += line.len() + 1;
}
}
assert!(result.is_empty());
}
#[test]
fn test_multiple_occurrences() {
let names = vec!["JavaScript".to_string(), "Node.js".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "javascript with nodejs\njavascript and nodejs again";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
println!("Number of warnings: {}", result.len());
for (i, warning) in result.iter().enumerate() {
println!(
"Warning {}: Line {}, Column {}, Message: {}",
i + 1,
warning.line,
warning.column,
warning.message
);
}
assert!(!result.is_empty(), "Should detect multiple improper names");
let fixed = rule.fix(&ctx).unwrap();
println!("Original content: '{content}'");
println!("Fixed content: '{fixed}'");
assert!(
fixed.contains("JavaScript"),
"Should replace 'javascript' with 'JavaScript'"
);
assert!(fixed.contains("Node.js"), "Should replace 'nodejs' with 'Node.js'");
}
#[test]
fn test_word_boundaries() {
let names = vec!["Git".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "Using git and github with gitflow";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1); let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "Using Git and github with gitflow");
}
#[test]
fn test_fix_multiple_on_same_line() {
let names = vec!["Rust".to_string(), "Cargo".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "Using rust and cargo is fun. rust is fast.";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "Using Rust and Cargo is fun. Rust is fast.");
}
#[test]
fn test_fix_adjacent_to_markdown() {
let names = vec!["Markdown".to_string()];
let rule = MD044ProperNames::new(names, false); let content = "*markdown* _markdown_ `markdown` [markdown](link)";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "*Markdown* _Markdown_ `markdown` [Markdown](link)");
}
#[test]
fn test_fix_with_dots() {
let names = vec!["Node.js".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "Using node.js or sometimes nodejs.";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "Using Node.js or sometimes Node.js.");
}
#[test]
fn test_fix_code_block_included() {
let names = vec!["Rust".to_string()];
let rule = MD044ProperNames::new(names, true); let content = "```rust\nlet lang = \"rust\";\n```\n\nThis is rust code.";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "```rust\nlet lang = \"Rust\";\n```\n\nThis is Rust code.");
}
#[test]
fn test_code_fence_language_identifiers_preserved() {
let names = vec!["Rust".to_string(), "Python".to_string(), "JavaScript".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = r#"```rust
// This is rust code
let rust = "rust";
```
```python
# This is python code
python = "python"
```
```javascript
// This is javascript code
const javascript = "javascript";
```"#;
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert!(fixed.contains("```rust"), "rust identifier should stay lowercase");
assert!(fixed.contains("```python"), "python identifier should stay lowercase");
assert!(
fixed.contains("```javascript"),
"javascript identifier should stay lowercase"
);
assert!(
fixed.contains("let Rust = \"Rust\""),
"Variable names should be capitalized"
);
assert!(
fixed.contains("# This is Python code"),
"Comments should be capitalized"
);
assert!(
fixed.contains("Python = \"Python\""),
"Variable names should be capitalized"
);
assert!(
fixed.contains("const JavaScript = \"JavaScript\""),
"Variable names should be capitalized"
);
}
#[test]
fn test_tilde_fence_language_identifiers() {
let names = vec!["Ruby".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "~~~ruby\nputs 'ruby'\n~~~";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert!(
fixed.contains("~~~ruby"),
"Tilde fence identifier should stay lowercase"
);
assert!(fixed.contains("puts 'Ruby'"), "Content should be capitalized");
}
#[test]
fn test_fence_with_attributes() {
let names = vec!["JSON".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "```json {highlight: [2]}\n{\n \"json\": \"value\"\n}\n```";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert!(
fixed.contains("```json {highlight: [2]}"),
"Fence with attributes preserved"
);
assert!(fixed.contains("\"JSON\""), "Content should be capitalized");
}
#[test]
fn test_mixed_fence_types() {
let names = vec!["Go".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "```go\nfmt.Println(\"go\")\n```\n\n~~~go\nfmt.Println(\"go\")\n~~~";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert!(fixed.contains("```go"), "Backtick fence preserved");
assert!(fixed.contains("~~~go"), "Tilde fence preserved");
assert_eq!(fixed.matches("\"Go\"").count(), 2, "Both contents capitalized");
}
#[test]
fn test_html_comments() {
let names = vec!["JavaScript".to_string(), "TypeScript".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "# JavaScript Guide\n\n<!-- javascript and typescript are mentioned here -->\n\nJavaScript is great!";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
2,
"Should detect 'javascript' and 'typescript' in HTML comments by default"
);
let fixed = rule.fix(&ctx).unwrap();
assert!(
fixed.contains("<!-- JavaScript and TypeScript are mentioned here -->"),
"Should fix names in HTML comments by default"
);
}
#[test]
fn test_html_comments_backtick_code_skipped() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- Use javascript here -->\n<!-- Use `javascript` here -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should only flag 'javascript' in non-backtick HTML comment, got: {result:?}",
);
assert_eq!(result[0].line, 3);
}
#[test]
fn test_html_comments_double_backtick_code_skipped() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- This is a ``javascript`` command. -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip name inside double backticks in HTML comment"
);
}
#[test]
fn test_html_comments_unclosed_backtick_not_code() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- This is a `javascript command. -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1, "Unclosed backtick should not suppress the violation");
}
#[test]
fn test_html_comments_multiple_code_spans() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- `javascript` and `javascript` are both code -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 0, "Both backtick-wrapped occurrences should be skipped");
}
#[test]
fn test_html_comments_mixed_code_and_prose() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- javascript and `javascript` in same comment -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1, "Should only flag the non-backtick occurrence");
}
#[test]
fn test_regular_markdown_backticks_still_work() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\nThis is javascript and `javascript` in backticks.";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1, "Regular markdown backtick handling should still work");
}
#[test]
fn test_html_block_backtick_code_skipped() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<div>\nUse javascript here and `javascript` in backticks.\n</div>";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should only flag bare name in HTML block, not backtick-wrapped"
);
}
#[test]
fn test_html_comments_backtick_code_blocks_true() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, true);
let content = "# Heading\n\n<!-- Use `javascript` here -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"With code_blocks=true, backtick-wrapped text should still be flagged"
);
}
#[test]
fn test_html_comments_backtick_autofix() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- Use javascript here and `javascript` in backticks. -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(
fixed,
"# Heading\n\n<!-- Use JavaScript here and `javascript` in backticks. -->"
);
}
#[test]
fn test_html_comments_multiline_with_backticks() {
let names = vec!["JavaScript".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!--\nUse javascript here.\nUse `javascript` as code.\n-->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(result.len(), 1, "Should only flag bare name in multi-line HTML comment");
assert_eq!(result[0].line, 4);
}
#[test]
fn test_html_comments_inline_link_url_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\nThis is a Test.\n\n<!-- For more information, see the [relevant page](test.md). -->\n<!-- For more information, see `test.md` -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should not flag names inside link URLs in HTML comments. Got: {result:?}",
);
}
#[test]
fn test_html_comments_inline_link_text_still_flagged() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- See the [test page](docs.md) for details -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should flag improper name in link text within HTML comments. Got: {result:?}",
);
}
#[test]
fn test_html_comments_multiple_inline_links() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- [a](test.md) and [b](test2.md) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in multiple link URLs. Got: {result:?}",
);
}
#[test]
fn test_html_comments_link_with_title() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- [page](test.md \"test title\") -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in link URL with title. Got: {result:?}",
);
}
#[test]
fn test_html_comments_relative_link_paths() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- See [page](../test/file.md) and [other](./test.md) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in relative link paths. Got: {result:?}",
);
}
#[test]
fn test_html_block_inline_link_url_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<div>\nSee [relevant page](test.md) for details.\n</div>";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in link URLs inside HTML blocks. Got: {result:?}",
);
}
#[test]
fn test_regular_markdown_link_url_still_handled() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\nSee [relevant page](test.md) for details.";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Regular Markdown link URLs should still be skipped. Got: {result:?}",
);
}
#[test]
fn test_html_comments_not_a_link() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- test is mentioned here -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Bare name in HTML comment should still be flagged. Got: {result:?}",
);
}
#[test]
fn test_html_comments_inline_link_autofix() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- See the [test page](test.md) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let fixed = rule.fix(&ctx).unwrap();
assert_eq!(fixed, "# Heading\n\n<!-- See the [Test page](test.md) -->",);
}
#[test]
fn test_html_comments_image_link_url_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!--  -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in image URLs in HTML comments. Got: {result:?}",
);
}
#[test]
fn test_html_comments_multiline_with_link() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!--\nFor details, see [the guide](test.md).\n-->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in link URLs in multi-line HTML comments. Got: {result:?}",
);
}
#[test]
fn test_html_comments_link_with_nested_brackets() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- [see [this] page](test.md) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should handle nested brackets in link text and skip URL. Got: {result:?}",
);
}
#[test]
fn test_html_comments_link_with_balanced_parens_in_url() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- [page](https://example.com/test_(section)) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should handle balanced parentheses in URLs. Got: {result:?}",
);
}
#[test]
fn test_html_comments_reference_link_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- See the [relevant page][test-ref] for details -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in reference link labels in HTML comments. Got: {result:?}",
);
}
#[test]
fn test_html_comments_reference_link_text_still_flagged() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- See the [test page][ref] for details -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should flag improper name in reference link text. Got: {result:?}",
);
}
#[test]
fn test_html_comments_mixed_link_styles() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- [page](test.md) and [other][test-ref] -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in both inline and reference link URLs. Got: {result:?}",
);
}
#[test]
fn test_frontmatter_inline_link_url_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "---\ndescription: See [relevant page](test.md) for details\n---\n\n# Heading\n";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in link URLs within frontmatter. Got: {result:?}",
);
}
#[test]
fn test_frontmatter_link_text_still_flagged() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "---\ndescription: See [test page](example.md) for details\n---\n\n# Heading\n";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
1,
"Should flag improper name in link text within frontmatter. Got: {result:?}",
);
}
#[test]
fn test_html_comments_double_escaped_bracket_link() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<!-- \\\\[page](test.md) -->";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in link URLs even with double-escaped preceding backslash. Got: {result:?}",
);
}
#[test]
fn test_html_block_reference_link_url_skipped() {
let names = vec!["Test".to_string()];
let rule = MD044ProperNames::new(names, false);
let content = "# Heading\n\n<div>\n[relevant page][test-ref]\n</div>\n";
let ctx = rumdl_lib::lint_context::LintContext::new(content, rumdl_lib::config::MarkdownFlavor::Standard, None);
let result = rule.check(&ctx).unwrap();
assert_eq!(
result.len(),
0,
"Should skip names in reference link labels in HTML blocks. Got: {result:?}",
);
}