use crate::{run_command, rust_fixture_dir};
use rust_llm_tidy::languages::LanguageBackend;
use std::fs;
mod doc001_missing_docs;
mod doc002_missing_errors_section;
mod doc003_vague_errors;
mod doc004_missing_arguments;
mod doc005_undocumented_param;
mod doc006_placeholder;
mod doc008_error_variant_order;
mod doc009_missing_module_docs;
mod len001_method_length;
mod mod001_module_size;
mod mod003_qualified_path;
mod perf001_allocation_hints;
mod test001_test_naming;
mod test002_test_summary;
mod text001_paragraph_size;
mod text002_line_length;
mod text003_sentence_length;
mod text004_header_opener;
#[test]
fn clean_file_no_diagnostics() {
let (stderr, exit) = run_rust_fixture("clean.rs", "lints");
assert_eq!(exit, 0, "clean file should pass");
assert!(
stderr.is_empty(),
"clean file should produce no diagnostics, got:\n{stderr}"
);
}
#[test]
fn rs_diagnostics_match_direct_check_composition() {
for name in [
"doc001_missing_docs.rs",
"text-001_text-002_block_attr_budgets.rs",
"doc001_doc002_doc004_text002_mixed.rs",
] {
let path = rust_fixture_dir().join(name);
let source = fs::read_to_string(&path).unwrap();
let output = run_command(
&[
"--include",
"lints",
"--include",
"TEXT007",
"--output-mode",
"json",
],
&path,
);
let stdout = String::from_utf8_lossy(&output.stdout);
let rendered: Vec<(usize, String, String)> =
serde_json::from_str::<serde_json::Value>(&stdout)
.expect("JSON diagnostics must parse")
.as_array()
.expect("diagnostics must be an array")
.iter()
.map(|f| {
(
f["line"].as_u64().expect("line must be a number") as usize,
f["severity"].as_str().expect("severity").to_string(),
f["code"].as_str().expect("code").to_string(),
)
})
.collect();
let parsed = rust_llm_tidy::languages::RustBackend
.parse(&source)
.unwrap();
let expected = rust_llm_tidy::languages::rust::RustBackend.lint(&parsed);
let expected: Vec<(usize, String, String)> = expected
.iter()
.map(|d| {
let sev = match d.severity {
rust_llm_tidy::reporting::Severity::Error => "error",
rust_llm_tidy::reporting::Severity::Warning => "warning",
rust_llm_tidy::reporting::Severity::Hint => "hint",
rust_llm_tidy::reporting::Severity::Reminder => "reminder",
};
(d.line, sev.to_string(), d.code.to_string())
})
.collect();
assert_eq!(
rendered, expected,
"{name}: CLI rs dispatch must render exactly the backend lint composition"
);
}
}
fn run_rust_fixture(name: &str, codes: &str) -> (String, i32) {
let path = rust_fixture_dir().join(name);
let args: Vec<_> = codes
.split(',')
.flat_map(|code| ["--include", code])
.collect();
let output = run_command(&args, &path);
(
String::from_utf8_lossy(&output.stderr).to_string(),
output.status.code().unwrap_or(-1),
)
}