im_rc/proptest.rs
1//! Proptest strategies.
2//!
3//! These are only available when using the `proptest` feature flag.
4
5use crate::{HashMap, HashSet, OrdMap, OrdSet, Vector};
6use ::proptest::collection::vec;
7use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree};
8use std::hash::Hash;
9use std::iter::FromIterator;
10use std::ops::Range;
11
12/// A strategy for generating a [`Vector`][Vector] of a certain size.
13///
14/// # Examples
15///
16/// ```rust,no_run
17/// # use ::proptest::proptest;
18/// proptest! {
19/// #[test]
20/// fn proptest_a_vector(ref l in vector(".*", 10..100)) {
21/// assert!(l.len() < 100);
22/// assert!(l.len() >= 10);
23/// }
24/// }
25/// ```
26///
27/// [Vector]: ../struct.Vector.html
28pub fn vector<A: Strategy + 'static>(
29 element: A,
30 size: Range<usize>,
31) -> BoxedStrategy<Vector<<A::Tree as ValueTree>::Value>>
32where
33 <A::Tree as ValueTree>::Value: Clone,
34{
35 vec(element, size).prop_map(Vector::from_iter).boxed()
36}
37
38/// A strategy for an [`OrdMap`][OrdMap] of a given size.
39///
40/// # Examples
41///
42/// ```rust,no_run
43/// # use ::proptest::proptest;
44/// proptest! {
45/// #[test]
46/// fn proptest_works(ref m in ord_map(0..9999, ".*", 10..100)) {
47/// assert!(m.len() < 100);
48/// assert!(m.len() >= 10);
49/// }
50/// }
51/// ```
52///
53/// [OrdMap]: ../struct.OrdMap.html
54pub fn ord_map<K: Strategy + 'static, V: Strategy + 'static>(
55 key: K,
56 value: V,
57 size: Range<usize>,
58) -> BoxedStrategy<OrdMap<<K::Tree as ValueTree>::Value, <V::Tree as ValueTree>::Value>>
59where
60 <K::Tree as ValueTree>::Value: Ord + Clone,
61 <V::Tree as ValueTree>::Value: Clone,
62{
63 ::proptest::collection::vec((key, value), size.clone())
64 .prop_map(OrdMap::from)
65 .prop_filter("OrdMap minimum size".to_owned(), move |m| {
66 m.len() >= size.start
67 })
68 .boxed()
69}
70
71/// A strategy for an [`OrdSet`][OrdSet] of a given size.
72///
73/// # Examples
74///
75/// ```rust,no_run
76/// # use ::proptest::proptest;
77/// proptest! {
78/// #[test]
79/// fn proptest_a_set(ref s in ord_set(".*", 10..100)) {
80/// assert!(s.len() < 100);
81/// assert!(s.len() >= 10);
82/// }
83/// }
84/// ```
85///
86/// [OrdSet]: ../struct.OrdSet.html
87pub fn ord_set<A: Strategy + 'static>(
88 element: A,
89 size: Range<usize>,
90) -> BoxedStrategy<OrdSet<<A::Tree as ValueTree>::Value>>
91where
92 <A::Tree as ValueTree>::Value: Ord + Clone,
93{
94 ::proptest::collection::vec(element, size.clone())
95 .prop_map(OrdSet::from)
96 .prop_filter("OrdSet minimum size".to_owned(), move |s| {
97 s.len() >= size.start
98 })
99 .boxed()
100}
101
102/// A strategy for a [`HashMap`][HashMap] of a given size.
103///
104/// # Examples
105///
106/// ```rust,no_run
107/// # use ::proptest::proptest;
108/// proptest! {
109/// #[test]
110/// fn proptest_works(ref m in hash_map(0..9999, ".*", 10..100)) {
111/// assert!(m.len() < 100);
112/// assert!(m.len() >= 10);
113/// }
114/// }
115/// ```
116///
117/// [HashMap]: ../struct.HashMap.html
118pub fn hash_map<K: Strategy + 'static, V: Strategy + 'static>(
119 key: K,
120 value: V,
121 size: Range<usize>,
122) -> BoxedStrategy<HashMap<<K::Tree as ValueTree>::Value, <V::Tree as ValueTree>::Value>>
123where
124 <K::Tree as ValueTree>::Value: Hash + Eq + Clone,
125 <V::Tree as ValueTree>::Value: Clone,
126{
127 ::proptest::collection::vec((key, value), size.clone())
128 .prop_map(HashMap::from)
129 .prop_filter("Map minimum size".to_owned(), move |m| {
130 m.len() >= size.start
131 })
132 .boxed()
133}
134
135/// A strategy for a [`HashSet`][HashSet] of a given size.
136///
137/// # Examples
138///
139/// ```rust,no_run
140/// # use ::proptest::proptest;
141/// proptest! {
142/// #[test]
143/// fn proptest_a_set(ref s in hash_set(".*", 10..100)) {
144/// assert!(s.len() < 100);
145/// assert!(s.len() >= 10);
146/// }
147/// }
148/// ```
149///
150/// [HashSet]: ../struct.HashSet.html
151pub fn hash_set<A: Strategy + 'static>(
152 element: A,
153 size: Range<usize>,
154) -> BoxedStrategy<HashSet<<A::Tree as ValueTree>::Value>>
155where
156 <A::Tree as ValueTree>::Value: Hash + Eq + Clone,
157{
158 ::proptest::collection::vec(element, size.clone())
159 .prop_map(HashSet::from)
160 .prop_filter("HashSet minimum size".to_owned(), move |s| {
161 s.len() >= size.start
162 })
163 .boxed()
164}