#quickcheck #derive #macro #arbitrary #data-structures

derive-quickcheck

自动为 derive 实现 quickcheck::Arbitrary

5 个版本

0.2.0 2023年7月2日
0.1.3 2023年6月27日
0.1.2 2023年6月27日
0.1.1 2023年5月20日
0.1.0 2023年5月20日

#776 in 测试

Download history 14/week @ 2024-03-28 16/week @ 2024-04-04

每月下载量:98
用于 rsmonad

MPL-2.0 许可证

74KB
1.5K SLoC

#[derive(QuickCheck)]

自动为任何数据结构实现 quickcheck::Arbitrary

规则

  • 对于 struct(或,一般而言,当你有一个类型集合的所有类型时),我们只需对每个类型调用 quickcheck::Arbitrary::arbitrary
  • 对于 enum(或,一般而言,当你有一个类型集合中的一个类型时),我们同等权重地考虑所有变体。
  • 所有类型参数(<A, ...>)都必须实现 quickcheck::Arbitrary。如果没有,结构体仍然可以在 quickcheck 之外工作,但你不能对其属性进行测试。
    • 注意事项:我们可能未来会检查你是否实际上使用了该类型参数,但到目前为止,我们还没有(例如,PhantomData<A> 仍然需要 <A: Arbitrary>)。

结构体

//                     vvvvvvvvvv
#[derive(Clone, Debug, QuickCheck)]
struct StructWithABunchOfEdgeCases<A, B, T, const N: usize> {
    a: A,
    b: B,
    t1: T,
    t2: T,
    t3: T,
}

自动写入以下内容

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),
    }
}

枚举

#[derive(Clone, Debug, QuickCheck)]
enum Enum<A, B, C> {
    First(A, B, C),
    Second(A, B, C),
    Third(A, B, C),
}

变为

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)
        }
    }

所有关于令人难以置信的 quickcheck 库的荣誉都归功于其作者,而不是我! :)

依赖项

~0.3–0.8MB
~19K SLoC