#[path = "support/mod.rs"]
mod support;
use std::path::Path;
use proptest::prelude::*;
use support::scan_fixture;
proptest! {
#[test]
fn go_parser_never_panics(source in ".*") {
let _ = deslop::validate_source(Path::new("arb.go"), &source);
}
#[test]
fn python_parser_never_panics(source in ".*") {
let _ = deslop::validate_source(Path::new("arb.py"), &source);
}
#[test]
fn rust_parser_never_panics(source in ".*") {
let _ = deslop::validate_source(Path::new("arb.rs"), &source);
}
}
macro_rules! positive_fixture_invariant {
($test_name:ident, $fixture_path:literal, $target_path:literal) => {
#[test]
fn $test_name() {
let report = scan_fixture($fixture_path, $target_path);
assert!(
!report.findings.is_empty(),
"positive fixture '{}' should produce at least one finding",
$fixture_path
);
}
};
}
positive_fixture_invariant!(
go_error_handling_slop_has_findings,
"go/error_handling_slop.txt",
"error_handling_slop.go"
);
positive_fixture_invariant!(
go_context_cancel_slop_has_findings,
"go/context_cancel_slop.txt",
"context_cancel_slop.go"
);
positive_fixture_invariant!(
go_concurrency_slop_has_findings,
"go/concurrency_slop.txt",
"concurrency_slop.go"
);
positive_fixture_invariant!(
go_busy_waiting_slop_has_findings,
"go/busy_waiting_slop.txt",
"busy_waiting_slop.go"
);
positive_fixture_invariant!(
go_db_query_slop_has_findings,
"go/db_query_slop.txt",
"db_query_slop.go"
);
positive_fixture_invariant!(
python_rule_pack_positive_has_findings,
"python/rule_pack_positive.txt",
"rule_pack_positive.py"
);
positive_fixture_invariant!(
python_phase4_positive_has_findings,
"python/phase4_positive.txt",
"phase4_positive.py"
);
positive_fixture_invariant!(
rust_rule_pack_positive_has_findings,
"rust/rule_pack_positive.txt",
"rule_pack_positive.rs"
);
positive_fixture_invariant!(
rust_direct_call_hallucination_positive_has_findings,
"rust/direct_call_hallucination_positive.txt",
"direct_call_hallucination_positive.rs"
);
#[test]
fn go_zero_findings_baseline_produces_no_findings() {
let findings = scan_fixture("go/zero_findings_baseline.txt", "zero_findings_baseline.go")
.findings
.into_iter()
.map(|finding| finding.rule_id)
.collect::<Vec<_>>();
assert!(
findings.is_empty(),
"zero-findings Go baseline produced unexpected findings: {findings:?}"
);
}
#[test]
fn python_zero_findings_baseline_produces_no_findings() {
let findings = scan_fixture(
"python/zero_findings_baseline.txt",
"zero_findings_baseline.py",
)
.findings
.into_iter()
.map(|finding| finding.rule_id)
.collect::<Vec<_>>();
assert!(
findings.is_empty(),
"zero-findings Python baseline produced unexpected findings: {findings:?}"
);
}
#[test]
fn rust_zero_findings_baseline_produces_no_findings() {
let findings = scan_fixture(
"rust/zero_findings_baseline.txt",
"zero_findings_baseline.rs",
)
.findings
.into_iter()
.map(|finding| finding.rule_id)
.collect::<Vec<_>>();
assert!(
findings.is_empty(),
"zero-findings Rust baseline produced unexpected findings: {findings:?}"
);
}
#[test]
fn scan_results_contain_no_duplicate_findings() {
let report = scan_fixture("go/error_handling_slop.txt", "dedup_check.go");
let mut seen = std::collections::BTreeSet::new();
for f in &report.findings {
let key = (f.start_line, f.rule_id.clone());
assert!(
seen.insert(key.clone()),
"duplicate finding detected: rule='{}' at line {}",
key.1,
key.0
);
}
}