diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 92f893b..26b0be8 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -39,15 +39,33 @@ pub struct Gen { } impl Gen { - /// Returns a `Gen` with the given size configuration. + pub(crate) const DEFAULT_SIZE: usize = 100; + + /// Returns a `Gen` with a random seed and the given size configuration. + pub fn new(size: usize) -> Gen { + Gen { rng: rand::rngs::SmallRng::from_entropy(), size: size } + } + + /// Returns a `Gen` with the given seed and a default size configuration. + /// + /// Two `Gen`s created with the same seed will generate the same values. Though the values + /// may vary between QuickCheck releases. + pub fn from_seed(seed: u64) -> Gen { + Gen { + rng: rand::rngs::SmallRng::seed_from_u64(seed), + size: Self::DEFAULT_SIZE, + } + } + + /// Sets the size configuration for this generator. /// /// The `size` parameter controls the size of random values generated. /// For example, it specifies the maximum length of a randomly generated /// vector, but is and should not be used to control the range of a /// randomly generated number. (Unless that number is used to control the /// size of a data structure.) - pub fn new(size: usize) -> Gen { - Gen { rng: rand::rngs::SmallRng::from_entropy(), size: size } + pub fn set_size(&mut self, size: usize) { + self.size = size; } /// Returns the size configured with this generator. diff --git a/src/tester.rs b/src/tester.rs index e2eaa20..723cfbe 100644 --- a/src/tester.rs +++ b/src/tester.rs @@ -33,13 +33,17 @@ fn qc_max_tests() -> u64 { } fn qc_gen_size() -> usize { - let default = 100; + let default = Gen::DEFAULT_SIZE; match env::var("QUICKCHECK_GENERATOR_SIZE") { Ok(val) => val.parse().unwrap_or(default), Err(_) => default, } } +fn qc_seed() -> Option { + env::var("QUICKCHECK_SEED").ok().and_then(|v| u64::from_str_radix(v.as_ref(), 16).ok()) +} + fn qc_min_tests_passed() -> u64 { let default = 0; match env::var("QUICKCHECK_MIN_TESTS_PASSED") { @@ -55,11 +59,27 @@ impl QuickCheck { /// You may also adjust the configuration, such as the number of tests to /// run. /// - /// By default, the maximum number of passed tests is set to `100`, the max - /// number of overall tests is set to `10000` and the generator is created - /// with a size of `100`. + /// The instance is initialized with the following configuration: + /// + /// * The maximum number of passed tests is initialized from the env var + /// `QUICKCHECK_TESTS`. This value defaults to `100`. + /// * The maximum number of overall tests is initialized from the env var + /// `QUICKCHECK_MAX_TESTS`. This value defaults to `10000`. + /// * The generator is initialized with a size specified in the env var + /// `QUICKCHECK_GENERATOR_SIZE`. The size defaults to `100`. + /// * If the env var `QUICKCHECK_SEED` is present and contains a + /// hexadecimal number, its value is used to seed the generator. + /// * The minimum number of valid tests which need to pass (i.e. excluding + /// discarded ones) is initialized from the env var + /// `QUICKCHECK_MIN_TESTS_PASSED`. This defaults to `0`. pub fn new() -> QuickCheck { - let gen = Gen::new(qc_gen_size()); + let gen = if let Some(seed) = qc_seed() { + let mut g = Gen::from_seed(seed); + g.set_size(qc_gen_size()); + g + } else { + Gen::new(qc_gen_size()) + }; let tests = qc_tests(); let max_tests = cmp::max(tests, qc_max_tests()); let min_tests_passed = qc_min_tests_passed();