use super::common::{k4_dense, k4_v2_round, two_k4_dense, two_k4_v2_result, v2_step};
use crate::collapse::SchedulePosition;
use crate::collapse::verify::verify_dense;
#[test]
fn accepts_two_k4_v2_rounds() {
assert_eq!(
verify_dense(&two_k4_dense(), None, &two_k4_v2_result()),
Ok(())
);
}
#[test]
fn rejects_same_round_conflict_despite_serial_validity() {
let result = k4_v2_round(vec![v2_step(0, 1, 1, 2), v2_step(0, 2, 1, 3)]);
let err = verify_dense(&k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(1));
assert!(err.message.contains("conflict"), "{}", err.message);
}
#[test]
fn rejects_witnesses_valid_only_after_earlier_step() {
let result = k4_v2_round(vec![v2_step(0, 1, 1, 2), v2_step(1, 2, 1, 3)]);
let err = verify_dense(&k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(1));
assert!(err.message.contains("conflict"), "{}", err.message);
}
#[test]
fn rejects_witnesses_from_stale_snapshot() {
let mut result = two_k4_v2_result();
result.certificate.steps[2].witnesses = vec![(1.0, 1)];
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(2));
assert!(err.message.contains("common neighbor"), "{}", err.message);
}
#[test]
fn rejects_round_gap() {
let mut result = two_k4_v2_result();
for step in &mut result.certificate.steps[2..] {
step.position = SchedulePosition::Round(3);
}
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(2));
assert!(err.message.contains("skips round 2"), "{}", err.message);
}
#[test]
fn rejects_interleaved_rounds() {
let mut result = two_k4_v2_result();
result.certificate.steps.swap(1, 2);
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(2));
assert!(err.message.contains("decreases"), "{}", err.message);
}
#[test]
fn rejects_out_of_order_within_round() {
let mut result = two_k4_v2_result();
result.certificate.steps.swap(0, 1);
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(1));
assert!(err.message.contains("schedule order"), "{}", err.message);
}
#[test]
fn rejects_first_round_not_one() {
let mut result = two_k4_v2_result();
result.certificate.steps[0].position = SchedulePosition::Round(2);
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(0));
assert!(err.message.contains("first step"), "{}", err.message);
}
#[test]
fn rejects_round_zero() {
let mut result = two_k4_v2_result();
result.certificate.steps[0].position = SchedulePosition::Round(0);
let err = verify_dense(&two_k4_dense(), None, &result).unwrap_err();
assert_eq!(err.step, Some(0));
assert!(err.message.contains("round number 0"), "{}", err.message);
}