diff --git a/src/inclusive_map.rs b/src/inclusive_map.rs index 752da0a..9f17534 100644 --- a/src/inclusive_map.rs +++ b/src/inclusive_map.rs @@ -958,6 +958,16 @@ mod tests { } } + #[proptest] + fn test_len(mut map: RangeInclusiveMap) { + assert_eq!(map.len(), map.iter().count()); + assert_eq!(map.is_empty(), map.len() == 0); + map.clear(); + assert_eq!(map.len(), 0); + assert!(map.is_empty()); + assert_eq!(map.iter().count(), 0); + } + #[proptest] fn test_first(set: RangeInclusiveMap) { assert_eq!( @@ -1026,6 +1036,47 @@ mod tests { } } + #[proptest] + #[allow(deprecated)] + fn test_hash(left: RangeInclusiveMap, right: RangeInclusiveMap) { + use core::hash::{Hash, Hasher, SipHasher}; + + let hash = |set: &RangeInclusiveMap<_, _>| { + let mut hasher = SipHasher::new(); + set.hash(&mut hasher); + hasher.finish() + }; + + if left == right { + assert!( + hash(&left) == hash(&right), + "if two values are equal, their hash must be equal" + ); + } + + // if the hashes are equal the values might not be the same (collision) + if hash(&left) != hash(&right) { + assert!( + left != right, + "if two value's hashes are not equal, they must not be equal" + ); + } + } + + #[proptest] + fn test_ord(left: RangeInclusiveMap, right: RangeInclusiveMap) { + assert_eq!( + left == right, + left.cmp(&right).is_eq(), + "ordering and equality must match" + ); + assert_eq!( + left.cmp(&right), + left.partial_cmp(&right).unwrap(), + "ordering is total for ordered parameters" + ); + } + #[test] fn test_from_array() { let mut map = RangeInclusiveMap::new(); @@ -1039,7 +1090,10 @@ mod tests { #[test] fn test_macro() { - assert_eq!(range_inclusive_map![], RangeInclusiveMap::::new()); + assert_eq!( + range_inclusive_map![], + RangeInclusiveMap::::default() + ); assert_eq!( range_inclusive_map!(0..=100 => "abc", 100..=200 => "def", 200..=300 => "ghi"), [(0..=100, "abc"), (100..=200, "def"), (200..=300, "ghi")] diff --git a/src/inclusive_set.rs b/src/inclusive_set.rs index e82e320..c46aa79 100644 --- a/src/inclusive_set.rs +++ b/src/inclusive_set.rs @@ -496,6 +496,16 @@ mod tests { assert_eq!(set.first(), set.iter().min_by_key(|range| range.start())); } + #[proptest] + fn test_len(mut map: RangeInclusiveSet) { + assert_eq!(map.len(), map.iter().count()); + assert_eq!(map.is_empty(), map.len() == 0); + map.clear(); + assert_eq!(map.len(), 0); + assert!(map.is_empty()); + assert_eq!(map.iter().count(), 0); + } + #[proptest] fn test_last(set: RangeInclusiveSet) { assert_eq!(set.last(), set.iter().max_by_key(|range| range.end())); @@ -551,6 +561,47 @@ mod tests { } } + #[proptest] + #[allow(deprecated)] + fn test_hash(left: RangeInclusiveSet, right: RangeInclusiveSet) { + use core::hash::{Hash, Hasher, SipHasher}; + + let hash = |set: &RangeInclusiveSet<_>| { + let mut hasher = SipHasher::new(); + set.hash(&mut hasher); + hasher.finish() + }; + + if left == right { + assert!( + hash(&left) == hash(&right), + "if two values are equal, their hash must be equal" + ); + } + + // if the hashes are equal the values might not be the same (collision) + if hash(&left) != hash(&right) { + assert!( + left != right, + "if two value's hashes are not equal, they must not be equal" + ); + } + } + + #[proptest] + fn test_ord(left: RangeInclusiveSet, right: RangeInclusiveSet) { + assert_eq!( + left == right, + left.cmp(&right).is_eq(), + "ordering and equality must match" + ); + assert_eq!( + left.cmp(&right), + left.partial_cmp(&right).unwrap(), + "ordering is total for ordered parameters" + ); + } + #[test] fn test_from_array() { let mut set = RangeInclusiveSet::new(); @@ -561,7 +612,7 @@ mod tests { #[test] fn test_macro() { - assert_eq!(range_inclusive_set![], RangeInclusiveSet::::new()); + assert_eq!(range_inclusive_set![], RangeInclusiveSet::::default()); assert_eq!( range_inclusive_set![0..=100, 200..=300, 400..=500], [0..=100, 200..=300, 400..=500].iter().cloned().collect(), @@ -569,10 +620,7 @@ mod tests { } #[proptest] - fn test_union_overlaps_u8(left: Vec>, right: Vec>) { - let left: RangeInclusiveSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeInclusiveSet<_> = filter_ranges(right).into_iter().collect(); - + fn test_union_overlaps_u8(left: RangeInclusiveSet, right: RangeInclusiveSet) { let mut union = RangeInclusiveSet::new(); for range in left.union(&right) { // there should not be any overlaps in the ranges returned by the union @@ -582,10 +630,8 @@ mod tests { } #[proptest] - fn test_union_contains_u8(left: Vec>, right: Vec>) { - let left: RangeInclusiveSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeInclusiveSet<_> = filter_ranges(right).into_iter().collect(); - let union: RangeInclusiveSet<_> = left.union(&right).collect(); + fn test_union_contains_u8(left: RangeInclusiveSet, right: RangeInclusiveSet) { + let union = (&left) | (&right); // value should be in the union if and only if it is in either set for value in 0..u8::MAX { @@ -597,31 +643,20 @@ mod tests { } #[proptest] - fn test_intersection_contains_u8( - left: Vec>, - right: Vec>, - ) { - let left: RangeInclusiveSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeInclusiveSet<_> = filter_ranges(right).into_iter().collect(); - let union: RangeInclusiveSet<_> = left.intersection(&right).collect(); + fn test_intersection_contains_u8(left: RangeInclusiveSet, right: RangeInclusiveSet) { + let intersection = (&left) & (&right); - // value should be in the union if and only if it is in either set + // value should be in the intersection if and only if it is in both sets for value in 0..u8::MAX { assert_eq!( - union.contains(&value), + intersection.contains(&value), left.contains(&value) && right.contains(&value) ); } } #[proptest] - fn test_intersection_overlaps_u8( - left: Vec>, - right: Vec>, - ) { - let left: RangeInclusiveSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeInclusiveSet<_> = filter_ranges(right).into_iter().collect(); - + fn test_intersection_overlaps_u8(left: RangeInclusiveSet, right: RangeInclusiveSet) { let mut union = RangeInclusiveSet::new(); for range in left.intersection(&right) { // there should not be any overlaps in the ranges returned by the diff --git a/src/map.rs b/src/map.rs index a160962..9b0aabd 100644 --- a/src/map.rs +++ b/src/map.rs @@ -854,6 +854,16 @@ mod tests { ); } + #[proptest] + fn test_len(mut map: RangeMap) { + assert_eq!(map.len(), map.iter().count()); + assert_eq!(map.is_empty(), map.len() == 0); + map.clear(); + assert_eq!(map.len(), 0); + assert!(map.is_empty()); + assert_eq!(map.iter().count(), 0); + } + #[proptest] fn test_last(set: RangeMap) { assert_eq!( @@ -911,6 +921,47 @@ mod tests { } } + #[proptest] + #[allow(deprecated)] + fn test_hash(left: RangeMap, right: RangeMap) { + use core::hash::{Hash, Hasher, SipHasher}; + + let hash = |set: &RangeMap<_, _>| { + let mut hasher = SipHasher::new(); + set.hash(&mut hasher); + hasher.finish() + }; + + if left == right { + assert!( + hash(&left) == hash(&right), + "if two values are equal, their hash must be equal" + ); + } + + // if the hashes are equal the values might not be the same (collision) + if hash(&left) != hash(&right) { + assert!( + left != right, + "if two value's hashes are not equal, they must not be equal" + ); + } + } + + #[proptest] + fn test_ord(left: RangeMap, right: RangeMap) { + assert_eq!( + left == right, + left.cmp(&right).is_eq(), + "ordering and equality must match" + ); + assert_eq!( + left.cmp(&right), + left.partial_cmp(&right).unwrap(), + "ordering is total for ordered parameters" + ); + } + #[test] fn test_from_array() { let mut map = RangeMap::new(); @@ -924,7 +975,7 @@ mod tests { #[test] fn test_macro() { - assert_eq!(range_map![], RangeMap::::new()); + assert_eq!(range_map![], RangeMap::::default()); assert_eq!( range_map!(0..100 => "abc", 100..200 => "def", 200..300 => "ghi"), [(0..100, "abc"), (100..200, "def"), (200..300, "ghi")] diff --git a/src/set.rs b/src/set.rs index 874379c..a672f38 100644 --- a/src/set.rs +++ b/src/set.rs @@ -452,7 +452,12 @@ mod tests { fn arbitrary_with(_parameters: Self::Parameters) -> Self::Strategy { any::>>() - .prop_map(|ranges| ranges.into_iter().collect::>()) + .prop_map(|ranges| { + ranges + .into_iter() + .filter(|range| range.start != range.end) + .collect::>() + }) .boxed() } } @@ -462,6 +467,16 @@ mod tests { assert_eq!(set.first(), set.iter().min_by_key(|range| range.start)); } + #[proptest] + fn test_len(mut map: RangeSet) { + assert_eq!(map.len(), map.iter().count()); + assert_eq!(map.is_empty(), map.len() == 0); + map.clear(); + assert_eq!(map.len(), 0); + assert!(map.is_empty()); + assert_eq!(map.iter().count(), 0); + } + #[proptest] fn test_last(set: RangeSet) { assert_eq!(set.last(), set.iter().max_by_key(|range| range.end)); @@ -515,6 +530,47 @@ mod tests { } } + #[proptest] + #[allow(deprecated)] + fn test_hash(left: RangeSet, right: RangeSet) { + use core::hash::{Hash, Hasher, SipHasher}; + + let hash = |set: &RangeSet<_>| { + let mut hasher = SipHasher::new(); + set.hash(&mut hasher); + hasher.finish() + }; + + if left == right { + assert!( + hash(&left) == hash(&right), + "if two values are equal, their hash must be equal" + ); + } + + // if the hashes are equal the values might not be the same (collision) + if hash(&left) != hash(&right) { + assert!( + left != right, + "if two value's hashes are not equal, they must not be equal" + ); + } + } + + #[proptest] + fn test_ord(left: RangeSet, right: RangeSet) { + assert_eq!( + left == right, + left.cmp(&right).is_eq(), + "ordering and equality must match" + ); + assert_eq!( + left.cmp(&right), + left.partial_cmp(&right).unwrap(), + "ordering is total for ordered parameters" + ); + } + #[test] fn test_from_array() { let mut set = RangeSet::new(); @@ -533,10 +589,7 @@ mod tests { } #[proptest] - fn test_union_overlaps_u8(left: Vec>, right: Vec>) { - let left: RangeSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeSet<_> = filter_ranges(right).into_iter().collect(); - + fn test_union_overlaps_u8(left: RangeSet, right: RangeSet) { let mut union = RangeSet::new(); for range in left.union(&right) { // there should not be any overlaps in the ranges returned by the union @@ -546,10 +599,8 @@ mod tests { } #[proptest] - fn test_union_contains_u8(left: Vec>, right: Vec>) { - let left: RangeSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeSet<_> = filter_ranges(right).into_iter().collect(); - let union: RangeSet<_> = left.union(&right).collect(); + fn test_union_contains_u8(left: RangeSet, right: RangeSet) { + let union = (&left) | (&right); // value should be in the union if and only if it is in either set for value in 0..u8::MAX { @@ -561,25 +612,20 @@ mod tests { } #[proptest] - fn test_intersection_contains_u8(left: Vec>, right: Vec>) { - let left: RangeSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeSet<_> = filter_ranges(right).into_iter().collect(); - let union: RangeSet<_> = left.intersection(&right).collect(); + fn test_intersection_contains_u8(left: RangeSet, right: RangeSet) { + let intersection = (&left) & (&right); - // value should be in the union if and only if it is in either set + // value should be in the intersection if and only if it is in both sets for value in 0..u8::MAX { assert_eq!( - union.contains(&value), + intersection.contains(&value), left.contains(&value) && right.contains(&value) ); } } #[proptest] - fn test_intersection_overlaps_u8(left: Vec>, right: Vec>) { - let left: RangeSet<_> = filter_ranges(left).into_iter().collect(); - let right: RangeSet<_> = filter_ranges(right).into_iter().collect(); - + fn test_intersection_overlaps_u8(left: RangeSet, right: RangeSet) { let mut union = RangeSet::new(); for range in left.intersection(&right) { // there should not be any overlaps in the ranges returned by the