use proptest::prelude::*;
use super::{passes_not_present_gate, MIN_CONTRADICTORY_TECHNIQUES, STRONG_THRESHOLD};
use crate::aggregation::reducer::EvidenceEvent;
use crate::existence::families::SignalFamily;
fn weak(weight: f64) -> EvidenceEvent {
EvidenceEvent::contradictory(SignalFamily::General, "weak", weight, weight)
}
fn strong() -> EvidenceEvent {
EvidenceEvent::contradictory(SignalFamily::General, "strong", 0.25, 0.25)
}
fn positive() -> EvidenceEvent {
EvidenceEvent::positive(SignalFamily::General, "pos", 0.5, 0.5)
}
#[test]
fn empty_events_fails_gate() {
assert!(!passes_not_present_gate(&[]));
}
#[test]
fn three_weak_contradictories_fails_no_strong() {
let events = [weak(0.05), weak(0.05), weak(0.05)];
assert!(!passes_not_present_gate(&events));
}
#[test]
fn three_contradictories_one_strong_passes() {
let events = [strong(), weak(0.05), weak(0.05)];
assert!(passes_not_present_gate(&events));
}
#[test]
fn two_strong_contradictories_fails_below_min_count() {
let events = [strong(), strong()];
assert!(!passes_not_present_gate(&events));
}
#[test]
fn positive_disqualifies_even_with_strong_contradictories() {
let events = [strong(), weak(0.05), weak(0.05), positive()];
assert!(!passes_not_present_gate(&events));
}
#[test]
fn ten_weak_contradictories_no_strong_fails() {
let events: Vec<EvidenceEvent> = (0..10).map(|_| weak(0.05)).collect();
assert!(!passes_not_present_gate(&events));
}
#[test]
fn weight_exactly_at_strong_threshold_counts_as_strong() {
let events = [weak(STRONG_THRESHOLD), weak(0.05), weak(0.05)];
assert!(passes_not_present_gate(&events));
}
#[test]
fn weight_just_below_strong_threshold_does_not_count() {
let just_below = STRONG_THRESHOLD - 0.000_01;
let events = [weak(just_below), weak(just_below), weak(just_below)];
assert!(!passes_not_present_gate(&events));
}
proptest! {
#[test]
fn any_positive_event_fails_the_gate(
positives in 1usize..=5,
contradictories in 0usize..=10,
) {
let mut events: Vec<EvidenceEvent> =
(0..contradictories).map(|_| strong()).collect();
events.extend((0..positives).map(|_| positive()));
prop_assert!(!passes_not_present_gate(&events));
}
#[test]
fn fewer_than_min_contradictories_fails_the_gate(
contradictories in 0usize..MIN_CONTRADICTORY_TECHNIQUES,
) {
let events: Vec<EvidenceEvent> = (0..contradictories).map(|_| strong()).collect();
prop_assert!(!passes_not_present_gate(&events));
}
#[test]
fn enough_strong_contradictories_passes(extra_weak in 0usize..=10) {
let mut events: Vec<EvidenceEvent> =
(0..MIN_CONTRADICTORY_TECHNIQUES).map(|_| strong()).collect();
events.extend((0..extra_weak).map(|_| weak(0.05)));
prop_assert!(passes_not_present_gate(&events));
}
#[test]
fn no_strong_techniques_fails_regardless_of_count(
n_weak in MIN_CONTRADICTORY_TECHNIQUES..=20,
) {
let events: Vec<EvidenceEvent> = (0..n_weak).map(|_| weak(0.05)).collect();
prop_assert!(!passes_not_present_gate(&events));
}
}