• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use {
2     super::{Arbitrary, Result, Unstructured},
3     std::{collections::HashSet, fmt::Debug, hash::Hash, rc::Rc, sync::Arc},
4 };
5 
6 /// Assert that the given expected values are all generated.
7 ///
8 /// Exhaustively enumerates all buffers up to length 10 containing the
9 /// following bytes: `0x00`, `0x01`, `0x61` (aka ASCII 'a'), and `0xff`
assert_generates<T>(expected_values: impl IntoIterator<Item = T>) where T: Clone + Debug + Hash + Eq + for<'a> Arbitrary<'a>,10 fn assert_generates<T>(expected_values: impl IntoIterator<Item = T>)
11 where
12     T: Clone + Debug + Hash + Eq + for<'a> Arbitrary<'a>,
13 {
14     let expected_values: HashSet<_> = expected_values.into_iter().collect();
15     let mut arbitrary_expected = expected_values.clone();
16     let mut arbitrary_take_rest_expected = expected_values;
17 
18     let bytes = [0, 1, b'a', 0xff];
19     let max_len = 10;
20 
21     let mut buf = Vec::with_capacity(max_len);
22 
23     let mut g = exhaustigen::Gen::new();
24     while !g.done() {
25         let len = g.gen(max_len);
26 
27         buf.clear();
28         buf.extend(
29             std::iter::repeat_with(|| {
30                 let index = g.gen(bytes.len() - 1);
31                 bytes[index]
32             })
33             .take(len),
34         );
35 
36         let mut u = Unstructured::new(&buf);
37         let val = T::arbitrary(&mut u).unwrap();
38         arbitrary_expected.remove(&val);
39 
40         let u = Unstructured::new(&buf);
41         let val = T::arbitrary_take_rest(u).unwrap();
42         arbitrary_take_rest_expected.remove(&val);
43 
44         if arbitrary_expected.is_empty() && arbitrary_take_rest_expected.is_empty() {
45             return;
46         }
47     }
48 
49     panic!(
50         "failed to generate all expected values!\n\n\
51          T::arbitrary did not generate: {arbitrary_expected:#?}\n\n\
52          T::arbitrary_take_rest did not generate {arbitrary_take_rest_expected:#?}"
53     )
54 }
55 
56 /// Generates an arbitrary `T`, and checks that the result is consistent with the
57 /// `size_hint()` reported by `T`.
checked_arbitrary<'a, T: Arbitrary<'a>>(u: &mut Unstructured<'a>) -> Result<T>58 fn checked_arbitrary<'a, T: Arbitrary<'a>>(u: &mut Unstructured<'a>) -> Result<T> {
59     let (min, max) = T::size_hint(0);
60 
61     let len_before = u.len();
62     let result = T::arbitrary(u);
63 
64     let consumed = len_before - u.len();
65 
66     if let Some(max) = max {
67         assert!(
68             consumed <= max,
69             "incorrect maximum size: indicated {}, actually consumed {}",
70             max,
71             consumed
72         );
73     }
74 
75     if result.is_ok() {
76         assert!(
77             consumed >= min,
78             "incorrect minimum size: indicated {}, actually consumed {}",
79             min,
80             consumed
81         );
82     }
83 
84     result
85 }
86 
87 /// Like `checked_arbitrary()`, but calls `arbitrary_take_rest()` instead of `arbitrary()`.
checked_arbitrary_take_rest<'a, T: Arbitrary<'a>>(u: Unstructured<'a>) -> Result<T>88 fn checked_arbitrary_take_rest<'a, T: Arbitrary<'a>>(u: Unstructured<'a>) -> Result<T> {
89     let (min, _) = T::size_hint(0);
90 
91     let len_before = u.len();
92     let result = T::arbitrary_take_rest(u);
93 
94     if result.is_ok() {
95         assert!(
96             len_before >= min,
97             "incorrect minimum size: indicated {}, worked with {}",
98             min,
99             len_before
100         );
101     }
102 
103     result
104 }
105 
106 #[test]
finite_buffer_fill_buffer()107 fn finite_buffer_fill_buffer() {
108     let x = [1, 2, 3, 4];
109     let mut rb = Unstructured::new(&x);
110     let mut z = [0; 2];
111     rb.fill_buffer(&mut z).unwrap();
112     assert_eq!(z, [1, 2]);
113     rb.fill_buffer(&mut z).unwrap();
114     assert_eq!(z, [3, 4]);
115     rb.fill_buffer(&mut z).unwrap();
116     assert_eq!(z, [0, 0]);
117 }
118 
119 #[test]
arbitrary_for_integers()120 fn arbitrary_for_integers() {
121     let x = [1, 2, 3, 4];
122     let mut buf = Unstructured::new(&x);
123     let expected = 1 | (2 << 8) | (3 << 16) | (4 << 24);
124     let actual = checked_arbitrary::<i32>(&mut buf).unwrap();
125     assert_eq!(expected, actual);
126 
127     assert_generates([
128         i32::from_ne_bytes([0, 0, 0, 0]),
129         i32::from_ne_bytes([0, 0, 0, 1]),
130         i32::from_ne_bytes([0, 0, 1, 0]),
131         i32::from_ne_bytes([0, 1, 0, 0]),
132         i32::from_ne_bytes([1, 0, 0, 0]),
133         i32::from_ne_bytes([1, 1, 1, 1]),
134         i32::from_ne_bytes([0xff, 0xff, 0xff, 0xff]),
135     ]);
136 }
137 
138 #[test]
arbitrary_for_bytes()139 fn arbitrary_for_bytes() {
140     let x = [1, 2, 3, 4, 4];
141     let mut buf = Unstructured::new(&x);
142     let expected = &[1, 2, 3, 4];
143     let actual = checked_arbitrary::<&[u8]>(&mut buf).unwrap();
144     assert_eq!(expected, actual);
145 }
146 
147 #[test]
arbitrary_take_rest_for_bytes()148 fn arbitrary_take_rest_for_bytes() {
149     let x = [1, 2, 3, 4];
150     let buf = Unstructured::new(&x);
151     let expected = &[1, 2, 3, 4];
152     let actual = checked_arbitrary_take_rest::<&[u8]>(buf).unwrap();
153     assert_eq!(expected, actual);
154 }
155 
156 #[test]
arbitrary_for_vec_u8()157 fn arbitrary_for_vec_u8() {
158     assert_generates::<Vec<u8>>([
159         vec![],
160         vec![0],
161         vec![1],
162         vec![0, 0],
163         vec![0, 1],
164         vec![1, 0],
165         vec![1, 1],
166         vec![0, 0, 0],
167         vec![0, 0, 1],
168         vec![0, 1, 0],
169         vec![0, 1, 1],
170         vec![1, 0, 0],
171         vec![1, 0, 1],
172         vec![1, 1, 0],
173         vec![1, 1, 1],
174     ]);
175 }
176 
177 #[test]
arbitrary_for_vec_vec_u8()178 fn arbitrary_for_vec_vec_u8() {
179     assert_generates::<Vec<Vec<u8>>>([
180         vec![],
181         vec![vec![]],
182         vec![vec![0]],
183         vec![vec![1]],
184         vec![vec![0, 1]],
185         vec![vec![], vec![]],
186         vec![vec![0], vec![]],
187         vec![vec![], vec![1]],
188         vec![vec![0], vec![1]],
189         vec![vec![0, 1], vec![]],
190         vec![vec![], vec![1, 0]],
191         vec![vec![], vec![], vec![]],
192     ]);
193 }
194 
195 #[test]
arbitrary_for_vec_vec_vec_u8()196 fn arbitrary_for_vec_vec_vec_u8() {
197     assert_generates::<Vec<Vec<Vec<u8>>>>([
198         vec![],
199         vec![vec![]],
200         vec![vec![vec![0]]],
201         vec![vec![vec![1]]],
202         vec![vec![vec![0, 1]]],
203         vec![vec![], vec![]],
204         vec![vec![], vec![vec![]]],
205         vec![vec![vec![]], vec![]],
206         vec![vec![vec![]], vec![vec![]]],
207         vec![vec![vec![0]], vec![]],
208         vec![vec![], vec![vec![1]]],
209         vec![vec![vec![0]], vec![vec![1]]],
210         vec![vec![vec![0, 1]], vec![]],
211         vec![vec![], vec![vec![0, 1]]],
212         vec![vec![], vec![], vec![]],
213         vec![vec![vec![]], vec![], vec![]],
214         vec![vec![], vec![vec![]], vec![]],
215         vec![vec![], vec![], vec![vec![]]],
216     ]);
217 }
218 
219 #[test]
arbitrary_for_string()220 fn arbitrary_for_string() {
221     assert_generates::<String>(["".into(), "a".into(), "aa".into(), "aaa".into()]);
222 }
223 
224 #[test]
arbitrary_collection()225 fn arbitrary_collection() {
226     let x = [
227         1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 12,
228     ];
229     assert_eq!(
230         checked_arbitrary::<&[u8]>(&mut Unstructured::new(&x)).unwrap(),
231         &[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
232     );
233     assert_eq!(
234         checked_arbitrary::<Vec<u8>>(&mut Unstructured::new(&x)).unwrap(),
235         &[2, 4, 6, 8, 1]
236     );
237     assert_eq!(
238         &*checked_arbitrary::<Box<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
239         &[2, 4, 6, 8, 1]
240     );
241     assert_eq!(
242         &*checked_arbitrary::<Arc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
243         &[2, 4, 6, 8, 1]
244     );
245     assert_eq!(
246         &*checked_arbitrary::<Rc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
247         &[2, 4, 6, 8, 1]
248     );
249     assert_eq!(
250         checked_arbitrary::<Vec<u32>>(&mut Unstructured::new(&x)).unwrap(),
251         &[84148994]
252     );
253     assert_eq!(
254         checked_arbitrary::<String>(&mut Unstructured::new(&x)).unwrap(),
255         "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x01\x02\x03"
256     );
257 }
258 
259 #[test]
arbitrary_take_rest()260 fn arbitrary_take_rest() {
261     // Basic examples
262     let x = [1, 2, 3, 4];
263     assert_eq!(
264         checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&x)).unwrap(),
265         &[1, 2, 3, 4]
266     );
267     assert_eq!(
268         checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&x)).unwrap(),
269         &[2, 4]
270     );
271     assert_eq!(
272         &*checked_arbitrary_take_rest::<Box<[u8]>>(Unstructured::new(&x)).unwrap(),
273         &[2, 4]
274     );
275     assert_eq!(
276         &*checked_arbitrary_take_rest::<Arc<[u8]>>(Unstructured::new(&x)).unwrap(),
277         &[2, 4]
278     );
279     assert_eq!(
280         &*checked_arbitrary_take_rest::<Rc<[u8]>>(Unstructured::new(&x)).unwrap(),
281         &[2, 4]
282     );
283     assert_eq!(
284         checked_arbitrary_take_rest::<Vec<u32>>(Unstructured::new(&x)).unwrap(),
285         &[0x040302]
286     );
287     assert_eq!(
288         checked_arbitrary_take_rest::<String>(Unstructured::new(&x)).unwrap(),
289         "\x01\x02\x03\x04"
290     );
291 
292     // Empty remainder
293     assert_eq!(
294         checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&[])).unwrap(),
295         &[]
296     );
297     assert_eq!(
298         checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&[])).unwrap(),
299         &[]
300     );
301 
302     // Cannot consume all but can consume part of the input
303     assert_eq!(
304         checked_arbitrary_take_rest::<String>(Unstructured::new(&[1, 0xFF, 2])).unwrap(),
305         "\x01"
306     );
307 }
308 
309 #[test]
size_hint_for_tuples()310 fn size_hint_for_tuples() {
311     assert_eq!(
312         (7, Some(7)),
313         <(bool, u16, i32) as Arbitrary<'_>>::size_hint(0)
314     );
315     assert_eq!((1, None), <(u8, Vec<u8>) as Arbitrary>::size_hint(0));
316 }
317