diff --git a/Cargo.toml b/Cargo.toml index 3a95b21..9cd7f85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ categories = ["data-structures"] rust-version = "1.66.0" [dependencies] +quickcheck = { version = "1.0.3", optional = true } serde = { version = "1", optional = true } [dev-dependencies] @@ -42,6 +43,7 @@ nightly = [] # Requires a nightly compiler because `const_btree_new` is an unstable feature, # but is soon to be stabilized: const_fn = [] +quickcheck = ["dep:quickcheck"] [[bench]] name = "benches" diff --git a/src/inclusive_map.rs b/src/inclusive_map.rs index 34724f6..6ba7e03 100644 --- a/src/inclusive_map.rs +++ b/src/inclusive_map.rs @@ -103,6 +103,21 @@ where } } +#[cfg(feature = "quickcheck")] +impl quickcheck::Arbitrary for RangeInclusiveMap +where + K: quickcheck::Arbitrary + Ord + StepLite, + V: quickcheck::Arbitrary + Eq, +{ + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + // REVISIT: allocation could be avoided if Gen::gen_size were public (https://github.com/BurntSushi/quickcheck/issues/326#issue-2653601170) + , _)>>::arbitrary(g) + .into_iter() + .filter(|(range, _)| !range.is_empty()) + .collect() + } +} + impl RangeInclusiveMap { /// Gets an iterator over all pairs of key range and value, /// ordered by key range. @@ -1920,4 +1935,11 @@ mod tests { const _MAP: RangeInclusiveMap = RangeInclusiveMap::new(); #[cfg(feature = "const_fn")] const _MAP2: RangeInclusiveMap = RangeInclusiveMap::new_with_step_fns(); + + #[cfg(feature = "quickcheck")] + quickcheck::quickcheck! { + fn prop(xs: RangeInclusiveMap) -> bool { + xs == xs + } + } } diff --git a/src/inclusive_set.rs b/src/inclusive_set.rs index 46bb8f7..ab5189a 100644 --- a/src/inclusive_set.rs +++ b/src/inclusive_set.rs @@ -39,6 +39,18 @@ impl Default for RangeInclusiveSet { } } +#[cfg(feature = "quickcheck")] +impl quickcheck::Arbitrary for RangeInclusiveSet +where + K: quickcheck::Arbitrary + Ord + StepLite, +{ + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + Self { + rm: RangeInclusiveMap::arbitrary(g), + } + } +} + impl RangeInclusiveSet where T: Ord + Clone + StepLite, @@ -827,4 +839,11 @@ mod tests { const _SET: RangeInclusiveSet = RangeInclusiveSet::new(); #[cfg(feature = "const_fn")] const _SET2: RangeInclusiveSet = RangeInclusiveSet::new_with_step_fns(); + + #[cfg(feature = "quickcheck")] + quickcheck::quickcheck! { + fn prop(xs: RangeInclusiveSet) -> bool { + xs == xs + } + } } diff --git a/src/map.rs b/src/map.rs index d56b274..0b89343 100644 --- a/src/map.rs +++ b/src/map.rs @@ -83,6 +83,21 @@ where } } +#[cfg(feature = "quickcheck")] +impl quickcheck::Arbitrary for RangeMap +where + K: quickcheck::Arbitrary + Ord, + V: quickcheck::Arbitrary + Eq, +{ + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + // REVISIT: allocation could be avoided if Gen::gen_size were public (https://github.com/BurntSushi/quickcheck/issues/326#issue-2653601170) + , _)>>::arbitrary(g) + .into_iter() + .filter(|(range, _)| !range.is_empty()) + .collect() + } +} + impl RangeMap { /// Makes a new empty `RangeMap`. #[cfg(feature = "const_fn")] @@ -1818,4 +1833,11 @@ mod tests { #[cfg(feature = "const_fn")] const _MAP: RangeMap = RangeMap::new(); + + #[cfg(feature = "quickcheck")] + quickcheck::quickcheck! { + fn prop(xs: RangeMap) -> bool { + xs == xs + } + } } diff --git a/src/set.rs b/src/set.rs index 549e60d..6a52520 100644 --- a/src/set.rs +++ b/src/set.rs @@ -39,6 +39,18 @@ impl Default for RangeSet { } } +#[cfg(feature = "quickcheck")] +impl quickcheck::Arbitrary for RangeSet +where + K: quickcheck::Arbitrary + Ord, +{ + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + Self { + rm: RangeMap::arbitrary(g), + } + } +} + impl RangeSet where T: Ord + Clone, @@ -793,4 +805,11 @@ mod tests { #[cfg(feature = "const_fn")] const _SET: RangeSet = RangeSet::new(); + + #[cfg(feature = "quickcheck")] + quickcheck::quickcheck! { + fn prop(xs: RangeSet) -> bool { + xs == xs + } + } }