1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use proptest::{
    strategy::{Strategy, ValueTree},
    test_runner::{Config, TestRng, TestRunner},
};

/// Context for generating single values out of strategies.
///
/// Proptest is designed to be built around "value trees", which represent a spectrum from complex
/// values to simpler ones. But in some contexts, like benchmarking or generating corpuses, one just
/// wants a single value. This is a convenience struct for that.
#[derive(Default)]
pub struct ValueGenerator {
    runner: TestRunner,
}

impl ValueGenerator {
    /// Creates a new value generator with the default RNG.
    pub fn new() -> Self {
        Default::default()
    }

    /// Creates a new value generator with provided RNG
    pub fn new_with_rng(rng: TestRng) -> Self {
        Self {
            runner: TestRunner::new_with_rng(Config::default(), rng),
        }
    }

    /// Creates a new value generator with a deterministic RNG.
    ///
    /// This generator has a hardcoded seed, so its results are predictable across test runs.
    /// However, a new proptest version may change the seed.
    pub fn deterministic() -> Self {
        Self {
            runner: TestRunner::deterministic(),
        }
    }

    /// Generates a single value for this strategy.
    ///
    /// Panics if generating the new value fails. The only situation in which this can happen is if
    /// generating the value causes too many internal rejects.
    pub fn generate<S: Strategy>(&mut self, strategy: S) -> S::Value {
        strategy
            .new_tree(&mut self.runner)
            .expect("creating a new value should succeed")
            .current()
    }
}