diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 92f893b..b66ebbc 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. @@ -62,6 +80,17 @@ impl Gen { slice.choose(&mut self.rng) } + /// Creates a generator suitable for recursion. + /// + /// The returned generator's size will be the origianl gnerator's size + /// divided by n. In addition, the new generator will be seeded from the + /// original. + pub fn sub(&mut self, num: NonZeroUsize) -> Self { + let mut res = Self::from_seed(self.gen()); + res.set_size(self.size() / num); + res + } + fn gen(&mut self) -> T where rand::distributions::Standard: rand::distributions::Distribution, diff --git a/src/tester.rs b/src/tester.rs index e2eaa20..e639973 100644 --- a/src/tester.rs +++ b/src/tester.rs @@ -33,7 +33,7 @@ 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, diff --git a/src/tests.rs b/src/tests.rs index 465ef15..9086e6b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -255,6 +255,12 @@ fn all_tests_discarded_min_tests_passed_missing() { } quickcheck! { + /// The documentation on `Gen::sub_n` adversizes some easy-to-check property + /// regarding the generators' sizes. + fn gen_sub_size_sum(original: usize, num: std::num::NonZeroUsize) -> bool { + Gen::new(original).sub(num).size() * num.get() <= original + } + /// The following is a very simplistic test, which only verifies /// that our PathBuf::arbitrary does not panic. Still, that's /// something! :)