use super::*;
#[kani::proof]
#[kani::unwind(3)]
fn report_classification_and_capacity_preserve_exact_events() {
let mut report = AppliedViewChanges {
changes: Vec::with_capacity(1),
maximum: 1,
};
let full: bool = kani::any();
let id: u8 = kani::any();
let existing = AppliedViewChange::Left { id };
if full {
report.changes.push(existing);
}
let before: Option<(u64, u8)> = kani::any();
let after: (u64, u8) = kani::any();
let result = report.compare_row(
id,
before.as_ref().map(|(identity, value)| (*identity, value)),
(after.0, &after.1),
);
if before == Some(after) {
assert!(result.is_ok());
assert_eq!(report.changes.len(), usize::from(full));
kani::cover!(true, "subscription.report_unchanged");
} else if full {
assert_eq!(result, Err(ViewApplyError::ReportCapacityExceeded));
assert_eq!(report.changes.as_slice(), &[existing]);
kani::cover!(true, "subscription.report_full");
} else {
assert!(result.is_ok());
assert_eq!(report.changes.len(), 1);
let actual = report.changes.first();
match before {
None => {
assert_eq!(actual, Some(&AppliedViewChange::Entered { id }));
kani::cover!(true, "subscription.report_entered");
}
Some((identity, _)) if identity != after.0 => {
assert_eq!(actual, Some(&AppliedViewChange::Replaced { id }));
kani::cover!(true, "subscription.report_replaced");
}
Some((identity, value)) => {
assert_eq!(identity, after.0);
assert_ne!(value, after.1);
assert_eq!(actual, Some(&AppliedViewChange::Updated { id }));
kani::cover!(true, "subscription.report_updated");
}
}
}
report.clear();
assert!(report.as_slice().is_empty());
assert_eq!(report.maximum, 1);
}