BurntSushi / quickcheck

Automated property based testing for Rust (with shrinking).
The Unlicense
2.4k stars 149 forks source link

#[derive(Arbitrary)] #163

Closed emk closed 7 years ago

emk commented 7 years ago

Assuming we have a struct type:

#[derive(Clone)]
pub struct Rect {
    left: usize,
    top: usize,
    width: usize,
    height: usize,
}

…it's fairly mechanical to write an Arbitrary impl for it:

    impl Arbitrary for Rect {
        fn arbitrary<G: Gen>(g: &mut G) -> Self {
            let s = g.size();
            Rect {
                left: g.gen_range(0, s),
                top: g.gen_range(0, s),
                width: g.gen_range(0, s),
                height: g.gen_range(0, s),
            }
        }

        fn shrink(&self) -> Box<Iterator<Item=Self>> {
            let tuple = (self.left, self.top, self.width, self.height);
            Box::new(tuple.shrink().map(|(l, t, w, h)| Rect {
                left: l,
                top: t,
                width: w,
                height: h
            }))
        }
    }

It might be more general to also use a tuple let (left, top, width, bottom) = g.gen() in arbitrary, although that would need some constraints to ensure that left + width fits in a usize. But the basic idea seems to work, and it could be easily generalized to enums.

However, it would be even easier if I could write something like:

#[derive(Arbitrary, Clone)]
pub struct Rect {
    left: usize,
    top: usize,
    width: usize,
    height: usize,
}

This could be implemented for stable Rust using Macros 1.1. It would only work for types where correctness is enforced by the type system. Again, the challenge is what to do about constraints, such as the one on left + width not overflowing.

Does this seem like a desirable feature? It might be fun to poke at someday, if nobody beats me to it. :-)

BurntSushi commented 7 years ago

Nice writeup! I think this is desirable yes, assuming it doesn't require nightly Rust (which I think is true nowadays). But this has been a long wanted feature, which makes it a dupe of #98. :-)

emk commented 7 years ago

Hah! I looked for that but didn't see it. Thank you.