use super::*;
#[cfg(test)]
mod unit_tests {
use super::*;
#[test]
fn test_minkowski_add_basic() {
let a = I8CO::try_new(1, 5).unwrap();
let b = I8CO::try_new(-3, 2).unwrap();
let res = a.checked_minkowski_add(b).unwrap();
assert_eq!(res.start(), -2);
assert_eq!(res.end_excl(), 6);
}
#[test]
fn test_minkowski_sub_basic() {
let a = I8CO::try_new(5, 10).unwrap();
let b = I8CO::try_new(2, 4).unwrap();
let res = a.checked_minkowski_sub(b).unwrap();
assert_eq!(res.start(), 2); assert_eq!(res.end_excl(), 8); }
#[test]
fn test_minkowski_mul_basic() {
let a = I8CO::try_new(-2, 3).unwrap(); let b = I8CO::try_new(-1, 2).unwrap(); let res = a.checked_minkowski_mul_hull(b).unwrap();
assert_eq!(res.start(), -2);
assert_eq!(res.end_excl(), 3); }
#[test]
fn test_minkowski_div_basic() {
let a = I8CO::try_new(-4, 10).unwrap();
let b = I8CO::try_new(2, 5).unwrap();
let res = a.checked_minkowski_div_hull(b).unwrap();
assert_eq!(res.start(), -2);
assert_eq!(res.end_excl(), 5); }
#[test]
fn test_minkowski_div_by_zero() {
let a = I8CO::try_new(1, 5).unwrap();
let b = I8CO::try_new(0, 3).unwrap();
assert!(a.checked_minkowski_div_hull(b).is_none());
}
}
#[cfg(test)]
mod prop_tests {
use super::*;
use proptest::prelude::*;
fn interval_strategy() -> impl Strategy<Value = I8CO> {
prop_oneof![
Just(I8CO::try_new(i8::MIN, i8::MIN + 1).unwrap()), Just(I8CO::try_new(i8::MIN, i8::MAX).unwrap()), Just(I8CO::try_new(i8::MAX - 1, i8::MAX).unwrap()), (i8::MIN..=i8::MAX, i8::MIN..=i8::MAX)
.prop_filter_map("valid interval", |(s, e)| I8CO::try_new(s, e))
]
}
proptest! {
#[test]
fn prop_add_containment(a in interval_strategy(), b in interval_strategy()) {
if let Some(c) = a.checked_minkowski_add(b) {
let xs = [a.start(), a.end_excl()-1];
let ys = [b.start(), b.end_excl()-1];
for &x in &xs {
for &y in &ys {
let sum = x.wrapping_add(y);
prop_assert!(c.start() <= sum && sum < c.end_excl());
}
}
}
}
#[test]
fn prop_sub_containment(a in interval_strategy(), b in interval_strategy()) {
if let Some(c) = a.checked_minkowski_sub(b) {
let xs = [a.start(), a.end_excl()-1];
let ys = [b.start(), b.end_excl()-1];
for &x in &xs {
for &y in &ys {
let diff = x.wrapping_sub(y);
prop_assert!(c.start() <= diff && diff < c.end_excl());
}
}
}
}
#[test]
fn prop_mul_containment(a in interval_strategy(), b in interval_strategy()) {
if let Some(c) = a.checked_minkowski_mul_hull(b) {
let xs = [a.start(), a.end_excl()-1];
let ys = [b.start(), b.end_excl()-1];
for &x in &xs {
for &y in &ys {
let prod = x.wrapping_mul(y);
prop_assert!(c.start() <= prod && prod < c.end_excl());
}
}
}
}
#[test]
fn prop_div_containment(a in interval_strategy(), b in interval_strategy()
.prop_filter("non-zero start", |b| b.start() != 0)) {
if let Some(c) = a.checked_minkowski_div_hull(b) {
let xs = [a.start(), a.end_excl()-1];
let ys = [b.start(), b.end_excl()-1];
for &x in &xs {
for &y in &ys {
let div = x / y;
prop_assert!(c.start() <= div && div < c.end_excl());
}
}
}
}
#[test]
fn prop_add_commutative(a in interval_strategy(), b in interval_strategy()) {
let res1 = a.checked_minkowski_add(b);
let res2 = b.checked_minkowski_add(a);
prop_assert_eq!(res1, res2);
}
#[test]
fn prop_mul_commutative(a in interval_strategy(), b in interval_strategy()) {
let res1 = a.checked_minkowski_mul_hull(b);
let res2 = b.checked_minkowski_mul_hull(a);
prop_assert_eq!(res1, res2);
}
}
}