use std::fs;
use std::process::Command;
use tempfile::tempdir;
const STYLE_CONFIGS: &[(&str, &str, &[&str])] = &[
(
"MD003",
"style",
&[
"atx",
"atx_closed",
"consistent",
"setext_with_atx",
"setext_with_atx_closed",
],
),
("MD046", "style", &["fenced", "indented", "consistent"]),
("MD048", "style", &["backtick", "tilde", "consistent"]),
("MD049", "style", &["asterisk", "underscore", "consistent"]),
("MD050", "style", &["asterisk", "underscore", "consistent"]),
(
"MD055",
"style",
&[
"consistent",
"leading-only",
"trailing-only",
"leading-and-trailing",
"no-leading-or-trailing",
],
),
(
"MD060",
"style",
&["aligned", "aligned-no-space", "compact", "tight", "any"],
),
("MD063", "style", &["title_case", "sentence_case", "all_caps"]),
];
fn generate_variants(canonical: &str) -> Vec<(String, String)> {
let mut variants = vec![];
variants.push(("canonical".to_string(), canonical.to_string()));
variants.push(("UPPERCASE".to_string(), canonical.to_uppercase()));
if canonical.contains('_') {
let kebab = canonical.replace('_', "-");
variants.push(("kebab-case".to_string(), kebab.clone()));
variants.push(("KEBAB-UPPER".to_string(), kebab.to_uppercase()));
}
if canonical.contains('-') {
let snake = canonical.replace('-', "_");
variants.push(("snake_case".to_string(), snake.clone()));
variants.push(("SNAKE_UPPER".to_string(), snake.to_uppercase()));
}
variants
}
fn rumdl_binary() -> String {
let output = Command::new("cargo")
.args(["build", "--quiet"])
.output()
.expect("Failed to build rumdl");
assert!(
output.status.success(),
"cargo build failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let manifest_dir = env!("CARGO_MANIFEST_DIR");
format!("{manifest_dir}/target/debug/rumdl")
}
#[test]
fn test_all_style_configs_accept_variant_forms() {
let binary = rumdl_binary();
let temp_dir = tempdir().expect("Failed to create temporary directory");
let md_file = temp_dir.path().join("test.md");
fs::write(&md_file, "# Test\n\nSome content.\n").expect("Failed to write markdown file");
let mut failures = Vec::new();
for (rule_name, field_name, canonical_values) in STYLE_CONFIGS {
for canonical in *canonical_values {
for (variant_desc, variant_value) in generate_variants(canonical) {
let config_content = format!("[{rule_name}]\n{field_name} = \"{variant_value}\"\n");
let config_path = temp_dir.path().join(".rumdl.toml");
fs::write(&config_path, &config_content).expect("Failed to write config");
let output = Command::new(&binary)
.args([
"check",
"--no-cache",
"--config",
config_path.to_str().unwrap(),
md_file.to_str().unwrap(),
])
.output()
.expect("Failed to run rumdl");
let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("Invalid configuration")
|| stderr.contains("unknown variant")
|| stderr.contains("Invalid")
{
failures.push(format!(
"{rule_name}.{field_name} = \"{variant_value}\" ({variant_desc} of \"{canonical}\"): {stderr}"
));
}
}
}
}
if !failures.is_empty() {
panic!(
"Style configuration normalization failures ({} total):\n\n{}",
failures.len(),
failures.join("\n\n")
);
}
}