use super::*;
#[test]
fn evaluate_complete_not_present_on_same_status() {
let ds = diff_set_1(404, 404);
let SampleDecision::Complete(result, _outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
assert_eq!(result.verdict, OracleVerdict::NotPresent);
assert_eq!(result.severity, None);
}
#[test]
fn same_status_on_status_code_diff_produces_contradictory() {
let ds = diff_set_1(404, 404);
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
let StrategyOutcome::Contradictory(_inner, weight) = outcome else {
panic!("expected Contradictory outcome for same-status StatusCodeDiff");
};
assert!(weight > 0.0, "Contradictory weight must be > 0.0");
}
#[test]
fn same_status_on_redirect_diff_produces_no_signal() {
use parlov_core::{
always_applicable, NormativeStrength, OracleClass, SignalSurface, Technique, Vector,
};
let ds = DifferentialSet {
baseline: vec![fake_exchange(404)],
probe: vec![fake_exchange(404)],
canonical: None,
technique: Technique {
id: "test-redirect-diff-same",
name: "Test redirect diff same",
oracle_class: OracleClass::Existence,
vector: Vector::RedirectDiff,
strength: NormativeStrength::Should,
normalization_weight: None,
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
};
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
assert!(
matches!(outcome, StrategyOutcome::NoSignal(_)),
"same-status on RedirectDiff must produce NoSignal outcome"
);
}
#[test]
fn same_status_with_normalization_weight_is_contradictory() {
use parlov_core::{
always_applicable, NormativeStrength, OracleClass, SignalSurface, Technique, Vector,
};
let ds = DifferentialSet {
baseline: vec![fake_exchange(404)],
probe: vec![fake_exchange(404)],
canonical: None,
technique: Technique {
id: "test-normalization-weight",
name: "Test normalization weight",
oracle_class: OracleClass::Existence,
vector: Vector::StatusCodeDiff,
strength: NormativeStrength::Must,
normalization_weight: Some(0.2),
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
};
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
let StrategyOutcome::Contradictory(_inner, weight) = outcome else {
panic!("expected Contradictory for Some(0.2) normalization_weight on SameStatus");
};
assert!(
(weight - 0.2).abs() < f32::EPSILON,
"weight must equal normalization_weight; got {weight}"
);
}
#[test]
fn same_status_without_normalization_weight_is_no_signal() {
use parlov_core::{
always_applicable, NormativeStrength, OracleClass, SignalSurface, Technique, Vector,
};
let ds = DifferentialSet {
baseline: vec![fake_exchange(404)],
probe: vec![fake_exchange(404)],
canonical: None,
technique: Technique {
id: "test-no-normalization",
name: "Test no normalization",
oracle_class: OracleClass::Existence,
vector: Vector::CacheProbing,
strength: NormativeStrength::May,
normalization_weight: None,
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
};
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
assert!(
matches!(outcome, StrategyOutcome::NoSignal(_)),
"normalization_weight: None on SameStatus must produce NoSignal"
);
}
use proptest::prelude::*;
proptest! {
#[test]
fn same_status_normalization_weight_some_always_contradictory(w in 0.01f32..=1.0f32) {
use parlov_core::{NormativeStrength, OracleClass, SignalSurface, Technique, Vector, always_applicable};
let ds = DifferentialSet {
baseline: vec![fake_exchange(404)],
probe: vec![fake_exchange(404)],
canonical: None,
technique: Technique {
id: "test-prop",
name: "Test prop",
oracle_class: OracleClass::Existence,
vector: Vector::StatusCodeDiff,
strength: NormativeStrength::Must,
normalization_weight: Some(w),
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
};
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
panic!("expected Complete");
};
let StrategyOutcome::Contradictory(_, weight) = outcome else {
return Err(proptest::test_runner::TestCaseError::fail("expected Contradictory"));
};
prop_assert!(
(weight - w).abs() < f32::EPSILON,
"weight {weight} must equal normalization_weight {w}"
);
}
#[test]
fn same_status_normalization_weight_none_always_no_signal(status in 200u16..=599u16) {
use parlov_core::{NormativeStrength, OracleClass, SignalSurface, Technique, Vector, always_applicable};
let valid_status = if http::StatusCode::from_u16(status).is_err() {
404u16
} else {
status
};
let ds = DifferentialSet {
baseline: vec![fake_exchange(valid_status)],
probe: vec![fake_exchange(valid_status)],
canonical: None,
technique: Technique {
id: "test-none-prop",
name: "Test none prop",
oracle_class: OracleClass::Existence,
vector: Vector::CacheProbing,
strength: NormativeStrength::May,
normalization_weight: None,
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
};
let SampleDecision::Complete(_result, outcome) = ExistenceAnalyzer.evaluate(&ds) else {
return Err(proptest::test_runner::TestCaseError::fail("expected Complete"));
};
prop_assert!(
matches!(outcome, StrategyOutcome::NoSignal(_)),
"normalization_weight: None on SameStatus must always produce NoSignal"
);
}
}