5 releases
0.2.0 | Jul 2, 2023 |
---|---|
0.1.3 | Jun 27, 2023 |
0.1.2 | Jun 27, 2023 |
0.1.1 | May 20, 2023 |
0.1.0 | May 20, 2023 |
#981 in Testing
Used in rsmonad
74KB
1.5K
SLoC
#[derive(QuickCheck)]
Automatically implements quickcheck::Arbitrary
for any data structure.
Rules:
- For
struct
s (or, generally, when you have all of a collection of types), we simply callquickcheck::Arbitrary::arbitrary
on each. - For
enum
s (or, generally, when you have one of a collection of types), we weight all variants equally. - All type parameters (
<A, ...>
) must implementquickcheck::Arbitrary
. If not, the struct will still work outsidequickcheck
, but you can't property-test it.- Caveat: We might in the future check if you actually use that type parameter, but for now, we don't (e.g.
PhantomData<A>
still requires<A: Arbitrary>
).
- Caveat: We might in the future check if you actually use that type parameter, but for now, we don't (e.g.
Structs
// vvvvvvvvvv
#[derive(Clone, Debug, QuickCheck)]
struct StructWithABunchOfEdgeCases<A, B, T, const N: usize> {
a: A,
b: B,
t1: T,
t2: T,
t3: T,
}
automatically writes the following:
impl<
A: ::quickcheck::Arbitrary,
B: ::quickcheck::Arbitrary,
T: ::quickcheck::Arbitrary,
const N: usize, // recognizes this is not a type
> ::quickcheck::Arbitrary for StructWithABunchOfEdgeCases<A, B, T, { N }> {
#[inline]
fn arbitrary(g: &mut ::quickcheck::Gen) -> Self {
a: <A as ::quickcheck::Arbitrary>::arbitrary(g),
b: <B as ::quickcheck::Arbitrary>::arbitrary(g),
t1: <T as ::quickcheck::Arbitrary>::arbitrary(g),
t2: <T as ::quickcheck::Arbitrary>::arbitrary(g),
t3: <T as ::quickcheck::Arbitrary>::arbitrary(g),
}
}
Enums
#[derive(Clone, Debug, QuickCheck)]
enum Enum<A, B, C> {
First(A, B, C),
Second(A, B, C),
Third(A, B, C),
}
becomes
impl<
A: ::quickcheck::Arbitrary,
B: ::quickcheck::Arbitrary,
C: ::quickcheck::Arbitrary,
> ::quickcheck::Arbitrary for Enum<A, B, C> {
#[inline]
fn arbitrary(g: &mut ::quickcheck::Gen) -> Self {
g.choose::<fn(&mut ::quickcheck::Gen) -> Self>(&[
(move |g| Self::First(
<A as ::quickcheck::Arbitrary>::arbitrary(g),
<B as ::quickcheck::Arbitrary>::arbitrary(g),
<C as ::quickcheck::Arbitrary>::arbitrary(g),
)) as fn(&mut ::quickcheck::Gen) -> Self,
(move |g| Self::Second(
<A as ::quickcheck::Arbitrary>::arbitrary(g),
<B as ::quickcheck::Arbitrary>::arbitrary(g),
<C as ::quickcheck::Arbitrary>::arbitrary(g),
)) as fn(&mut ::quickcheck::Gen) -> Self,
(move |g| Self::Third(
<A as ::quickcheck::Arbitrary>::arbitrary(g),
<B as ::quickcheck::Arbitrary>::arbitrary(g),
<C as ::quickcheck::Arbitrary>::arbitrary(g),
)) as fn(&mut ::quickcheck::Gen) -> Self,
]).unwrap()(g)
}
}
All credit for the incredible quickcheck
library goes to its authors, not me! :)
Dependencies
~290–730KB
~17K SLoC