A safe, efficient and simple QuickCheck inspired library to generate shrinkable random data mainly oriented towards generative/property/exploratory testing.
One would use this library to prove more general properties about a program than unit tests can by strategically searching the input space for comprehensible failing cases.
Main Traits:
Generate: is implemented for many of rust's standard types and allows the generation of any random composite/structured data through combinator (such as tuples,Any,Map,Flattenand more). It is designed for composability and its usage should feel like working withIterators.Shrink: tries to reduce a generated sample to a 'smaller' version of it while maintaining its constraints (ex: a sampleusizein the range10..100will never be shrunk below10). For numbers, it means bringing the sample closer to 0, for vectors, it means removing irrelevant items and shrinking the remaining ones, and so on.Prove: represents a desirable property of a program under test. It is used mainly in the context of theGenerate::checkorChecker::checkmethods and it is the failure of a proof that triggers the shrinking process. It is implemented for a couple of standard types such as(),boolandResult. Apanic!()is also considered as a failing property, thus standardassert!()macros (or any other panicking assertions) can be used to check the property.
To ensure safety, this library is #![forbid(unsafe_code)].
Cheat sheet
use *;
/// The builtin `letter()` generator will yield ascii letters.
///
/// This test will be run many times with different generated values to find a
/// failing input.
/// Ranges can be used as generators and will yield values within its bounds.
///
/// A [`bool`] can be returned and if `true`, it will be considered as evidence
/// that the property under test holds.
/// Regexes can be used and validated at compile-time with the [`regex!`] macro.
///
/// Usual panicking assertions can be used in the body of the checking function
/// since a panic is considered a failed property.
/// An empty `#[check]` attribute acts just like `#[test]`. It exists for
/// consistency between tests.
/// The `_` and `..` operators can be used to infer the [`FullGenerate`]
/// generator implementation for a type.
///
/// Since this test will panic, `#[should_panic]` can be used in the usual way.
/// `color = false` disables coloring of the output.
/// `verbose = true` will display all the steps taken by the [`check::Checker`]
/// while generating and shrinking values.
///
/// The shrinking process is pretty good at finding minimal inputs to reproduce
/// a failing property and in this case, it will always shrink values over
/// `1000` to exactly `1000`.
/// Multiple checks can be performed.
///
/// If all generators always yield the same value, the check becomes a
/// parameterized unit test and will run only once.
/// Generics can be used as inputs to the checking function.
///
/// [`Generate::map`] can be used to map a value to another.
/// Use tuples to combine generators and build more complex structured types.
/// Alternatively implement the [`FullGenerate`] trait for the [`Person`]
/// struct.
///
/// Any generator combinator can be used here; see the other examples in the
/// _examples_ folder for more details.
///
/// Disable `debug` if a generated type does not implement [`Debug`] which
/// removes the only requirement that `#[check]` requires from input types.
/// The `#[check]` attribute essentially expands to a check to [`Check::check`]
/// with pretty printing. For some more complex scenarios, it becomes more
/// convenient to simply call the [`ChecK::check`] manually.
///
/// The [`Generate::any`] combinator chooses from its inputs. The produced
/// `Or<..>` preserves the information about the choice but here, it can be
/// simply collapsed using `Or<..>::into::<T>()`.
See the examples and tests folder for more detailed examples.