#![allow(clippy::all)]
use super::*;
use crate::schema::{
Contract, EnforcementLevel, Equation, FalsificationTest, KaniHarness, Metadata,
VerificationSummary,
};
fn minimal_contract() -> Contract {
Contract {
metadata: Metadata {
version: "1".into(),
description: "test contract".into(),
..Default::default()
},
..Default::default()
}
}
fn make_falsification_test(id: &str, test_name: &str) -> FalsificationTest {
FalsificationTest {
id: id.into(),
rule: "test rule".into(),
prediction: "test prediction".into(),
test: Some(test_name.into()),
if_fails: "investigate".into(),
}
}
fn make_kani_harness(id: &str) -> KaniHarness {
KaniHarness {
id: id.into(),
obligation: "test-obl".into(),
property: None,
bound: None,
strategy: None,
solver: None,
harness: None,
}
}
fn make_equation(
preconditions: Vec<&str>,
postconditions: Vec<&str>,
lean: Option<&str>,
) -> Equation {
Equation {
formula: "x + y".into(),
domain: None,
codomain: None,
invariants: vec![],
preconditions: preconditions.into_iter().map(String::from).collect(),
postconditions: postconditions.into_iter().map(String::from).collect(),
lean_theorem: lean.map(String::from),
float_tolerance: None,
assumes: None,
guarantees: None,
}
}
#[test]
fn test_collect_test_fns_finds_test_functions() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(
dir.path().join("example.rs"),
"fn test_basic_add() {}\nfn test_edge_case() {}\nfn prop_monotonic() {}\nfn helper_function() {}\n",
)
.unwrap();
let mut tests = HashSet::new();
collect_test_fns(dir.path(), &mut tests);
assert!(tests.contains("test_basic_add"));
assert!(tests.contains("test_edge_case"));
assert!(tests.contains("prop_monotonic"));
assert!(
!tests.contains("helper_function"),
"should not collect non-test functions"
);
}
#[test]
fn test_collect_test_fns_empty_dir() {
let dir = tempfile::tempdir().unwrap();
let mut tests = HashSet::new();
collect_test_fns(dir.path(), &mut tests);
assert!(tests.is_empty());
}
#[test]
fn test_collect_test_fns_nested_dirs() {
let dir = tempfile::tempdir().unwrap();
let sub = dir.path().join("submodule");
std::fs::create_dir_all(&sub).unwrap();
std::fs::write(sub.join("tests.rs"), "fn test_nested() {}\n").unwrap();
let mut tests = HashSet::new();
collect_test_fns(dir.path(), &mut tests);
assert!(tests.contains("test_nested"));
}
#[test]
fn test_collect_test_fns_ignores_non_rs_files() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("test.txt"), "fn test_fake() {}\n").unwrap();
std::fs::write(dir.path().join("test.py"), "def test_python(): pass\n").unwrap();
let mut tests = HashSet::new();
collect_test_fns(dir.path(), &mut tests);
assert!(tests.is_empty());
}
#[test]
fn test_collect_test_fns_extracts_name_correctly() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(
dir.path().join("lib.rs"),
" fn test_with_spaces() {\n fn test_inside_body() {}\n }\n",
)
.unwrap();
let mut tests = HashSet::new();
collect_test_fns(dir.path(), &mut tests);
assert!(tests.contains("test_with_spaces"));
assert!(tests.contains("test_inside_body"));
}
#[test]
fn test_verify_gate_all_tests_present() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(
src.join("lib.rs"),
"fn test_alpha() {}\nfn test_beta() {}\n",
)
.unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![
make_falsification_test("F-01", "test_alpha"),
make_falsification_test("F-02", "test_beta"),
];
let contracts = vec![("test-contract-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed);
assert!(findings.is_empty());
if let GateDetail::Verify {
total_refs,
existing,
missing,
} = result.detail
{
assert_eq!(total_refs, 2);
assert_eq!(existing, 2);
assert_eq!(missing, 0);
} else {
panic!("expected Verify detail");
}
}
#[test]
fn test_verify_gate_missing_test() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "fn test_alpha() {}\n").unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![
make_falsification_test("F-01", "test_alpha"),
make_falsification_test("F-02", "test_missing_fn"),
];
let contracts = vec![("test-contract-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(!result.passed, "gate should fail when test is missing");
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].rule_id, "PV-VER-001");
assert!(findings[0].message.contains("test_missing_fn"));
}
#[test]
fn test_verify_gate_gpu_test_is_warning_not_error() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "").unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_gpu_dispatch")];
let contracts = vec![("gpu-kernel-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed, "gate should pass for GPU-only warnings");
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].severity, RuleSeverity::Warning);
assert!(findings[0].message.contains("may require --features gpu"));
}
#[test]
fn test_verify_gate_skips_non_test_names() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "").unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "verify_something")];
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed);
assert!(findings.is_empty(), "non-test/prop names should be skipped");
}
#[test]
fn test_verify_gate_no_falsification_tests() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "").unwrap();
let c = minimal_contract();
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_verify_gate_test_with_module_path() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "fn test_foo() {}\n").unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test(
"F-01",
"my_module::submod::test_foo",
)];
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_verify_gate_test_name_with_quotes() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "fn test_quoted() {}\n").unwrap();
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "\"test_quoted\"")];
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_verify_gate(&contracts, dir.path());
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_enforce_gate_no_equations() {
let c = minimal_contract();
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(result.passed);
assert!(findings.is_empty());
if let GateDetail::Enforce {
equations_total, ..
} = result.detail
{
assert_eq!(equations_total, 0);
} else {
panic!("expected Enforce detail");
}
}
#[test]
fn test_enforce_gate_equation_with_all_fields() {
let mut c = minimal_contract();
c.equations.insert(
"softmax".to_string(),
make_equation(
vec!["input.len() > 0"],
vec!["result.sum() == 1.0"],
Some("Theorems.Softmax"),
),
);
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(result.passed);
assert!(findings.is_empty());
if let GateDetail::Enforce {
equations_total,
equations_with_pre,
equations_with_post,
equations_with_lean,
} = result.detail
{
assert_eq!(equations_total, 1);
assert_eq!(equations_with_pre, 1);
assert_eq!(equations_with_post, 1);
assert_eq!(equations_with_lean, 1);
} else {
panic!("expected Enforce detail");
}
}
#[test]
fn test_enforce_gate_equation_missing_preconditions() {
let mut c = minimal_contract();
c.equations.insert(
"silu".to_string(),
make_equation(vec![], vec!["result > 0"], Some("Theorems.Silu")),
);
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(
result.passed,
"missing preconditions are warnings, not errors"
);
let pre_findings: Vec<_> = findings
.iter()
.filter(|f| f.rule_id == "PV-ENF-001")
.collect();
assert_eq!(pre_findings.len(), 1);
assert!(pre_findings[0].message.contains("no preconditions"));
assert!(pre_findings[0].suggestion.is_some());
}
#[test]
fn test_enforce_gate_equation_missing_lean_theorem() {
let mut c = minimal_contract();
c.equations.insert(
"gelu".to_string(),
make_equation(vec!["x > 0"], vec!["y > 0"], None),
);
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(result.passed, "missing lean is a warning, not error");
let lean_findings: Vec<_> = findings
.iter()
.filter(|f| f.rule_id == "PV-ENF-002")
.collect();
assert_eq!(lean_findings.len(), 1);
assert!(lean_findings[0].message.contains("no lean_theorem"));
let suggestion = lean_findings[0].suggestion.as_deref().unwrap();
assert!(
suggestion.contains("Gelu"),
"expected capitalized 'Gelu' in suggestion: {suggestion}"
);
}
#[test]
fn test_enforce_gate_skips_registries() {
let mut c = minimal_contract();
c.metadata.registry = true;
c.equations.insert(
"registry_eq".to_string(),
make_equation(vec![], vec![], None),
);
let contracts = vec![("registry-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(result.passed);
assert!(findings.is_empty(), "registry contracts should be skipped");
}
#[test]
fn test_enforce_gate_multiple_equations_mixed() {
let mut c = minimal_contract();
c.equations.insert(
"eq_good".to_string(),
make_equation(vec!["x > 0"], vec!["y > 0"], Some("Theorems.Good")),
);
c.equations
.insert("eq_bad".to_string(), make_equation(vec![], vec![], None));
let contracts = vec![("mixed-v1".to_string(), c)];
let (result, findings) = run_enforce_gate(&contracts);
assert!(result.passed);
assert_eq!(findings.len(), 3);
}
#[test]
fn test_capitalize_first_normal() {
assert_eq!(capitalize_first("softmax"), "Softmax");
}
#[test]
fn test_capitalize_first_empty() {
assert_eq!(capitalize_first(""), "");
}
#[test]
fn test_capitalize_first_single_char() {
assert_eq!(capitalize_first("x"), "X");
}
#[test]
fn test_capitalize_first_already_capitalized() {
assert_eq!(capitalize_first("Foo"), "Foo");
}
#[test]
fn test_enforcement_level_gate_basic_contract_meets_basic() {
let mut c = minimal_contract(); c.metadata.enforcement_level = Some(EnforcementLevel::Basic);
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Basic);
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_enforcement_level_gate_basic_below_standard() {
let c = minimal_contract(); let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Standard);
let level_findings: Vec<_> = findings
.iter()
.filter(|f| f.message.contains("below required"))
.collect();
assert!(!level_findings.is_empty());
assert_eq!(result.name, "enforcement-level");
}
#[test]
fn test_enforcement_level_gate_standard_contract() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
c.kani_harnesses = vec![make_kani_harness("K-01")];
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Standard);
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_enforcement_level_gate_declared_vs_actual_mismatch() {
let mut c = minimal_contract();
c.metadata.enforcement_level = Some(EnforcementLevel::Strict);
let contracts = vec![("test-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Basic);
let mismatch_findings: Vec<_> = findings
.iter()
.filter(|f| f.message.contains("declares enforcement_level"))
.collect();
assert_eq!(mismatch_findings.len(), 1);
assert!(mismatch_findings[0].message.contains("Strict"));
assert!(mismatch_findings[0].message.contains("Basic"));
assert_eq!(result.name, "enforcement-level");
}
#[test]
fn test_enforcement_level_gate_skips_registries() {
let mut c = minimal_contract();
c.metadata.registry = true;
let contracts = vec![("registry-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Proven);
assert!(result.passed);
assert!(findings.is_empty());
}
#[test]
fn test_compute_actual_level_basic() {
let c = minimal_contract();
assert_eq!(compute_actual_level(&c), EnforcementLevel::Basic);
}
#[test]
fn test_compute_actual_level_standard() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
c.kani_harnesses = vec![make_kani_harness("K-01")];
assert_eq!(compute_actual_level(&c), EnforcementLevel::Standard);
}
#[test]
fn test_compute_actual_level_proven() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
c.kani_harnesses = vec![make_kani_harness("K-01")];
c.verification_summary = Some(VerificationSummary {
total_obligations: 1,
l2_property_tested: 1,
l3_kani_proved: 1,
l4_lean_proved: 1,
l4_sorry_count: 0,
l4_not_applicable: 0,
});
assert_eq!(compute_actual_level(&c), EnforcementLevel::Proven);
}
#[test]
fn test_compute_actual_level_with_sorry_not_proven() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
c.kani_harnesses = vec![make_kani_harness("K-01")];
c.verification_summary = Some(VerificationSummary {
total_obligations: 1,
l2_property_tested: 1,
l3_kani_proved: 1,
l4_lean_proved: 1,
l4_sorry_count: 1, l4_not_applicable: 0,
});
assert_eq!(compute_actual_level(&c), EnforcementLevel::Standard);
}
#[test]
fn test_compute_actual_level_only_falsification() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
assert_eq!(compute_actual_level(&c), EnforcementLevel::Basic);
}
#[test]
fn test_compute_actual_level_only_kani() {
let mut c = minimal_contract();
c.kani_harnesses = vec![make_kani_harness("K-01")];
assert_eq!(compute_actual_level(&c), EnforcementLevel::Basic);
}
#[test]
fn test_level_lock_regression_detected() {
let mut c = minimal_contract();
c.metadata.locked_level = Some("standard".to_string());
let contracts = vec![("locked-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Basic);
assert!(!result.passed, "should fail: level lock regression");
let lock_findings: Vec<_> = findings
.iter()
.filter(|f| f.rule_id == "PV-LCK-001")
.collect();
assert_eq!(lock_findings.len(), 1);
assert!(lock_findings[0].message.contains("locked"));
assert!(lock_findings[0].message.contains("regressed"));
assert_eq!(lock_findings[0].severity, RuleSeverity::Error);
}
#[test]
fn test_level_lock_no_regression() {
let mut c = minimal_contract();
c.falsification_tests = vec![make_falsification_test("F-01", "test_x")];
c.kani_harnesses = vec![make_kani_harness("K-01")];
c.metadata.locked_level = Some("standard".to_string());
let contracts = vec![("locked-v1".to_string(), c)];
let (result, findings) = run_enforcement_level_gate(&contracts, EnforcementLevel::Basic);
assert!(result.passed);
let lock_findings: Vec<_> = findings
.iter()
.filter(|f| f.rule_id == "PV-LCK-001")
.collect();
assert!(lock_findings.is_empty());
}
#[test]
fn test_level_lock_aliases() {
let mut c = minimal_contract();
c.metadata.locked_level = Some("l1".to_string()); let contracts = vec![("alias-v1".to_string(), c.clone())];
let (result, _) = run_enforcement_level_gate(&contracts, EnforcementLevel::Basic);
assert!(result.passed);
let mut c2 = minimal_contract();
c2.metadata.locked_level = Some("l5".to_string());
let contracts2 = vec![("alias-v1".to_string(), c2)];
let (result2, findings2) = run_enforcement_level_gate(&contracts2, EnforcementLevel::Basic);
assert!(!result2.passed);
assert!(findings2.iter().any(|f| f.rule_id == "PV-LCK-001"));
}
#[test]
fn test_reverse_coverage_gate_high_coverage() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "pub fn alpha() {}\npub fn beta() {}\n").unwrap();
let binding = dir.path().join("binding.yaml");
std::fs::write(
&binding,
"bindings:\n - function: alpha\n - function: beta\n",
)
.unwrap();
let (result, findings) = run_reverse_coverage_gate(&binding, dir.path());
assert!(result.passed);
let unbound: Vec<_> = findings
.iter()
.filter(|f| f.rule_id == "PV-RCV-001")
.collect();
assert!(unbound.is_empty());
}
#[test]
fn test_reverse_coverage_gate_below_threshold() {
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
let mut code = String::new();
for i in 0..10 {
code.push_str(&format!("pub fn zzzunbound_qqq_{i}() {{}}\n"));
}
std::fs::write(src.join("lib.rs"), &code).unwrap();
let binding = dir.path().join("binding.yaml");
std::fs::write(&binding, "bindings: []\n").unwrap();
let (result, findings) = run_reverse_coverage_gate(&binding, dir.path());
assert!(!result.passed, "should fail: coverage below 50%");
assert!(findings.iter().any(|f| f.rule_id == "PV-RCV-002"));
}
#[test]
fn test_stale_suppressions_rule_still_active() {
let findings = vec![LintFinding::new(
"PV-VAL-001",
RuleSeverity::Error,
"msg",
"a.yaml",
)];
let stale = check_stale_suppressions(&findings, &["PV-VAL-001".into()], &[]);
assert!(stale.is_empty(), "active rule should not be stale");
}
#[test]
fn test_stale_suppressions_rule_no_longer_fires() {
let findings = vec![LintFinding::new(
"PV-VAL-001",
RuleSeverity::Error,
"msg",
"a.yaml",
)];
let stale = check_stale_suppressions(&findings, &["PV-GONE-001".into()], &[]);
assert_eq!(stale.len(), 1);
assert_eq!(stale[0].rule_id, "PV-SUP-001");
assert!(stale[0].message.contains("PV-GONE-001"));
assert!(stale[0].message.contains("stale"));
}
#[test]
fn test_stale_suppressions_stem_still_has_findings() {
let mut f = LintFinding::new("PV-VAL-001", RuleSeverity::Error, "msg", "a.yaml");
f.contract_stem = Some("softmax-v1".into());
let findings = vec![f];
let stale = check_stale_suppressions(&findings, &[], &["softmax-v1".into()]);
assert!(
stale.is_empty(),
"stem with active findings should not be stale"
);
}
#[test]
fn test_stale_suppressions_stem_no_findings() {
let findings: Vec<LintFinding> = vec![];
let stale = check_stale_suppressions(&findings, &[], &["old-contract-v1".into()]);
assert_eq!(stale.len(), 1);
assert!(stale[0].message.contains("old-contract-v1"));
}
#[test]
fn test_stale_suppressions_empty_everything() {
let stale = check_stale_suppressions(&[], &[], &[]);
assert!(stale.is_empty());
}
#[test]
fn test_stale_suppressions_multiple_stale_rules() {
let findings: Vec<LintFinding> = vec![];
let stale = check_stale_suppressions(&findings, &["PV-A-001".into(), "PV-B-001".into()], &[]);
assert_eq!(stale.len(), 2);
}