use std::fs;
use tempfile::TempDir;
#[test]
fn test_exclude_patterns_with_explicit_paths() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let docs_dir = base_path.join("docs");
fs::create_dir(&docs_dir).unwrap();
let root_file = base_path.join("README.md");
let docs_file = docs_dir.join("guide.md");
fs::write(&root_file, "Some content without heading.\n").unwrap();
fs::write(&docs_file, "Some content without heading.\n").unwrap();
let pyproject_content = r#"
[tool.rumdl]
exclude = ["docs/*"]
"#;
fs::write(base_path.join("pyproject.toml"), pyproject_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_rumdl"))
.arg("check")
.arg(root_file.to_str().unwrap())
.arg(docs_file.to_str().unwrap())
.current_dir(base_path)
.output()
.expect("Failed to execute rumdl");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let combined = format!("{stdout}\n{stderr}");
assert!(
stderr.contains("warning:")
&& stderr.contains("docs/guide.md")
&& stderr.contains("ignored because of exclude pattern"),
"docs/guide.md should show exclusion warning. stderr:\n{stderr}"
);
assert!(
!stdout.contains("docs/guide.md"),
"docs/guide.md should not be in linting results. stdout:\n{stdout}"
);
assert!(
combined.contains("README.md"),
"README.md should be processed. Output:\n{combined}"
);
let output2 = std::process::Command::new(env!("CARGO_BIN_EXE_rumdl"))
.arg("check")
.arg(".")
.current_dir(base_path)
.output()
.expect("Failed to execute rumdl");
let stdout2 = String::from_utf8_lossy(&output2.stdout);
let stderr2 = String::from_utf8_lossy(&output2.stderr);
let combined2 = format!("{stdout2}\n{stderr2}");
assert!(
!combined2.contains("docs/guide.md"),
"docs/guide.md should be excluded in discovery mode. Output:\n{combined2}"
);
}
#[test]
fn test_force_exclude_with_explicit_paths() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let docs_dir = base_path.join("docs");
fs::create_dir(&docs_dir).unwrap();
let docs_file = docs_dir.join("guide.md");
fs::write(&docs_file, "# Guide\n\nSome content.\n").unwrap();
let pyproject_content = r#"
[tool.rumdl]
exclude = ["docs/*"]
force_exclude = true
"#;
fs::write(base_path.join("pyproject.toml"), pyproject_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_rumdl"))
.arg("check")
.arg(docs_file.to_str().unwrap())
.current_dir(base_path)
.output()
.expect("Failed to execute rumdl");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("warning:") && stderr.contains("ignored because of exclude pattern"),
"docs/guide.md should be excluded with warning. stderr: {stderr}"
);
assert!(
stdout.contains("No markdown files found") || stderr.contains("No markdown files found"),
"Should report no markdown files found when all are excluded. stdout: {stdout}, stderr: {stderr}"
);
}
#[test]
fn test_no_exclude_flag() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
let base_path = temp_dir.path();
let docs_dir = base_path.join("docs");
fs::create_dir(&docs_dir)?;
let docs_file = docs_dir.join("guide.md");
fs::write(&docs_file, "# Guide\n\nSome content.\n")?;
let pyproject_content = r#"
[tool.rumdl]
exclude = ["docs/*"]
"#;
fs::write(base_path.join("pyproject.toml"), pyproject_content)?;
let output = std::process::Command::new(env!("CARGO_BIN_EXE_rumdl"))
.arg("check")
.arg(docs_file.to_str().unwrap())
.arg("--no-exclude")
.current_dir(base_path)
.output()
.expect("Failed to execute rumdl");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.contains("warning:") && !stderr.contains("ignored because of exclude pattern"),
"Should not show exclusion warning with --no-exclude. stderr: {stderr}"
);
assert!(
stdout.contains("Success") || stdout.contains("No issues found"),
"Should report linting success. stdout: {stdout}"
);
Ok(())
}
#[test]
fn test_cli_exclude_overrides_config() {
let temp_dir = TempDir::new().unwrap();
let base_path = temp_dir.path();
let docs_dir = base_path.join("docs");
let tests_dir = base_path.join("tests");
fs::create_dir(&docs_dir).unwrap();
fs::create_dir(&tests_dir).unwrap();
let docs_file = docs_dir.join("guide.md");
let tests_file = tests_dir.join("test.md");
fs::write(&docs_file, "# Guide\n\nSome content.\n").unwrap();
fs::write(&tests_file, "# Test\n\nSome content.\n").unwrap();
let pyproject_content = r#"
[tool.rumdl]
exclude = ["docs/*"]
"#;
fs::write(base_path.join("pyproject.toml"), pyproject_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_rumdl"))
.arg("check")
.arg("--exclude")
.arg("tests/*")
.arg(docs_file.to_str().unwrap())
.arg(tests_file.to_str().unwrap())
.current_dir(base_path)
.output()
.expect("Failed to execute rumdl");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("warning:")
&& stderr.contains("tests/test.md")
&& stderr.contains("ignored because of exclude pattern"),
"tests/test.md should show exclusion warning. stderr: {stderr}"
);
assert!(
!stdout.contains("tests/test.md"),
"tests/test.md should not be in linting results. stdout: {stdout}"
);
assert!(output.status.success() || output.status.code() == Some(1));
}