Crate sample_std

Source
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 size isn’t really necessary in a world with sampling strategies.
  • The Random struct could probably just become a type definition around the underlying rng.

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.
ArbitrarySampler
Bridge for creating a Sample from an Arbitrary type.
ChainResample
See Sample::chain_resample.
Chained
Capture the seed used to generate the given value.
Chance
Generate a boolean value with the specified probability (in the range 0..=1).
Choice
See choice.
Gen
Gen represents a PRNG.
Random
Random represents a PRNG.
Regex
Sample strings given a “valid” regular expression.
SampleAll
See sample_all.
SamplerChoice
See sampler_choice.
TestResult
Describes the status of a single instance of a test.
TryConvert
See Sample::try_convert.
VecSampler
Sample a Vec with a length drawn from a usize Sample and elements drawn from the el sampler.
Zip
See Sample::zip.

Traits§

Arbitrary
Arbitrary describes types whose values can be randomly generated and shrunk.
Sample
User-defined strategies for generating and shrinking an Output type.
Testable
Testable describes types (e.g., a function) whose values can be tested.

Functions§

arbitrary
Sampler for any type implementing Arbitrary.
choice
Sample from a list of choice values.
sample_all
Use a Vec of samplers to generate a new Vec of equal length, where each sampler in the Vec is 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

Type Aliases§

Shrunk
An Iterator of “smaller” values derived from a given value.