use ordmask::{OrdMask, ordmask};
macro_rules! assert_mask_eq {
($left:expr, $right:expr, $msg:expr) => {
assert_eq!(
$left, $right,
"{}: left={:?}, right={:?}",
$msg, $left, $right
);
};
}
#[test]
fn test_complement_basic() {
let test_cases: Vec<(Vec<i32>, bool, Vec<i32>, bool)> = vec![
(vec![0, 10], false, vec![0, 10], true),
(vec![5, 15, 20, 30], false, vec![5, 15, 20, 30], true),
(vec![0, 10], true, vec![0, 10], false),
(vec![5, 15, 20, 30], true, vec![5, 15, 20, 30], false),
(vec![], false, vec![], true),
(vec![], true, vec![], false),
];
for (input_kp, input_rev, expected_kp, expected_rev) in test_cases {
let mask: OrdMask<i32> = unsafe { OrdMask::with_checked(input_kp, input_rev) };
let expected: OrdMask<i32> = unsafe { OrdMask::with_checked(expected_kp, expected_rev) };
let result = mask.complement();
assert_mask_eq!(result, expected, "complement basic test failed");
}
}
#[test]
fn test_complement_empty() {
let empty: OrdMask<i32> = ordmask![];
assert_eq!(empty.complement(), ordmask![..]);
assert_eq!(empty.complement().complement(), empty);
}
#[test]
fn test_complement_universal() {
let universal: OrdMask<i32> = ordmask![..];
assert_eq!(universal.complement(), ordmask![]);
assert_eq!(universal.complement().complement(), universal);
}
#[test]
fn test_complement_with_reversed() {
let reversed1 = ordmask![.., 0, 10];
assert_eq!(reversed1.complement(), ordmask![0, 10]);
assert_eq!(reversed1.complement().complement(), reversed1);
}
#[test]
fn test_complement_with_infinite() {
let inf_right = ordmask![0]; let inf_left = ordmask![.., 10];
assert_eq!(inf_right.complement(), ordmask![.., 0]);
assert_eq!(inf_left.complement(), ordmask![10]);
}
#[test]
fn test_complement_at_edge() {
let a: OrdMask<u32> = ordmask![.., 0]; let b = ordmask![u32::MAX]; let c = ordmask![0, 10]; let d = ordmask![100, u32::MAX];
assert_eq!(a.complement(), ordmask![..]);
assert_eq!(b.complement(), ordmask![.., u32::MAX]);
assert_eq!(c.complement(), ordmask![.., 0, 10]);
assert_eq!(d.complement(), ordmask![.., 100, u32::MAX]);
}
#[test]
fn test_complement_operator() {
let mask = ordmask![0, 10];
let expected = ordmask![.., 0, 10];
assert_eq!(!&mask, expected);
assert_eq!(!mask.clone(), expected);
assert_eq!(!(!&mask), mask);
assert_eq!(!(!mask.clone()), mask);
}
#[test]
fn test_to_complement() {
let mask = ordmask![0, 10];
let expected = ordmask![.., 0, 10];
let complement = mask.to_complement();
assert_eq!(complement, expected);
}
#[test]
fn test_reverse() {
let mut mask = ordmask![0, 10];
let expected = ordmask![.., 0, 10];
mask.reverse();
assert_eq!(mask, expected);
mask.reverse();
assert_eq!(mask, ordmask![0, 10]);
}
#[test]
fn test_complement_is_involution() {
let test_masks: Vec<OrdMask<i32>> = vec![
ordmask![],
ordmask![..],
ordmask![0, 10],
ordmask![5, 15, 20, 30],
ordmask![.., 0, 10],
ordmask![.., 5, 15, 20, 30],
ordmask![0],
ordmask![.., 10],
];
for mask in test_masks {
assert_eq!(
mask.complement().complement(),
mask,
"Double complement failed for {:?}",
mask
);
}
}
#[test]
fn test_complement_with_union() {
let a = ordmask![0, 10];
let b = ordmask![5, 15];
let left = OrdMask::union(&[&a, &b]).complement();
let right = OrdMask::intersection(&[&a.complement(), &b.complement()]);
assert_eq!(left, right);
}
#[test]
fn test_complement_with_intersection() {
let a = ordmask![0, 10];
let b = ordmask![5, 15];
let left = OrdMask::intersection(&[&a, &b]).complement();
let right = OrdMask::union(&[&a.complement(), &b.complement()]);
assert_eq!(left, right);
}
#[test]
fn test_complement_complex_ranges() {
let mask = ordmask![0, 5, 10, 15, 20, 25];
let complement = mask.complement();
assert!(!mask.included(&-1));
assert!(complement.included(&-1));
assert!(mask.included(&2));
assert!(!complement.included(&2));
assert!(!mask.included(&7));
assert!(complement.included(&7));
assert!(mask.included(&12));
assert!(!complement.included(&12));
assert!(!mask.included(&30));
assert!(complement.included(&30));
assert_eq!(complement.complement(), mask);
}