Expand description
Core sampling strategies, along with useful implementations for samplers on
types from std and the quickcheck crate.
The core of this library is the Sample trait, which uses Random to
generate arbitrary values from a sampled Output type with a custom
“sampling strategy”. It also defines a procedure for “shrinking” generated
values, which can be used to generate simple counterexamples against
expected properties.
This library is generally intended for usage alongside the sample_test
crate. See that crate for macros and examples for using samplers within unit
tests.
§Sampling Strategies
The simplest Sample implementation is for Range. It is a sampler
that generates values uniformly from the given range, and attempts to shrink
down to the start of the range:
use sample_std::{Sample, Random};
let mut s = 10..100;
let v = s.generate(&mut Random::new());
assert!(s.contains(&v));
let mut shrunk = s.shrink(v);
assert_eq!(shrunk.next(), Some(s.start));
if v > s.start {
assert!(shrunk.next().unwrap() < v)
}Samplers are defined for tuples of samplers up to size 8, which can be
used in concert with Sample::try_convert to combine samplers into a
sampler for a larger type:
use sample_std::{Chance, Sample, VecSampler, choice};
struct Large {
values: Vec<usize>,
is_blue: bool,
name: String,
}
let sampler = (
VecSampler { length: 0..10, el: 5..20 },
Chance(0.5),
choice(["cora".to_string(), "james".to_string()])
).try_convert(
|(values, is_blue, name)| Large { values, is_blue, name },
|large| Some((large.values, large.is_blue, large.name))
);For an example of sampling an enum, see sampler_choice.
§Prior Work
This crate is heavily inspired by quickcheck. It builds upon it, in
particular by defining samplers for Arbitrary (see arbitrary). Many
methods and structs in here were derived from their quickcheck
counterparts.
It attempts to iterate and improve on the quickcheck core idea:
- Allow definition of multiple sampling strategies for the same type.
- No need to define newtypes for custom sampling strategies.
There is still some cruft and weirdness from this early attempt to combine these worldviews:
- The concept of
sizeisn’t really necessary in a world with sampling strategies. - The
Randomstruct could probably just become a type definition around the underlyingrng.
The core idea for sampling “strategies” comes from proptest, which
uses macros instead of combinators for composition, and has more complex
shrinking functionality.
Re-exports§
pub use rand;
Modules§
- recursive
- Some simple helpers for recursive sampling.
Structs§
- Always
- Sampler that always generates a fixed value.
- Arbitrary
Sampler - Bridge for creating a
Samplefrom anArbitrarytype. - Chain
Resample - See
Sample::chain_resample. - Chained
- Capture the
seedused to generate the givenvalue. - Chance
- Generate a boolean value with the specified probability (in the range
0..=1). - Choice
- See choice.
- Gen
- Gen represents a PRNG.
- Random
Randomrepresents a PRNG.- Regex
- Sample strings given a “valid” regular expression.
- Sample
All - See
sample_all. - Sampler
Choice - See
sampler_choice. - Test
Result - Describes the status of a single instance of a test.
- TryConvert
- See
Sample::try_convert. - VecSampler
- Sample a
Vecwith a length drawn from ausizeSampleand elements drawn from theelsampler. - Zip
- See
Sample::zip.
Traits§
- Arbitrary
Arbitrarydescribes types whose values can be randomly generated and shrunk.- Sample
- User-defined strategies for generating and shrinking an
Outputtype. - Testable
Testabledescribes types (e.g., a function) whose values can be tested.
Functions§
- arbitrary
- Sampler for any type implementing
Arbitrary. - choice
- Sample from a list of
choicevalues. - sample_
all - Use a
Vecofsamplersto generate a newVecof equal length, where each sampler in theVecis used to sample the value at its corresponding position. - sampler_
choice - Sample values from a sampler randomly drawn from a list of
choices. - valid_
f32 - Sampler for non-NaN f32
- valid_
f64 - Sampler for non-NaN f64