BurntSushi / quickcheck

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

Most idiomatic way to implement Arbitrary on only a subset of a basic type #179

Closed NobbZ closed 4 years ago

NobbZ commented 7 years ago

I do currently have the situation, that I wan't to have an arbitrary String which does only contain basic latin letters in upper and lowercase, as well as numbers (each generated String has to match the regular expression ~/[a-zA-Z0-9]+/.

Generating them was fairly easy. Something along g.gen_ascii_chars().take(len).collect().

But I am absolutely without any clue how to shrink them correctly. If I follow the usual String.shrink, it will shrink everything into "\{0}", which of course fails but isn't a valid value anyway. If I though use empty-shrinks, I will get the first failed string with a lot of noise.

So what is the best way to deal with such a situation?

PS: I might be able to give out some more and complete example code later this day, but currently I am not on the computer that has my toy-project available.

BurntSushi commented 7 years ago

Unfortunately there's nothing particularly easy here. I guess there are various approaches you can take.

First, write your own shrinker, maybe by starting with copying the one in this crate.

Second, come up with a more general purpose shrinker that can be configured and contribute it to this crate.

Third, use the existing shrinker, and do post filtering to remove or replace chars you don't want. This is probably the easiest path, but it's a little hacky.