1use std::char;
2use std::collections::{
3 BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
4};
5use std::env;
6use std::ffi::{CString, OsString};
7use std::hash::{BuildHasher, Hash};
8use std::iter::{empty, once, successors};
9use std::net::{
10 IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
11};
12use std::num::Wrapping;
13use std::num::{
14 NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
15};
16use std::ops::{
17 Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
18 RangeToInclusive,
19};
20use std::path::PathBuf;
21use std::sync::Arc;
22use std::time::{Duration, SystemTime, UNIX_EPOCH};
23
24use rand::prelude::*;
25
26pub struct Gen {
36 rng: rand::rngs::SmallRng,
37 size: usize,
38}
39
40impl Gen {
41 pub fn new(size: usize) -> Gen {
49 Gen { rng: rand::make_rng(), size: size }
50 }
51
52 pub fn from_size_and_seed(size: usize, seed: u64) -> Gen {
63 Gen { rng: rand::rngs::SmallRng::seed_from_u64(seed), size }
64 }
65
66 pub fn size(&self) -> usize {
68 self.size
69 }
70
71 pub fn choose<'a, T>(&mut self, slice: &'a [T]) -> Option<&'a T> {
75 slice.choose(&mut self.rng)
76 }
77
78 fn random<T>(&mut self) -> T
79 where
80 rand::distr::StandardUniform: rand::distr::Distribution<T>,
81 {
82 self.rng.random()
83 }
84
85 fn random_range<T, R>(&mut self, range: R) -> T
86 where
87 T: rand::distr::uniform::SampleUniform,
88 R: rand::distr::uniform::SampleRange<T>,
89 {
90 self.rng.random_range(range)
91 }
92}
93
94pub fn empty_shrinker<A: 'static>() -> Box<dyn Iterator<Item = A>> {
96 Box::new(empty())
97}
98
99pub fn single_shrinker<A: 'static>(value: A) -> Box<dyn Iterator<Item = A>> {
101 Box::new(once(value))
102}
103
104pub trait Arbitrary: Clone + 'static {
119 fn arbitrary(g: &mut Gen) -> Self;
127
128 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
142 empty_shrinker()
143 }
144}
145
146impl Arbitrary for () {
147 fn arbitrary(_: &mut Gen) {}
148}
149
150impl Arbitrary for bool {
151 fn arbitrary(g: &mut Gen) -> bool {
152 g.random()
153 }
154
155 fn shrink(&self) -> Box<dyn Iterator<Item = bool>> {
156 if *self {
157 single_shrinker(false)
158 } else {
159 empty_shrinker()
160 }
161 }
162}
163
164impl<A: Arbitrary> Arbitrary for Option<A> {
165 fn arbitrary(g: &mut Gen) -> Option<A> {
166 if g.random() {
167 None
168 } else {
169 Some(Arbitrary::arbitrary(g))
170 }
171 }
172
173 fn shrink(&self) -> Box<dyn Iterator<Item = Option<A>>> {
174 match *self {
175 None => empty_shrinker(),
176 Some(ref x) => {
177 let chain = single_shrinker(None).chain(x.shrink().map(Some));
178 Box::new(chain)
179 }
180 }
181 }
182}
183
184impl<A: Arbitrary, B: Arbitrary> Arbitrary for Result<A, B> {
185 fn arbitrary(g: &mut Gen) -> Result<A, B> {
186 if g.random() {
187 Ok(Arbitrary::arbitrary(g))
188 } else {
189 Err(Arbitrary::arbitrary(g))
190 }
191 }
192
193 fn shrink(&self) -> Box<dyn Iterator<Item = Result<A, B>>> {
194 match *self {
195 Ok(ref x) => {
196 let xs = x.shrink();
197 let tagged = xs.map(Ok);
198 Box::new(tagged)
199 }
200 Err(ref x) => {
201 let xs = x.shrink();
202 let tagged = xs.map(Err);
203 Box::new(tagged)
204 }
205 }
206 }
207}
208
209macro_rules! impl_arb_for_single_tuple {
210 ($(($type_param:ident, $tuple_index:tt),)*) => {
211 impl<$($type_param),*> Arbitrary for ($($type_param,)*)
212 where $($type_param: Arbitrary,)*
213 {
214 fn arbitrary(g: &mut Gen) -> ($($type_param,)*) {
215 (
216 $(
217 $type_param::arbitrary(g),
218 )*
219 )
220 }
221
222 fn shrink(&self) -> Box<dyn Iterator<Item=($($type_param,)*)>> {
223 let iter = ::std::iter::empty();
224 $(
225 let cloned = self.clone();
226 let iter = iter.chain(
227 self.$tuple_index.shrink().map(move |shr_value| {
228 let mut result = cloned.clone();
229 result.$tuple_index = shr_value;
230 result
231 })
232 );
233 )*
234 Box::new(iter)
235 }
236 }
237 };
238}
239
240macro_rules! impl_arb_for_tuples {
241 (@internal [$($acc:tt,)*]) => { };
242 (@internal [$($acc:tt,)*] ($type_param:ident, $tuple_index:tt), $($rest:tt,)*) => {
243 impl_arb_for_single_tuple!($($acc,)* ($type_param, $tuple_index),);
244 impl_arb_for_tuples!(@internal [$($acc,)* ($type_param, $tuple_index),] $($rest,)*);
245 };
246 ($(($type_param:ident, $tuple_index:tt),)*) => {
247 impl_arb_for_tuples!(@internal [] $(($type_param, $tuple_index),)*);
248 };
249}
250
251impl<A, B, C, D, E, F, G, H> Arbitrary for (A, B, C, D, E, F, G, H) where
A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary,
F: Arbitrary, G: Arbitrary, H: Arbitrary {
fn arbitrary(g: &mut Gen) -> (A, B, C, D, E, F, G, H) {
(A::arbitrary(g), B::arbitrary(g), C::arbitrary(g), D::arbitrary(g),
E::arbitrary(g), F::arbitrary(g), G::arbitrary(g),
H::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = (A, B, C, D, E, F, G, H)>> {
let iter = ::std::iter::empty();
let cloned = self.clone();
let iter =
iter.chain(self.0.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.0 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.1.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.1 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.2.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.2 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.3.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.3 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.4.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.4 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.5.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.5 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.6.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.6 = shr_value;
result
}));
let cloned = self.clone();
let iter =
iter.chain(self.7.shrink().map(move |shr_value|
{
let mut result = cloned.clone();
result.7 = shr_value;
result
}));
Box::new(iter)
}
}impl_arb_for_tuples! {
252 (A, 0),
253 (B, 1),
254 (C, 2),
255 (D, 3),
256 (E, 4),
257 (F, 5),
258 (G, 6),
259 (H, 7),
260}
261
262impl<const N: usize, A: Arbitrary> Arbitrary for [A; N] {
263 fn arbitrary(g: &mut Gen) -> Self {
264 std::array::from_fn(|_ix| A::arbitrary(g))
265 }
266
267 fn shrink(&self) -> Box<dyn Iterator<Item = [A; N]>> {
268 let cloned = self.clone();
269 let iter = (0..N).flat_map(move |n| {
270 let cloned = cloned.clone();
271 cloned[n].shrink().map(move |shr_value| {
272 let mut result = cloned.clone();
273 result[n] = shr_value;
274 result
275 })
276 });
277
278 Box::new(iter)
279 }
280}
281
282impl<A: Arbitrary> Arbitrary for Vec<A> {
283 fn arbitrary(g: &mut Gen) -> Vec<A> {
284 let size = {
285 let s = g.size();
286 g.random_range(0..s)
287 };
288 (0..size).map(|_| A::arbitrary(g)).collect()
289 }
290
291 fn shrink(&self) -> Box<dyn Iterator<Item = Vec<A>>> {
292 VecShrinker::new(self.clone())
293 }
294}
295
296struct VecShrinker<A> {
298 seed: Vec<A>,
299 size: usize,
301 offset: usize,
303 element_shrinker: Box<dyn Iterator<Item = A>>,
306}
307
308impl<A: Arbitrary> VecShrinker<A> {
309 #[allow(clippy::new_ret_no_self)]
310 fn new(seed: Vec<A>) -> Box<dyn Iterator<Item = Vec<A>>> {
311 let es = match seed.first() {
312 Some(e) => e.shrink(),
313 None => return empty_shrinker(),
314 };
315 let size = seed.len();
316 Box::new(VecShrinker {
317 seed,
318 size,
319 offset: size,
320 element_shrinker: es,
321 })
322 }
323
324 fn next_element(&mut self) -> Option<A> {
327 loop {
328 match self.element_shrinker.next() {
329 Some(e) => return Some(e),
330 None => match self.seed.get(self.offset) {
331 Some(e) => {
332 self.element_shrinker = e.shrink();
333 self.offset += 1;
334 }
335 None => return None,
336 },
337 }
338 }
339 }
340}
341
342impl<A> Iterator for VecShrinker<A>
343where
344 A: Arbitrary,
345{
346 type Item = Vec<A>;
347 fn next(&mut self) -> Option<Vec<A>> {
348 if self.size == self.seed.len() {
350 self.size /= 2;
351 self.offset = self.size;
352 return Some(::alloc::vec::Vec::new()vec![]);
353 }
354 if self.size != 0 {
355 let xs1 = self.seed[..(self.offset - self.size)]
358 .iter()
359 .chain(&self.seed[self.offset..])
360 .cloned()
361 .collect();
362 self.offset += self.size;
363 if self.offset > self.seed.len() {
366 self.size /= 2;
367 self.offset = self.size;
368 }
369 Some(xs1)
370 } else {
371 if self.offset == 0 {
379 self.offset = 1;
380 }
381
382 match self.next_element() {
383 Some(e) => Some(
384 self.seed[..self.offset - 1]
385 .iter()
386 .cloned()
387 .chain(Some(e))
388 .chain(self.seed[self.offset..].iter().cloned())
389 .collect(),
390 ),
391 None => None,
392 }
393 }
394 }
395}
396
397impl<K: Arbitrary + Ord, V: Arbitrary> Arbitrary for BTreeMap<K, V> {
398 fn arbitrary(g: &mut Gen) -> BTreeMap<K, V> {
399 let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
400 vec.into_iter().collect()
401 }
402
403 fn shrink(&self) -> Box<dyn Iterator<Item = BTreeMap<K, V>>> {
404 let vec: Vec<(K, V)> = self.clone().into_iter().collect();
405 Box::new(
406 vec.shrink().map(|v| v.into_iter().collect::<BTreeMap<K, V>>()),
407 )
408 }
409}
410
411impl<
412 K: Arbitrary + Eq + Hash,
413 V: Arbitrary,
414 S: BuildHasher + Default + Clone + 'static,
415 > Arbitrary for HashMap<K, V, S>
416{
417 fn arbitrary(g: &mut Gen) -> Self {
418 let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
419 vec.into_iter().collect()
420 }
421
422 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
423 let vec: Vec<(K, V)> = self.clone().into_iter().collect();
424 Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
425 }
426}
427
428impl<T: Arbitrary + Ord> Arbitrary for BTreeSet<T> {
429 fn arbitrary(g: &mut Gen) -> BTreeSet<T> {
430 let vec: Vec<T> = Arbitrary::arbitrary(g);
431 vec.into_iter().collect()
432 }
433
434 fn shrink(&self) -> Box<dyn Iterator<Item = BTreeSet<T>>> {
435 let vec: Vec<T> = self.clone().into_iter().collect();
436 Box::new(vec.shrink().map(|v| v.into_iter().collect::<BTreeSet<T>>()))
437 }
438}
439
440impl<T: Arbitrary + Ord> Arbitrary for BinaryHeap<T> {
441 fn arbitrary(g: &mut Gen) -> BinaryHeap<T> {
442 let vec: Vec<T> = Arbitrary::arbitrary(g);
443 vec.into_iter().collect()
444 }
445
446 fn shrink(&self) -> Box<dyn Iterator<Item = BinaryHeap<T>>> {
447 let vec: Vec<T> = self.clone().into_iter().collect();
448 Box::new(
449 vec.shrink().map(|v| v.into_iter().collect::<BinaryHeap<T>>()),
450 )
451 }
452}
453
454impl<T: Arbitrary + Eq + Hash, S: BuildHasher + Default + Clone + 'static>
455 Arbitrary for HashSet<T, S>
456{
457 fn arbitrary(g: &mut Gen) -> Self {
458 let vec: Vec<T> = Arbitrary::arbitrary(g);
459 vec.into_iter().collect()
460 }
461
462 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
463 let vec: Vec<T> = self.clone().into_iter().collect();
464 Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
465 }
466}
467
468impl<T: Arbitrary> Arbitrary for LinkedList<T> {
469 fn arbitrary(g: &mut Gen) -> LinkedList<T> {
470 let vec: Vec<T> = Arbitrary::arbitrary(g);
471 vec.into_iter().collect()
472 }
473
474 fn shrink(&self) -> Box<dyn Iterator<Item = LinkedList<T>>> {
475 let vec: Vec<T> = self.clone().into_iter().collect();
476 Box::new(
477 vec.shrink().map(|v| v.into_iter().collect::<LinkedList<T>>()),
478 )
479 }
480}
481
482impl<T: Arbitrary> Arbitrary for VecDeque<T> {
483 fn arbitrary(g: &mut Gen) -> VecDeque<T> {
484 let vec: Vec<T> = Arbitrary::arbitrary(g);
485 vec.into_iter().collect()
486 }
487
488 fn shrink(&self) -> Box<dyn Iterator<Item = VecDeque<T>>> {
489 let vec: Vec<T> = self.clone().into_iter().collect();
490 Box::new(vec.shrink().map(|v| v.into_iter().collect::<VecDeque<T>>()))
491 }
492}
493
494impl Arbitrary for IpAddr {
495 fn arbitrary(g: &mut Gen) -> IpAddr {
496 let ipv4: bool = g.random();
497 if ipv4 {
498 IpAddr::V4(Arbitrary::arbitrary(g))
499 } else {
500 IpAddr::V6(Arbitrary::arbitrary(g))
501 }
502 }
503}
504
505impl Arbitrary for Ipv4Addr {
506 fn arbitrary(g: &mut Gen) -> Ipv4Addr {
507 Ipv4Addr::new(g.random(), g.random(), g.random(), g.random())
508 }
509}
510
511impl Arbitrary for Ipv6Addr {
512 fn arbitrary(g: &mut Gen) -> Ipv6Addr {
513 Ipv6Addr::new(
514 g.random(),
515 g.random(),
516 g.random(),
517 g.random(),
518 g.random(),
519 g.random(),
520 g.random(),
521 g.random(),
522 )
523 }
524}
525
526impl Arbitrary for SocketAddr {
527 fn arbitrary(g: &mut Gen) -> SocketAddr {
528 SocketAddr::new(Arbitrary::arbitrary(g), g.random())
529 }
530}
531
532impl Arbitrary for SocketAddrV4 {
533 fn arbitrary(g: &mut Gen) -> SocketAddrV4 {
534 SocketAddrV4::new(Arbitrary::arbitrary(g), g.random())
535 }
536}
537
538impl Arbitrary for SocketAddrV6 {
539 fn arbitrary(g: &mut Gen) -> SocketAddrV6 {
540 SocketAddrV6::new(
541 Arbitrary::arbitrary(g),
542 g.random(),
543 g.random(),
544 g.random(),
545 )
546 }
547}
548
549impl Arbitrary for PathBuf {
550 fn arbitrary(g: &mut Gen) -> PathBuf {
551 let here = env::current_dir()
554 .unwrap_or_else(|_| PathBuf::from("/test/directory"));
555 let temp = env::temp_dir();
556 #[allow(deprecated)]
557 let home =
558 env::home_dir().unwrap_or_else(|| PathBuf::from("/home/user"));
559 let mut p = g
560 .choose(&[
561 here,
562 temp,
563 home,
564 PathBuf::from("."),
565 PathBuf::from(".."),
566 PathBuf::from("../../.."),
567 PathBuf::new(),
568 ])
569 .unwrap()
570 .to_owned();
571 p.extend(Vec::<OsString>::arbitrary(g).iter());
572 p
573 }
574
575 fn shrink(&self) -> Box<dyn Iterator<Item = PathBuf>> {
576 let mut shrunk = ::alloc::vec::Vec::new()vec![];
577 let mut popped = self.clone();
578 if popped.pop() {
579 shrunk.push(popped);
580 }
581
582 let normalized = self.iter().collect::<PathBuf>();
584 if normalized.as_os_str() != self.as_os_str() {
585 shrunk.push(normalized);
586 }
587
588 if let Ok(canonicalized) = self.canonicalize() {
592 if canonicalized.as_os_str() != self.as_os_str() {
593 shrunk.push(canonicalized);
594 }
595 }
596
597 Box::new(shrunk.into_iter())
598 }
599}
600
601impl Arbitrary for OsString {
602 fn arbitrary(g: &mut Gen) -> OsString {
603 OsString::from(String::arbitrary(g))
604 }
605
606 fn shrink(&self) -> Box<dyn Iterator<Item = OsString>> {
607 let mystring: String = self.clone().into_string().unwrap();
608 Box::new(mystring.shrink().map(OsString::from))
609 }
610}
611
612impl Arbitrary for String {
613 fn arbitrary(g: &mut Gen) -> String {
614 let size = {
615 let s = g.size();
616 g.random_range(0..s)
617 };
618 (0..size).map(|_| char::arbitrary(g)).collect()
619 }
620
621 fn shrink(&self) -> Box<dyn Iterator<Item = String>> {
622 let chars: Vec<char> = self.chars().collect();
624 Box::new(chars.shrink().map(|x| x.into_iter().collect::<String>()))
625 }
626}
627
628impl Arbitrary for CString {
629 fn arbitrary(g: &mut Gen) -> Self {
630 let size = {
631 let s = g.size();
632 g.random_range(0..s)
633 };
634 let utf8: bool = g.random();
636 if utf8 {
637 CString::new(
638 (0..)
639 .map(|_| char::arbitrary(g))
640 .filter(|&c| c != '\0')
641 .take(size)
642 .collect::<String>(),
643 )
644 } else {
645 CString::new(
646 (0..)
647 .map(|_| u8::arbitrary(g))
648 .filter(|&c| c != b'\0')
649 .take(size)
650 .collect::<Vec<u8>>(),
651 )
652 }
653 .expect("null characters should have been filtered out")
654 }
655
656 fn shrink(&self) -> Box<dyn Iterator<Item = CString>> {
657 Box::new(VecShrinker::new(self.as_bytes().to_vec()).map(|bytes| {
660 CString::new(
661 bytes.into_iter().filter(|&c| c != 0).collect::<Vec<u8>>(),
662 )
663 .expect("null characters should have been filtered out")
664 }))
665 }
666}
667
668impl Arbitrary for char {
669 fn arbitrary(g: &mut Gen) -> char {
670 let mode = g.random_range(0..100);
671 match mode {
672 0..=49 => {
673 g.random_range(0u8..0xB0) as char
675 }
676 50..=59 => {
677 loop {
679 if let Some(x) = char::from_u32(g.random_range(0..0x10000))
680 {
681 return x;
682 }
683 }
685 }
686 60..=84 => {
687 g.choose(&[
689 ' ', ' ', ' ', '\t', '\n', '~', '`', '!', '@', '#', '$',
690 '%', '^', '&', '*', '(', ')', '_', '-', '=', '+', '[',
691 ']', '{', '}', ':', ';', '\'', '"', '\\', '|', ',', '<',
692 '>', '.', '/', '?', '0', '1', '2', '3', '4', '5', '6',
693 '7', '8', '9',
694 ])
695 .unwrap()
696 .to_owned()
697 }
698 85..=89 => {
699 g.choose(&[
701 '\u{0149}', '\u{fff0}', '\u{fff1}',
704 '\u{fff2}',
705 '\u{fff3}',
706 '\u{fff4}',
707 '\u{fff5}',
708 '\u{fff6}',
709 '\u{fff7}',
710 '\u{fff8}',
711 '\u{fff9}',
712 '\u{fffA}',
713 '\u{fffB}',
714 '\u{fffC}',
715 '\u{fffD}',
716 '\u{fffE}',
717 '\u{fffF}',
718 '\u{0600}',
719 '\u{0601}',
720 '\u{0602}',
721 '\u{0603}',
722 '\u{0604}',
723 '\u{0605}',
724 '\u{061C}',
725 '\u{06DD}',
726 '\u{070F}',
727 '\u{180E}',
728 '\u{110BD}',
729 '\u{1D173}',
730 '\u{e0001}', '\u{e0020}', '\u{e000}',
733 '\u{e001}',
734 '\u{ef8ff}', '\u{f0000}',
736 '\u{ffffd}',
737 '\u{ffffe}',
738 '\u{fffff}',
739 '\u{100000}',
740 '\u{10FFFD}',
741 '\u{10FFFE}',
742 '\u{10FFFF}',
743 '\u{3000}', '\u{1680}',
748 ])
751 .unwrap()
752 .to_owned()
753 }
754 90..=94 => {
755 char::from_u32(g.random_range(0x2000..0x2070)).unwrap()
757 }
758 95..=99 => {
759 g.random()
761 }
762 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
763 }
764 }
765
766 fn shrink(&self) -> Box<dyn Iterator<Item = char>> {
767 Box::new((*self as u32).shrink().filter_map(char::from_u32))
768 }
769}
770
771macro_rules! unsigned_shrinker {
772 ($ty:ty) => {
773 mod shrinker {
774 pub struct UnsignedShrinker {
775 x: $ty,
776 i: $ty,
777 }
778
779 impl UnsignedShrinker {
780 #[allow(clippy::new_ret_no_self)]
781 pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
782 if x == 0 {
783 super::empty_shrinker()
784 } else {
785 Box::new(
786 vec![0]
787 .into_iter()
788 .chain(UnsignedShrinker { x, i: x / 2 }),
789 )
790 }
791 }
792 }
793
794 impl Iterator for UnsignedShrinker {
795 type Item = $ty;
796 fn next(&mut self) -> Option<$ty> {
797 if self.x - self.i < self.x {
798 let result = Some(self.x - self.i);
799 self.i /= 2;
800 result
801 } else {
802 None
803 }
804 }
805 }
806 }
807 };
808}
809
810macro_rules! unsigned_problem_values {
811 ($t:ty) => {
812 &[<$t>::MIN, 1, <$t>::MAX]
813 };
814}
815
816macro_rules! unsigned_arbitrary {
817 ($($ty:tt),*) => {
818 $(
819 impl Arbitrary for $ty {
820 fn arbitrary(g: &mut Gen) -> $ty {
821 match g.random_range(0..10) {
822 0 => *g.choose(unsigned_problem_values!($ty)).unwrap(),
823 _ => g.random()
824 }
825 }
826 fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
827 unsigned_shrinker!($ty);
828 shrinker::UnsignedShrinker::new(*self)
829 }
830 }
831 )*
832 }
833}
834
835impl Arbitrary for u128 {
fn arbitrary(g: &mut Gen) -> u128 {
match g.random_range(0..10) {
0 => *g.choose(&[<u128>::MIN, 1, <u128>::MAX]).unwrap(),
_ => g.random(),
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = u128>> {
mod shrinker {
pub struct UnsignedShrinker {
x: u128,
i: u128,
}
impl UnsignedShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: u128) -> Box<dyn Iterator<Item = u128>> {
if x == 0 {
super::empty_shrinker()
} else {
Box::new(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[0])).into_iter().chain(UnsignedShrinker { x, i: x / 2 }))
}
}
}
impl Iterator for UnsignedShrinker {
type Item = u128;
fn next(&mut self) -> Option<u128> {
if self.x - self.i < self.x {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}
shrinker::UnsignedShrinker::new(*self)
}
}unsigned_arbitrary! {
836 u8, u16, u32, u64, u128
837}
838
839impl Arbitrary for usize {
840 fn arbitrary(g: &mut Gen) -> usize {
841 match g.random_range(0..10) {
842 0 => *g.choose(&[<usize>::MIN, 1, <usize>::MAX]unsigned_problem_values!(usize)).unwrap(),
843 _ => {
844 #[cfg(target_pointer_width = "16")]
845 {
846 g.random::<u16>() as usize
847 }
848 #[cfg(target_pointer_width = "32")]
849 {
850 g.random::<u32>() as usize
851 }
852 #[cfg(target_pointer_width = "64")]
853 {
854 g.random::<u64>() as usize
855 }
856 }
857 }
858 }
859 fn shrink(&self) -> Box<dyn Iterator<Item = usize>> {
860 mod shrinker {
pub struct UnsignedShrinker {
x: usize,
i: usize,
}
impl UnsignedShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: usize) -> Box<dyn Iterator<Item = usize>> {
if x == 0 {
super::empty_shrinker()
} else {
Box::new(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[0])).into_iter().chain(UnsignedShrinker { x, i: x / 2 }))
}
}
}
impl Iterator for UnsignedShrinker {
type Item = usize;
fn next(&mut self) -> Option<usize> {
if self.x - self.i < self.x {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}unsigned_shrinker!(usize);
861 shrinker::UnsignedShrinker::new(*self)
862 }
863}
864
865macro_rules! signed_shrinker {
866 ($ty:ty) => {
867 mod shrinker {
868 pub struct SignedShrinker {
869 x: $ty,
870 i: $ty,
871 }
872
873 impl SignedShrinker {
874 #[allow(clippy::new_ret_no_self)]
875 pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
876 if x == 0 {
877 super::empty_shrinker()
878 } else {
879 let shrinker = SignedShrinker { x, i: x / 2 };
880 let mut items = vec![0];
881 if shrinker.i < 0 && shrinker.x != <$ty>::MIN {
882 items.push(shrinker.x.abs());
883 }
884 Box::new(items.into_iter().chain(shrinker))
885 }
886 }
887 }
888
889 impl Iterator for SignedShrinker {
890 type Item = $ty;
891 fn next(&mut self) -> Option<$ty> {
892 if self.i != 0 {
893 let result = Some(self.x - self.i);
894 self.i /= 2;
895 result
896 } else {
897 None
898 }
899 }
900 }
901 }
902 };
903}
904
905macro_rules! signed_problem_values {
906 ($t:ty) => {
907 &[<$t>::MIN, 0, <$t>::MAX]
908 };
909}
910
911macro_rules! signed_arbitrary {
912 ($($ty:tt),*) => {
913 $(
914 impl Arbitrary for $ty {
915 fn arbitrary(g: &mut Gen) -> $ty {
916 match g.random_range(0..10) {
917 0 => *g.choose(signed_problem_values!($ty)).unwrap(),
918 _ => g.random()
919 }
920 }
921 fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
922 signed_shrinker!($ty);
923 shrinker::SignedShrinker::new(*self)
924 }
925 }
926 )*
927 }
928}
929
930impl Arbitrary for i128 {
fn arbitrary(g: &mut Gen) -> i128 {
match g.random_range(0..10) {
0 => *g.choose(&[<i128>::MIN, 0, <i128>::MAX]).unwrap(),
_ => g.random(),
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = i128>> {
mod shrinker {
pub struct SignedShrinker {
x: i128,
i: i128,
}
impl SignedShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: i128) -> Box<dyn Iterator<Item = i128>> {
if x == 0 {
super::empty_shrinker()
} else {
let shrinker = SignedShrinker { x, i: x / 2 };
let mut items =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[0]));
if shrinker.i < 0 && shrinker.x != <i128>::MIN {
items.push(shrinker.x.abs());
}
Box::new(items.into_iter().chain(shrinker))
}
}
}
impl Iterator for SignedShrinker {
type Item = i128;
fn next(&mut self) -> Option<i128> {
if self.i != 0 {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}
shrinker::SignedShrinker::new(*self)
}
}signed_arbitrary! {
931 i8, i16, i32, i64, i128
932}
933
934impl Arbitrary for isize {
935 fn arbitrary(g: &mut Gen) -> isize {
936 match g.random_range(0..10) {
937 0 => *g.choose(&[<isize>::MIN, 0, <isize>::MAX]signed_problem_values!(isize)).unwrap(),
938 _ => {
939 #[cfg(target_pointer_width = "16")]
940 {
941 g.random::<i16>() as isize
942 }
943 #[cfg(target_pointer_width = "32")]
944 {
945 g.random::<i32>() as isize
946 }
947 #[cfg(target_pointer_width = "64")]
948 {
949 g.random::<i64>() as isize
950 }
951 }
952 }
953 }
954 fn shrink(&self) -> Box<dyn Iterator<Item = isize>> {
955 mod shrinker {
pub struct SignedShrinker {
x: isize,
i: isize,
}
impl SignedShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: isize) -> Box<dyn Iterator<Item = isize>> {
if x == 0 {
super::empty_shrinker()
} else {
let shrinker = SignedShrinker { x, i: x / 2 };
let mut items =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[0]));
if shrinker.i < 0 && shrinker.x != <isize>::MIN {
items.push(shrinker.x.abs());
}
Box::new(items.into_iter().chain(shrinker))
}
}
}
impl Iterator for SignedShrinker {
type Item = isize;
fn next(&mut self) -> Option<isize> {
if self.i != 0 {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}signed_shrinker!(isize);
956 shrinker::SignedShrinker::new(*self)
957 }
958}
959
960macro_rules! float_problem_values {
961 ($t:ty) => {{
962 &[
963 <$t>::NAN,
964 <$t>::NEG_INFINITY,
965 <$t>::MIN,
966 -0.,
967 0.,
968 <$t>::MAX,
969 <$t>::INFINITY,
970 ]
971 }};
972}
973
974macro_rules! float_arbitrary {
975 ($($t:ty, $shrinkable:ty),+) => {$(
976 impl Arbitrary for $t {
977 fn arbitrary(g: &mut Gen) -> $t {
978 match g.random_range(0..10) {
979 0 => *g.choose(float_problem_values!($t)).unwrap(),
980 _ => {
981 let exp = g.random_range((0.)..<$t>::MAX_EXP as i16 as $t);
982 let mantissa = g.random_range((1.)..2.);
983 let sign = *g.choose(&[-1., 1.]).unwrap();
984 sign * mantissa * exp.exp2()
985 }
986 }
987 }
988 fn shrink(&self) -> Box<dyn Iterator<Item = $t>> {
989 signed_shrinker!($shrinkable);
990 let it = shrinker::SignedShrinker::new(*self as $shrinkable);
991 let old = *self;
992 Box::new(it.map(|x| x as $t).filter(move |x| *x != old))
993 }
994 }
995 )*};
996}
997
998impl Arbitrary for f64 {
fn arbitrary(g: &mut Gen) -> f64 {
match g.random_range(0..10) {
0 =>
*g.choose({
&[<f64>::NAN, <f64>::NEG_INFINITY, <f64>::MIN, -0., 0.,
<f64>::MAX, <f64>::INFINITY]
}).unwrap(),
_ => {
let exp = g.random_range((0.)..<f64>::MAX_EXP as i16 as f64);
let mantissa = g.random_range((1.)..2.);
let sign = *g.choose(&[-1., 1.]).unwrap();
sign * mantissa * exp.exp2()
}
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = f64>> {
mod shrinker {
pub struct SignedShrinker {
x: i64,
i: i64,
}
impl SignedShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: i64) -> Box<dyn Iterator<Item = i64>> {
if x == 0 {
super::empty_shrinker()
} else {
let shrinker = SignedShrinker { x, i: x / 2 };
let mut items =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[0]));
if shrinker.i < 0 && shrinker.x != <i64>::MIN {
items.push(shrinker.x.abs());
}
Box::new(items.into_iter().chain(shrinker))
}
}
}
impl Iterator for SignedShrinker {
type Item = i64;
fn next(&mut self) -> Option<i64> {
if self.i != 0 {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}
let it = shrinker::SignedShrinker::new(*self as i64);
let old = *self;
Box::new(it.map(|x| x as f64).filter(move |x| *x != old))
}
}float_arbitrary!(f32, i32, f64, i64);
999
1000macro_rules! unsigned_non_zero_shrinker {
1001 ($ty:tt) => {
1002 mod shrinker {
1003 pub struct UnsignedNonZeroShrinker {
1004 x: $ty,
1005 i: $ty,
1006 }
1007
1008 impl UnsignedNonZeroShrinker {
1009 #[allow(clippy::new_ret_no_self)]
1010 pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
1011 debug_assert!(x > 0);
1012
1013 if x == 1 {
1014 super::empty_shrinker()
1015 } else {
1016 Box::new(
1017 std::iter::once(1).chain(
1018 UnsignedNonZeroShrinker { x, i: x / 2 },
1019 ),
1020 )
1021 }
1022 }
1023 }
1024
1025 impl Iterator for UnsignedNonZeroShrinker {
1026 type Item = $ty;
1027
1028 fn next(&mut self) -> Option<$ty> {
1029 if self.x - self.i < self.x {
1030 let result = Some(self.x - self.i);
1031 self.i /= 2;
1032 result
1033 } else {
1034 None
1035 }
1036 }
1037 }
1038 }
1039 };
1040}
1041
1042macro_rules! unsigned_non_zero_arbitrary {
1043 ($($ty:tt => $inner:tt),*) => {
1044 $(
1045 impl Arbitrary for $ty {
1046 fn arbitrary(g: &mut Gen) -> $ty {
1047 let mut v = $inner::arbitrary(g);
1048 if v == 0 {
1049 v += 1;
1050 }
1051 $ty::new(v).expect("non-zero value construction failed")
1052 }
1053
1054 fn shrink(&self) -> Box<dyn Iterator<Item = $ty>> {
1055 unsigned_non_zero_shrinker!($inner);
1056 Box::new(shrinker::UnsignedNonZeroShrinker::new(self.get())
1057 .map($ty::new)
1058 .map(Option::unwrap))
1059 }
1060 }
1061 )*
1062 }
1063}
1064
1065impl Arbitrary for NonZeroU128 {
fn arbitrary(g: &mut Gen) -> NonZeroU128 {
let mut v = u128::arbitrary(g);
if v == 0 { v += 1; }
NonZeroU128::new(v).expect("non-zero value construction failed")
}
fn shrink(&self) -> Box<dyn Iterator<Item = NonZeroU128>> {
mod shrinker {
pub struct UnsignedNonZeroShrinker {
x: u128,
i: u128,
}
impl UnsignedNonZeroShrinker {
#[allow(clippy :: new_ret_no_self)]
pub fn new(x: u128) -> Box<dyn Iterator<Item = u128>> {
if true {
if !(x > 0) {
::core::panicking::panic("assertion failed: x > 0")
};
};
if x == 1 {
super::empty_shrinker()
} else {
Box::new(std::iter::once(1).chain(UnsignedNonZeroShrinker {
x,
i: x / 2,
}))
}
}
}
impl Iterator for UnsignedNonZeroShrinker {
type Item = u128;
fn next(&mut self) -> Option<u128> {
if self.x - self.i < self.x {
let result = Some(self.x - self.i);
self.i /= 2;
result
} else { None }
}
}
}
Box::new(shrinker::UnsignedNonZeroShrinker::new(self.get()).map(NonZeroU128::new).map(Option::unwrap))
}
}unsigned_non_zero_arbitrary! {
1066 NonZeroUsize => usize,
1067 NonZeroU8 => u8,
1068 NonZeroU16 => u16,
1069 NonZeroU32 => u32,
1070 NonZeroU64 => u64,
1071 NonZeroU128 => u128
1072}
1073
1074impl<T: Arbitrary> Arbitrary for Wrapping<T> {
1075 fn arbitrary(g: &mut Gen) -> Wrapping<T> {
1076 Wrapping(T::arbitrary(g))
1077 }
1078 fn shrink(&self) -> Box<dyn Iterator<Item = Wrapping<T>>> {
1079 Box::new(self.0.shrink().map(Wrapping))
1080 }
1081}
1082
1083impl<T: Arbitrary> Arbitrary for Bound<T> {
1084 fn arbitrary(g: &mut Gen) -> Bound<T> {
1085 match g.random_range(0..3) {
1086 0 => Bound::Included(T::arbitrary(g)),
1087 1 => Bound::Excluded(T::arbitrary(g)),
1088 _ => Bound::Unbounded,
1089 }
1090 }
1091 fn shrink(&self) -> Box<dyn Iterator<Item = Bound<T>>> {
1092 match *self {
1093 Bound::Included(ref x) => {
1094 Box::new(x.shrink().map(Bound::Included))
1095 }
1096 Bound::Excluded(ref x) => {
1097 Box::new(x.shrink().map(Bound::Excluded))
1098 }
1099 Bound::Unbounded => empty_shrinker(),
1100 }
1101 }
1102}
1103
1104impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for Range<T> {
1105 fn arbitrary(g: &mut Gen) -> Range<T> {
1106 Arbitrary::arbitrary(g)..Arbitrary::arbitrary(g)
1107 }
1108 fn shrink(&self) -> Box<dyn Iterator<Item = Range<T>>> {
1109 Box::new(
1110 (self.start.clone(), self.end.clone()).shrink().map(|(s, e)| s..e),
1111 )
1112 }
1113}
1114
1115impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeInclusive<T> {
1116 fn arbitrary(g: &mut Gen) -> RangeInclusive<T> {
1117 Arbitrary::arbitrary(g)..=Arbitrary::arbitrary(g)
1118 }
1119 fn shrink(&self) -> Box<dyn Iterator<Item = RangeInclusive<T>>> {
1120 Box::new(
1121 (self.start().clone(), self.end().clone())
1122 .shrink()
1123 .map(|(s, e)| s..=e),
1124 )
1125 }
1126}
1127
1128impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeFrom<T> {
1129 fn arbitrary(g: &mut Gen) -> RangeFrom<T> {
1130 Arbitrary::arbitrary(g)..
1131 }
1132 fn shrink(&self) -> Box<dyn Iterator<Item = RangeFrom<T>>> {
1133 Box::new(self.start.clone().shrink().map(|start| start..))
1134 }
1135}
1136
1137impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeTo<T> {
1138 fn arbitrary(g: &mut Gen) -> RangeTo<T> {
1139 ..Arbitrary::arbitrary(g)
1140 }
1141 fn shrink(&self) -> Box<dyn Iterator<Item = RangeTo<T>>> {
1142 Box::new(self.end.clone().shrink().map(|end| ..end))
1143 }
1144}
1145
1146impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeToInclusive<T> {
1147 fn arbitrary(g: &mut Gen) -> RangeToInclusive<T> {
1148 ..=Arbitrary::arbitrary(g)
1149 }
1150 fn shrink(&self) -> Box<dyn Iterator<Item = RangeToInclusive<T>>> {
1151 Box::new(self.end.clone().shrink().map(|end| ..=end))
1152 }
1153}
1154
1155impl Arbitrary for RangeFull {
1156 fn arbitrary(_: &mut Gen) -> RangeFull {
1157 ..
1158 }
1159}
1160
1161impl Arbitrary for Duration {
1162 fn arbitrary(rng: &mut Gen) -> Self {
1163 let seconds = rng.random_range(0..rng.size() as u64);
1164 let nanoseconds = rng.random_range(0..1_000_000);
1165 Duration::new(seconds, nanoseconds)
1166 }
1167
1168 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
1169 Box::new(
1170 (self.as_secs(), self.subsec_nanos())
1171 .shrink()
1172 .map(|(secs, nanos)| Duration::new(secs, nanos % 1_000_000)),
1173 )
1174 }
1175}
1176
1177impl<A: Arbitrary> Arbitrary for Box<A> {
1178 fn arbitrary(g: &mut Gen) -> Box<A> {
1179 Box::new(A::arbitrary(g))
1180 }
1181
1182 fn shrink(&self) -> Box<dyn Iterator<Item = Box<A>>> {
1183 Box::new((**self).shrink().map(Box::new))
1184 }
1185}
1186
1187impl<A: Arbitrary + Sync> Arbitrary for Arc<A> {
1188 fn arbitrary(g: &mut Gen) -> Arc<A> {
1189 Arc::new(A::arbitrary(g))
1190 }
1191
1192 fn shrink(&self) -> Box<dyn Iterator<Item = Arc<A>>> {
1193 Box::new((**self).shrink().map(Arc::new))
1194 }
1195}
1196
1197impl Arbitrary for SystemTime {
1198 fn arbitrary(rng: &mut Gen) -> Self {
1199 let after_epoch = bool::arbitrary(rng);
1200 let duration = Duration::arbitrary(rng);
1201 successors(Some(duration), |d| Some(*d / 2))
1202 .take_while(|d| !d.is_zero())
1203 .find_map(|d| {
1204 if after_epoch {
1205 UNIX_EPOCH.checked_add(d)
1206 } else {
1207 UNIX_EPOCH.checked_sub(d)
1208 }
1209 })
1210 .unwrap_or(UNIX_EPOCH)
1211 }
1212
1213 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
1214 let duration = match self.duration_since(UNIX_EPOCH) {
1215 Ok(duration) => duration,
1216 Err(e) => e.duration(),
1217 };
1218 Box::new(
1219 duration
1220 .shrink()
1221 .flat_map(|d| ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[UNIX_EPOCH + d, UNIX_EPOCH - d]))vec![UNIX_EPOCH + d, UNIX_EPOCH - d]),
1222 )
1223 }
1224}
1225
1226#[derive(#[automatically_derived]
impl<A: ::core::clone::Clone + Arbitrary> ::core::clone::Clone for NoShrink<A>
{
#[inline]
fn clone(&self) -> NoShrink<A> {
NoShrink { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, #[automatically_derived]
impl<A: ::core::fmt::Debug + Arbitrary> ::core::fmt::Debug for NoShrink<A> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "NoShrink",
"inner", &&self.inner)
}
}Debug)]
1246pub struct NoShrink<A: Arbitrary> {
1247 inner: A,
1248}
1249
1250impl<A: Arbitrary> NoShrink<A> {
1251 pub fn into_inner(self) -> A {
1253 self.inner
1254 }
1255
1256 pub fn inner(&self) -> &A {
1258 &self.inner
1259 }
1260}
1261
1262impl<A: Arbitrary> Arbitrary for NoShrink<A> {
1263 fn arbitrary(rnd: &mut Gen) -> Self {
1264 Self { inner: Arbitrary::arbitrary(rnd) }
1265 }
1266}
1267
1268#[cfg(test)]
1269mod test {
1270 use std::collections::{
1271 BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
1272 };
1273 use std::fmt::Debug;
1274 use std::hash::Hash;
1275 use std::num::Wrapping;
1276 use std::path::PathBuf;
1277
1278 use super::{Arbitrary, Gen};
1279
1280 #[test]
1281 fn arby_unit() {
1282 let _: () = arby::<()>();
1283 }
1284
1285 macro_rules! arby_int {
1286 ( $signed:expr, $($t:ty),+) => {$(
1287 let mut arbys = (0..1_000_000).map(|_| arby::<$t>());
1288 let mut problems = if $signed {
1289 signed_problem_values!($t).iter()
1290 } else {
1291 unsigned_problem_values!($t).iter()
1292 };
1293 assert!(problems.all(|p| arbys.any(|arby| arby == *p)),
1294 "Arbitrary does not generate all problematic values");
1295 let max = <$t>::MAX;
1296 let mid = (max + <$t>::MIN) / 2;
1297 let double_chunks: $t = 9;
1300 let chunks = double_chunks * 2; let lim: Box<dyn Iterator<Item=$t>> = if $signed {
1302 Box::new((0..=chunks)
1303 .map(|idx| idx - chunks / 2)
1304 .map(|x| mid + max / (chunks / 2) * x))
1305 } else {
1306 Box::new((0..=chunks).map(|idx| max / chunks * idx))
1307 };
1308 let mut lim = lim.peekable();
1309 while let (Some(low), Some(&high)) = (lim.next(), lim.peek()) {
1310 assert!(arbys.any(|arby| low <= arby && arby <= high),
1311 "Arbitrary doesn't generate numbers in {}..={}", low, high)
1312 }
1313 )*};
1314 }
1315
1316 #[test]
1317 fn arby_int() {
1318 arby_int!(true, i8, i16, i32, i64, isize, i128);
1319 }
1320
1321 #[test]
1322 fn arby_uint() {
1323 arby_int!(false, u8, u16, u32, u64, usize, u128);
1324 }
1325
1326 macro_rules! arby_float {
1327 ($($t:ty),+) => {$({
1328 let mut arbys = (0..1_000_000).map(|_| arby::<$t>());
1329 assert!(arbys.any(|f| f.is_nan()),
1331 "Arbitrary does not generate the problematic value NaN"
1332 );
1333 for p in float_problem_values!($t).iter().filter(|f| !f.is_nan()) {
1334 assert!(arbys.any(|arby| arby == *p),
1335 "Arbitrary does not generate the problematic value {}",
1336 p
1337 );
1338 }
1339 let double_chunks: i8 = 9;
1342 let chunks = double_chunks * 2; let lim = (-double_chunks..=double_chunks)
1344 .map(|idx| <$t>::from(idx))
1345 .map(|idx| <$t>::MAX/(<$t>::from(chunks/2)) * idx);
1346 let mut lim = lim.peekable();
1347 while let (Some(low), Some(&high)) = (lim.next(), lim.peek()) {
1348 assert!(
1349 arbys.any(|arby| low <= arby && arby <= high),
1350 "Arbitrary doesn't generate numbers in {:e}..={:e}",
1351 low,
1352 high,
1353 )
1354 }
1355 })*};
1356 }
1357
1358 #[test]
1359 fn arby_float() {
1360 arby_float!(f32, f64);
1361 }
1362
1363 fn arby<A: Arbitrary>() -> A {
1364 Arbitrary::arbitrary(&mut Gen::new(5))
1365 }
1366
1367 #[test]
1369 fn unit() {
1370 eq((), vec![]);
1371 }
1372
1373 #[test]
1374 fn bools() {
1375 eq(false, vec![]);
1376 eq(true, vec![false]);
1377 }
1378
1379 #[test]
1380 fn options() {
1381 eq(None::<()>, vec![]);
1382 eq(Some(false), vec![None]);
1383 eq(Some(true), vec![None, Some(false)]);
1384 }
1385
1386 #[test]
1387 fn results() {
1388 ordered_eq(Ok::<bool, ()>(true), vec![Ok(false)]);
1392 ordered_eq(Err::<(), bool>(true), vec![Err(false)]);
1393 }
1394
1395 #[test]
1396 fn tuples() {
1397 eq((false, false), vec![]);
1398 eq((true, false), vec![(false, false)]);
1399 eq((true, true), vec![(false, true), (true, false)]);
1400 }
1401
1402 #[test]
1403 fn triples() {
1404 eq((false, false, false), vec![]);
1405 eq((true, false, false), vec![(false, false, false)]);
1406 eq(
1407 (true, true, false),
1408 vec![(false, true, false), (true, false, false)],
1409 );
1410 }
1411
1412 #[test]
1413 fn quads() {
1414 eq((false, false, false, false), vec![]);
1415 eq((true, false, false, false), vec![(false, false, false, false)]);
1416 eq(
1417 (true, true, false, false),
1418 vec![(false, true, false, false), (true, false, false, false)],
1419 );
1420 }
1421
1422 #[test]
1423 fn ints() {
1424 eq(5isize, vec![0, 3, 4]);
1426 eq(-5isize, vec![5, 0, -3, -4]);
1427 eq(0isize, vec![]);
1428 }
1429
1430 #[test]
1431 fn ints8() {
1432 eq(5i8, vec![0, 3, 4]);
1433 eq(-5i8, vec![5, 0, -3, -4]);
1434 eq(0i8, vec![]);
1435 }
1436
1437 #[test]
1438 fn ints16() {
1439 eq(5i16, vec![0, 3, 4]);
1440 eq(-5i16, vec![5, 0, -3, -4]);
1441 eq(0i16, vec![]);
1442 }
1443
1444 #[test]
1445 fn ints32() {
1446 eq(5i32, vec![0, 3, 4]);
1447 eq(-5i32, vec![5, 0, -3, -4]);
1448 eq(0i32, vec![]);
1449 }
1450
1451 #[test]
1452 fn ints64() {
1453 eq(5i64, vec![0, 3, 4]);
1454 eq(-5i64, vec![5, 0, -3, -4]);
1455 eq(0i64, vec![]);
1456 }
1457
1458 #[test]
1459 fn ints128() {
1460 eq(5i128, vec![0, 3, 4]);
1461 eq(-5i128, vec![5, 0, -3, -4]);
1462 eq(0i128, vec![]);
1463 }
1464
1465 #[test]
1466 fn uints() {
1467 eq(5usize, vec![0, 3, 4]);
1468 eq(0usize, vec![]);
1469 }
1470
1471 #[test]
1472 fn uints8() {
1473 eq(5u8, vec![0, 3, 4]);
1474 eq(0u8, vec![]);
1475 }
1476
1477 #[test]
1478 fn uints16() {
1479 eq(5u16, vec![0, 3, 4]);
1480 eq(0u16, vec![]);
1481 }
1482
1483 #[test]
1484 fn uints32() {
1485 eq(5u32, vec![0, 3, 4]);
1486 eq(0u32, vec![]);
1487 }
1488
1489 #[test]
1490 fn uints64() {
1491 eq(5u64, vec![0, 3, 4]);
1492 eq(0u64, vec![]);
1493 }
1494
1495 #[test]
1496 fn uints128() {
1497 eq(5u128, vec![0, 3, 4]);
1498 eq(0u128, vec![]);
1499 }
1500
1501 macro_rules! define_float_eq {
1502 ($ty:ty) => {
1503 fn eq(s: $ty, v: Vec<$ty>) {
1504 let shrunk: Vec<$ty> = s.shrink().collect();
1505 for n in v {
1506 let found = shrunk.iter().any(|&i| i == n);
1507 if !found {
1508 panic!(
1509 "Element {:?} was not found \
1510 in shrink results {:?}",
1511 n, shrunk
1512 );
1513 }
1514 }
1515 }
1516 };
1517 }
1518
1519 #[test]
1520 fn floats32() {
1521 define_float_eq!(f32);
1522
1523 eq(0.0, vec![]);
1524 eq(-0.0, vec![]);
1525 eq(1.0, vec![0.0]);
1526 eq(2.0, vec![0.0, 1.0]);
1527 eq(-2.0, vec![0.0, 2.0, -1.0]);
1528 eq(1.5, vec![0.0]);
1529 }
1530
1531 #[test]
1532 fn floats64() {
1533 define_float_eq!(f64);
1534
1535 eq(0.0, vec![]);
1536 eq(-0.0, vec![]);
1537 eq(1.0, vec![0.0]);
1538 eq(2.0, vec![0.0, 1.0]);
1539 eq(-2.0, vec![0.0, 2.0, -1.0]);
1540 eq(1.5, vec![0.0]);
1541 }
1542
1543 #[test]
1544 fn wrapping_ints32() {
1545 eq(Wrapping(5i32), vec![Wrapping(0), Wrapping(3), Wrapping(4)]);
1546 eq(
1547 Wrapping(-5i32),
1548 vec![Wrapping(5), Wrapping(0), Wrapping(-3), Wrapping(-4)],
1549 );
1550 eq(Wrapping(0i32), vec![]);
1551 }
1552
1553 #[test]
1554 fn vecs() {
1555 eq(
1556 {
1557 let it: Vec<isize> = vec![];
1558 it
1559 },
1560 vec![],
1561 );
1562 eq(
1563 {
1564 let it: Vec<Vec<isize>> = vec![vec![]];
1565 it
1566 },
1567 vec![vec![]],
1568 );
1569 eq(vec![1isize], vec![vec![], vec![0]]);
1570 eq(vec![11isize], vec![vec![], vec![0], vec![6], vec![9], vec![10]]);
1571 eq(
1572 vec![3isize, 5],
1573 vec![
1574 vec![],
1575 vec![5],
1576 vec![3],
1577 vec![0, 5],
1578 vec![2, 5],
1579 vec![3, 0],
1580 vec![3, 3],
1581 vec![3, 4],
1582 ],
1583 );
1584 }
1585
1586 macro_rules! map_tests {
1587 ($name:ident, $ctor:expr) => {
1588 #[test]
1589 fn $name() {
1590 ordered_eq($ctor, vec![]);
1591
1592 {
1593 let mut map = $ctor;
1594 map.insert(1usize, 1isize);
1595
1596 let shrinks = vec![
1597 $ctor,
1598 {
1599 let mut m = $ctor;
1600 m.insert(0, 1);
1601 m
1602 },
1603 {
1604 let mut m = $ctor;
1605 m.insert(1, 0);
1606 m
1607 },
1608 ];
1609
1610 ordered_eq(map, shrinks);
1611 }
1612 }
1613 };
1614 }
1615
1616 map_tests!(btreemap, BTreeMap::<usize, isize>::new());
1617 map_tests!(hashmap, HashMap::<usize, isize>::new());
1618
1619 macro_rules! list_tests {
1620 ($name:ident, $ctor:expr, $push:ident) => {
1621 #[test]
1622 fn $name() {
1623 ordered_eq($ctor, vec![]);
1624
1625 {
1626 let mut list = $ctor;
1627 list.$push(2usize);
1628
1629 let shrinks = vec![
1630 $ctor,
1631 {
1632 let mut m = $ctor;
1633 m.$push(0);
1634 m
1635 },
1636 {
1637 let mut m = $ctor;
1638 m.$push(1);
1639 m
1640 },
1641 ];
1642
1643 ordered_eq(list, shrinks);
1644 }
1645 }
1646 };
1647 }
1648
1649 list_tests!(btreesets, BTreeSet::<usize>::new(), insert);
1650 list_tests!(hashsets, HashSet::<usize>::new(), insert);
1651 list_tests!(linkedlists, LinkedList::<usize>::new(), push_back);
1652 list_tests!(vecdeques, VecDeque::<usize>::new(), push_back);
1653
1654 #[test]
1655 fn binaryheaps() {
1656 ordered_eq(
1657 BinaryHeap::<usize>::new().into_iter().collect::<Vec<_>>(),
1658 vec![],
1659 );
1660
1661 {
1662 let mut heap = BinaryHeap::<usize>::new();
1663 heap.push(2usize);
1664
1665 let shrinks = vec![vec![], vec![0], vec![1]];
1666
1667 ordered_eq(heap.into_iter().collect::<Vec<_>>(), shrinks);
1668 }
1669 }
1670
1671 #[test]
1672 fn chars() {
1673 eq('\x00', vec![]);
1674 }
1675
1676 fn eq<A: Arbitrary + Eq + Debug + Hash>(s: A, v: Vec<A>) {
1678 let (left, right) = (shrunk(s), set(v));
1679 assert_eq!(left, right);
1680 }
1681 fn shrunk<A: Arbitrary + Eq + Hash>(s: A) -> HashSet<A> {
1682 set(s.shrink())
1683 }
1684 fn set<A: Hash + Eq, I: IntoIterator<Item = A>>(xs: I) -> HashSet<A> {
1685 xs.into_iter().collect()
1686 }
1687
1688 fn ordered_eq<A: Arbitrary + Eq + Debug>(s: A, v: Vec<A>) {
1689 let (left, right) = (s.shrink().collect::<Vec<A>>(), v);
1690 assert_eq!(left, right);
1691 }
1692
1693 #[test]
1694 fn bounds() {
1695 use std::ops::Bound::*;
1696 for i in -5..=5 {
1697 ordered_eq(Included(i), i.shrink().map(Included).collect());
1698 ordered_eq(Excluded(i), i.shrink().map(Excluded).collect());
1699 }
1700 eq(Unbounded::<i32>, vec![]);
1701 }
1702
1703 #[allow(clippy::reversed_empty_ranges)]
1704 #[test]
1705 fn ranges() {
1706 ordered_eq(0..0, vec![]);
1707 ordered_eq(1..1, vec![0..1, 1..0]);
1708 ordered_eq(3..5, vec![0..5, 2..5, 3..0, 3..3, 3..4]);
1709 ordered_eq(5..3, vec![0..3, 3..3, 4..3, 5..0, 5..2]);
1710 ordered_eq(3.., vec![0.., 2..]);
1711 ordered_eq(..3, vec![..0, ..2]);
1712 ordered_eq(.., vec![]);
1713 ordered_eq(3..=5, vec![0..=5, 2..=5, 3..=0, 3..=3, 3..=4]);
1714 ordered_eq(..=3, vec![..=0, ..=2]);
1715 }
1716
1717 #[test]
1718 fn pathbuf() {
1719 ordered_eq(
1720 PathBuf::from("/home/foo//.././bar"),
1721 vec![
1722 PathBuf::from("/home/foo//.."),
1723 PathBuf::from("/home/foo/../bar"),
1724 ],
1725 );
1726 }
1727}