diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 897641a..e7418f0 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -1206,6 +1206,49 @@ impl Arbitrary for SystemTime { } } +/// Wrapper for disabling shrinking for an Arbitrary +/// +/// This type allows generating values via a given `Arbitrary` implementation +/// for a test for which we don't want to shrink input values. +/// +/// # Example +/// +/// ```rust +/// use quickcheck::{QuickCheck, NoShrink}; +/// +/// fn prop_sane_shrinker() { +/// // Yielding the original value will result in endless recursion +/// fn shrinker_no_self(value: NoShrink) -> bool { +/// use quickcheck::Arbitrary; +/// !value.as_ref().shrink().any(|v| v == *value.as_ref()) +/// } +/// QuickCheck::new().quickcheck(shrinker_no_self as fn(NoShrink) -> bool); +/// } +/// ``` +#[derive(Clone, Debug)] +pub struct NoShrink { + inner: A, +} + +impl NoShrink { + /// Unwrap the inner value + pub fn into_inner(self) -> A { + self.inner + } +} + +impl Arbitrary for NoShrink { + fn arbitrary(rnd: &mut Gen) -> Self { + Self { inner: Arbitrary::arbitrary(rnd) } + } +} + +impl AsRef for NoShrink { + fn as_ref(&self) -> &A { + &self.inner + } +} + #[cfg(test)] mod test { use std::collections::{ diff --git a/src/lib.rs b/src/lib.rs index d3a5ba4..8ff9a40 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,9 @@ new kind of witness being generated. These sorts of changes may happen in semver compatible releases. */ -pub use crate::arbitrary::{empty_shrinker, single_shrinker, Arbitrary, Gen}; +pub use crate::arbitrary::{ + empty_shrinker, single_shrinker, Arbitrary, Gen, NoShrink, +}; pub use crate::tester::{quickcheck, QuickCheck, TestResult, Testable}; /// A macro for writing quickcheck tests.