Trait ValueTree
pub trait ValueTree
A generated value and its associated shrinker.
Conceptually, a ValueTree represents a spectrum between a "minimally
complex" value and a starting, randomly-chosen value. For values such as
numbers, this can be thought of as a simple binary search, and this is how
the ValueTree state machine is defined.
The ValueTree state machine notionally has three fields: low, current,
and high. Initially, low is the "minimally complex" value for the type, and
high and current are both the initially chosen value. It can be queried for
its current state. When shrinking, the controlling code tries simplifying
the value one step. If the test failure still happens with the simplified
value, further simplification occurs. Otherwise, the code steps back up
towards the prior complexity.
The main invariants here are that the "high" value always corresponds to a
failing test case, and that repeated calls to complicate() will return
false only once the "current" value has returned to what it was before
the last call to simplify().
While it would be possible for default do-nothing implementations of
simplify() and complicate() to be provided, this was not done
deliberately since the majority of strategies will want to define their own
shrinking anyway, and the minority that do not must call it out explicitly
by their own implementation.
Associated Types
type Value: Debug;The type of the value produced by this
ValueTree.
Required Methods
fn current(&self) -> Self::ValueReturns the current value.
fn simplify(&mut self) -> boolAttempts to simplify the current value. Notionally, this sets the "high" value to the current value, and the current value to a "halfway point" between high and low, rounding towards low.
Returns whether any state changed as a result of this call. This does not necessarily imply that the value of
current()has changed, since in the most general case, it is not possible for an implementation to determine this.This call needs to correctly handle being called even immediately after it had been called previously and returned
false.fn complicate(&mut self) -> boolAttempts to partially undo the last simplification. Notionally, this sets the "low" value to one plus the current value, and the current value to a "halfway point" between high and the new low, rounding towards low.
Returns whether any state changed as a result of this call. This does not necessarily imply that the value of
current()has changed, since in the most general case, it is not possible for an implementation to determine this.It is usually expected that, immediately after a call to
simplify()which returns true, this call will itself return true. However, this is not always the case; in some strategies, particularly those that use some form of rejection sampling, the act of trying to simplify may change the state such thatsimplify()returns true, yet ultimately left the resulting value unchanged, in which case there is nothing left to complicate.This call does not need to gracefully handle being called before
simplify()was ever called, but does need to correctly handle being called even immediately after it had been called previously and returnedfalse.
Implementors
impl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BinarySearchimpl ValueTree for BoolValueTreeimpl ValueTree for CharValueTreeimpl ValueTree for IndexValueTreeimpl ValueTree for SelectorValueTreeimpl<A: Strategy, B: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>, F: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>, Option<LazyValueTree<F>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>, F: Strategy<Value = A::Value>, G: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>, Option<LazyValueTree<F>>, Option<LazyValueTree<G>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>, F: Strategy<Value = A::Value>, G: Strategy<Value = A::Value>, H: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>, Option<LazyValueTree<F>>, Option<LazyValueTree<G>>, Option<LazyValueTree<H>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>, F: Strategy<Value = A::Value>, G: Strategy<Value = A::Value>, H: Strategy<Value = A::Value>, I: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>, Option<LazyValueTree<F>>, Option<LazyValueTree<G>>, Option<LazyValueTree<H>>, Option<LazyValueTree<I>>)>impl<A: Strategy, B: Strategy<Value = A::Value>, C: Strategy<Value = A::Value>, D: Strategy<Value = A::Value>, E: Strategy<Value = A::Value>, F: Strategy<Value = A::Value>, G: Strategy<Value = A::Value>, H: Strategy<Value = A::Value>, I: Strategy<Value = A::Value>, J: Strategy<Value = A::Value>> ValueTree for TupleUnionValueTree<(LazyValueTree<A>, Option<LazyValueTree<B>>, Option<LazyValueTree<C>>, Option<LazyValueTree<D>>, Option<LazyValueTree<E>>, Option<LazyValueTree<F>>, Option<LazyValueTree<G>>, Option<LazyValueTree<H>>, Option<LazyValueTree<I>>, Option<LazyValueTree<J>>)>impl<A: ValueTree> ValueTree for TupleValueTree<(A,)>impl<A: ValueTree, B: ValueTree> ValueTree for TupleValueTree<(A, B)>impl<A: ValueTree, B: ValueTree, C: ValueTree> ValueTree for TupleValueTree<(A, B, C)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree> ValueTree for TupleValueTree<(A, B, C, D)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree, H: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G, H)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree, H: ValueTree, I: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G, H, I)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree, H: ValueTree, I: ValueTree, J: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G, H, I, J)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree, H: ValueTree, I: ValueTree, J: ValueTree, K: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G, H, I, J, K)>impl<A: ValueTree, B: ValueTree, C: ValueTree, D: ValueTree, E: ValueTree, F: ValueTree, G: ValueTree, H: ValueTree, I: ValueTree, J: ValueTree, K: ValueTree, L: ValueTree> ValueTree for TupleValueTree<(A, B, C, D, E, F, G, H, I, J, K, L)>impl<K, V> ValueTree for BTreeMapValueTree<K, V> where K: ValueTree, V: ValueTree, K::Value: Ord,impl<K, V> ValueTree for HashMapValueTree<K, V> where K: ValueTree, V: ValueTree, K::Value: Hash + Eq,impl<S: ValueTree> ValueTree for FlattenValueTree<S> where S::Value: Strategy,impl<S: ValueTree, F: FilterFn<S::Value>> ValueTree for Filter<S, F>impl<S: ValueTree, F: Fn(&S::Value) -> bool> ValueTree for Filter<S, F>impl<S: ValueTree, F: MapFn<S::Value>> ValueTree for Map<S, F>impl<S: ValueTree, O: Debug> ValueTree for MapInto<S, O> where S::Value: Into<O>,impl<S: ValueTree, O: Debug, F: Fn(S::Value) -> O> ValueTree for Map<S, F>impl<S: ValueTree, O: Debug, F: Fn(S::Value, TestRng) -> O> ValueTree for PerturbValueTree<S, F>impl<T> ValueTree for BTreeSetValueTree<T> where T: ValueTree, T::Value: Ord,impl<T> ValueTree for BinaryHeapValueTree<T> where T: ValueTree, T::Value: Ord,impl<T> ValueTree for HashSetValueTree<T> where T: ValueTree, T::Value: Hash + Eq,impl<T> ValueTree for LinkedListValueTree<T> where T: ValueTree,impl<T> ValueTree for OptionValueTree<T> where T: Strategy,impl<T> ValueTree for RangeSubsetValueTree<T> where T: Copy + Eq + Hash + Debug, Range<T>: ExactSizeIterator<Item = T>,impl<T> ValueTree for RegexGeneratorValueTree<T> where T: Debug,impl<T> ValueTree for SelectValueTree<T> where T: Clone + Debug + 'static,impl<T> ValueTree for VecDequeValueTree<T> where T: ValueTree,impl<T, E> ValueTree for MaybeErrValueTree<T, E> where T: Strategy, E: Strategy,impl<T, E> ValueTree for MaybeOkValueTree<T, E> where T: Strategy, E: Strategy,impl<T: BitSetLike> ValueTree for BitSetValueTree<T>impl<T: Clone + Debug> ValueTree for Just<T>impl<T: Debug + Clone + 'static> ValueTree for SubsequenceValueTree<T>impl<T: Debug> ValueTree for fn() -> Timpl<T: Debug, F: Fn() -> T> ValueTree for LazyJust<T, F>impl<T: Strategy> ValueTree for UnionValueTree<T>impl<T: ValueTree + ?Sized> ValueTree for Box<T>impl<T: ValueTree> ValueTree for Fuse<T>impl<T: ValueTree> ValueTree for NoShrink<T>impl<T: ValueTree> ValueTree for VecValueTree<T>impl<T: ValueTree, const N: usize> ValueTree for ArrayValueTree<[T; N]>impl<V: ValueTree> ValueTree for ShuffleValueTree<V> where V::Value: Shuffleable,impl<V: ValueTree, F: Fn(V::Value) -> Option<O>, O: Debug> ValueTree for FilterMapValueTree<V, F, O>