use std::char;
use std::collections::{
BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
};
use std::env;
use std::ffi::OsString;
use std::hash::{BuildHasher, Hash};
use std::iter::{empty, once};
use std::net::{
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
};
use std::num::Wrapping;
use std::ops::{Bound, Range, RangeFrom, RangeFull, RangeTo};
use std::path::PathBuf;
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use rand::seq::SliceRandom;
use rand::{self, Rng, RngCore};
pub trait Gen: RngCore {
fn size(&self) -> usize;
}
pub struct StdGen<R> {
rng: R,
size: usize,
}
impl<R: RngCore> StdGen<R> {
pub fn new(rng: R, size: usize) -> StdGen<R> {
StdGen { rng: rng, size: size }
}
}
impl<R: RngCore> RngCore for StdGen<R> {
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.rng.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.rng.fill_bytes(dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
self.rng.try_fill_bytes(dest)
}
}
impl<R: RngCore> Gen for StdGen<R> {
fn size(&self) -> usize {
self.size
}
}
pub struct StdThreadGen(StdGen<rand::rngs::ThreadRng>);
impl StdThreadGen {
pub fn new(size: usize) -> StdThreadGen {
StdThreadGen(StdGen { rng: rand::thread_rng(), size: size })
}
}
impl RngCore for StdThreadGen {
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
self.0.try_fill_bytes(dest)
}
}
impl Gen for StdThreadGen {
fn size(&self) -> usize {
self.0.size
}
}
pub fn empty_shrinker<A: 'static>() -> Box<dyn Iterator<Item = A>> {
Box::new(empty())
}
pub fn single_shrinker<A: 'static>(value: A) -> Box<dyn Iterator<Item = A>> {
Box::new(once(value))
}
pub trait Arbitrary: Clone + Send + 'static {
fn arbitrary<G: Gen>(g: &mut G) -> Self;
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
empty_shrinker()
}
}
impl Arbitrary for () {
fn arbitrary<G: Gen>(_: &mut G) -> () {
()
}
}
impl Arbitrary for bool {
fn arbitrary<G: Gen>(g: &mut G) -> bool {
g.gen()
}
fn shrink(&self) -> Box<dyn Iterator<Item = bool>> {
if *self {
single_shrinker(false)
} else {
empty_shrinker()
}
}
}
impl<A: Arbitrary> Arbitrary for Option<A> {
fn arbitrary<G: Gen>(g: &mut G) -> Option<A> {
if g.gen() {
None
} else {
Some(Arbitrary::arbitrary(g))
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = Option<A>>> {
match *self {
None => empty_shrinker(),
Some(ref x) => {
let chain = single_shrinker(None).chain(x.shrink().map(Some));
Box::new(chain)
}
}
}
}
impl<A: Arbitrary, B: Arbitrary> Arbitrary for Result<A, B> {
fn arbitrary<G: Gen>(g: &mut G) -> Result<A, B> {
if g.gen() {
Ok(Arbitrary::arbitrary(g))
} else {
Err(Arbitrary::arbitrary(g))
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = Result<A, B>>> {
match *self {
Ok(ref x) => {
let xs = x.shrink();
let tagged = xs.map(Ok);
Box::new(tagged)
}
Err(ref x) => {
let xs = x.shrink();
let tagged = xs.map(Err);
Box::new(tagged)
}
}
}
}
macro_rules! impl_arb_for_single_tuple {
($(($type_param:ident, $tuple_index:tt),)*) => {
impl<$($type_param),*> Arbitrary for ($($type_param,)*)
where $($type_param: Arbitrary,)*
{
fn arbitrary<GEN: Gen>(g: &mut GEN) -> ($($type_param,)*) {
(
$(
$type_param::arbitrary(g),
)*
)
}
fn shrink(&self) -> Box<dyn Iterator<Item=($($type_param,)*)>> {
let iter = ::std::iter::empty();
$(
let cloned = self.clone();
let iter = iter.chain(self.$tuple_index.shrink().map(move |shr_value| {
let mut result = cloned.clone();
result.$tuple_index = shr_value;
result
}));
)*
Box::new(iter)
}
}
};
}
macro_rules! impl_arb_for_tuples {
(@internal [$($acc:tt,)*]) => { };
(@internal [$($acc:tt,)*] ($type_param:ident, $tuple_index:tt), $($rest:tt,)*) => {
impl_arb_for_single_tuple!($($acc,)* ($type_param, $tuple_index),);
impl_arb_for_tuples!(@internal [$($acc,)* ($type_param, $tuple_index),] $($rest,)*);
};
($(($type_param:ident, $tuple_index:tt),)*) => {
impl_arb_for_tuples!(@internal [] $(($type_param, $tuple_index),)*);
};
}
impl_arb_for_tuples! {
(A, 0),
(B, 1),
(C, 2),
(D, 3),
(E, 4),
(F, 5),
(G, 6),
(H, 7),
}
impl<A: Arbitrary> Arbitrary for Vec<A> {
fn arbitrary<G: Gen>(g: &mut G) -> Vec<A> {
let size = {
let s = g.size();
g.gen_range(0, s)
};
(0..size).map(|_| Arbitrary::arbitrary(g)).collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = Vec<A>>> {
VecShrinker::new(self.clone())
}
}
struct VecShrinker<A> {
seed: Vec<A>,
size: usize,
offset: usize,
element_shrinker: Box<dyn Iterator<Item = A>>,
}
impl<A: Arbitrary> VecShrinker<A> {
fn new(seed: Vec<A>) -> Box<dyn Iterator<Item = Vec<A>>> {
let es = match seed.get(0) {
Some(e) => e.shrink(),
None => return empty_shrinker(),
};
let size = seed.len();
Box::new(VecShrinker {
seed: seed,
size: size,
offset: size,
element_shrinker: es,
})
}
fn next_element(&mut self) -> Option<A> {
loop {
match self.element_shrinker.next() {
Some(e) => return Some(e),
None => match self.seed.get(self.offset) {
Some(e) => {
self.element_shrinker = e.shrink();
self.offset += 1;
}
None => return None,
},
}
}
}
}
impl<A> Iterator for VecShrinker<A>
where
A: Arbitrary,
{
type Item = Vec<A>;
fn next(&mut self) -> Option<Vec<A>> {
if self.size == self.seed.len() {
self.size /= 2;
self.offset = self.size;
return Some(vec![]);
}
if self.size != 0 {
let xs1 = self.seed[..(self.offset - self.size)]
.iter()
.chain(&self.seed[self.offset..])
.cloned()
.collect();
self.offset += self.size;
if self.offset > self.seed.len() {
self.size /= 2;
self.offset = self.size;
}
Some(xs1)
} else {
if self.offset == 0 {
self.offset = 1
}
match self.next_element() {
Some(e) => Some(
self.seed[..self.offset - 1]
.iter()
.cloned()
.chain(Some(e).into_iter())
.chain(self.seed[self.offset..].iter().cloned())
.collect(),
),
None => None,
}
}
}
}
impl<K: Arbitrary + Ord, V: Arbitrary> Arbitrary for BTreeMap<K, V> {
fn arbitrary<G: Gen>(g: &mut G) -> BTreeMap<K, V> {
let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = BTreeMap<K, V>>> {
let vec: Vec<(K, V)> = self.clone().into_iter().collect();
Box::new(
vec.shrink().map(|v| v.into_iter().collect::<BTreeMap<K, V>>()),
)
}
}
impl<
K: Arbitrary + Eq + Hash,
V: Arbitrary,
S: BuildHasher + Default + Clone + Send + 'static,
> Arbitrary for HashMap<K, V, S>
{
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let vec: Vec<(K, V)> = self.clone().into_iter().collect();
Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
}
}
impl<T: Arbitrary + Ord> Arbitrary for BTreeSet<T> {
fn arbitrary<G: Gen>(g: &mut G) -> BTreeSet<T> {
let vec: Vec<T> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = BTreeSet<T>>> {
let vec: Vec<T> = self.clone().into_iter().collect();
Box::new(vec.shrink().map(|v| v.into_iter().collect::<BTreeSet<T>>()))
}
}
impl<T: Arbitrary + Ord> Arbitrary for BinaryHeap<T> {
fn arbitrary<G: Gen>(g: &mut G) -> BinaryHeap<T> {
let vec: Vec<T> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = BinaryHeap<T>>> {
let vec: Vec<T> = self.clone().into_iter().collect();
Box::new(
vec.shrink().map(|v| v.into_iter().collect::<BinaryHeap<T>>()),
)
}
}
impl<
T: Arbitrary + Eq + Hash,
S: BuildHasher + Default + Clone + Send + 'static,
> Arbitrary for HashSet<T, S>
{
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let vec: Vec<T> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let vec: Vec<T> = self.clone().into_iter().collect();
Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
}
}
impl<T: Arbitrary> Arbitrary for LinkedList<T> {
fn arbitrary<G: Gen>(g: &mut G) -> LinkedList<T> {
let vec: Vec<T> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = LinkedList<T>>> {
let vec: Vec<T> = self.clone().into_iter().collect();
Box::new(
vec.shrink().map(|v| v.into_iter().collect::<LinkedList<T>>()),
)
}
}
impl<T: Arbitrary> Arbitrary for VecDeque<T> {
fn arbitrary<G: Gen>(g: &mut G) -> VecDeque<T> {
let vec: Vec<T> = Arbitrary::arbitrary(g);
vec.into_iter().collect()
}
fn shrink(&self) -> Box<dyn Iterator<Item = VecDeque<T>>> {
let vec: Vec<T> = self.clone().into_iter().collect();
Box::new(vec.shrink().map(|v| v.into_iter().collect::<VecDeque<T>>()))
}
}
impl Arbitrary for IpAddr {
fn arbitrary<G: Gen>(g: &mut G) -> IpAddr {
let ipv4: bool = g.gen();
if ipv4 {
IpAddr::V4(Arbitrary::arbitrary(g))
} else {
IpAddr::V6(Arbitrary::arbitrary(g))
}
}
}
impl Arbitrary for Ipv4Addr {
fn arbitrary<G: Gen>(g: &mut G) -> Ipv4Addr {
Ipv4Addr::new(g.gen(), g.gen(), g.gen(), g.gen())
}
}
impl Arbitrary for Ipv6Addr {
fn arbitrary<G: Gen>(g: &mut G) -> Ipv6Addr {
Ipv6Addr::new(
g.gen(),
g.gen(),
g.gen(),
g.gen(),
g.gen(),
g.gen(),
g.gen(),
g.gen(),
)
}
}
impl Arbitrary for SocketAddr {
fn arbitrary<G: Gen>(g: &mut G) -> SocketAddr {
SocketAddr::new(Arbitrary::arbitrary(g), g.gen())
}
}
impl Arbitrary for SocketAddrV4 {
fn arbitrary<G: Gen>(g: &mut G) -> SocketAddrV4 {
SocketAddrV4::new(Arbitrary::arbitrary(g), g.gen())
}
}
impl Arbitrary for SocketAddrV6 {
fn arbitrary<G: Gen>(g: &mut G) -> SocketAddrV6 {
SocketAddrV6::new(Arbitrary::arbitrary(g), g.gen(), g.gen(), g.gen())
}
}
impl Arbitrary for PathBuf {
fn arbitrary<G: Gen>(g: &mut G) -> PathBuf {
let here =
env::current_dir().unwrap_or(PathBuf::from("/test/directory"));
let temp = env::temp_dir();
#[allow(deprecated)]
let home = env::home_dir().unwrap_or(PathBuf::from("/home/user"));
let choices = &[
here,
temp,
home,
PathBuf::from("."),
PathBuf::from(".."),
PathBuf::from("../../.."),
PathBuf::new(),
];
let mut p = choices.choose(g).unwrap().clone();
p.extend(Vec::<OsString>::arbitrary(g).iter());
p
}
fn shrink(&self) -> Box<dyn Iterator<Item = PathBuf>> {
let mut shrunk = vec![];
let mut popped = self.clone();
if popped.pop() {
shrunk.push(popped);
}
let normalized = self.iter().collect::<PathBuf>();
if normalized.as_os_str() != self.as_os_str() {
shrunk.push(normalized);
}
if let Ok(canonicalized) = self.canonicalize() {
if canonicalized.as_os_str() != self.as_os_str() {
shrunk.push(canonicalized);
}
}
Box::new(shrunk.into_iter())
}
}
impl Arbitrary for OsString {
fn arbitrary<G: Gen>(g: &mut G) -> OsString {
OsString::from(String::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = OsString>> {
let mystring: String = self.clone().into_string().unwrap();
Box::new(mystring.shrink().map(|s| OsString::from(s)))
}
}
impl Arbitrary for String {
fn arbitrary<G: Gen>(g: &mut G) -> String {
let size = {
let s = g.size();
g.gen_range(0, s)
};
let mut s = String::with_capacity(size);
for _ in 0..size {
s.push(char::arbitrary(g));
}
s
}
fn shrink(&self) -> Box<dyn Iterator<Item = String>> {
let chars: Vec<char> = self.chars().collect();
Box::new(chars.shrink().map(|x| x.into_iter().collect::<String>()))
}
}
impl Arbitrary for char {
fn arbitrary<G: Gen>(g: &mut G) -> char {
let mode = g.gen_range(0, 100);
match mode {
0..=49 => {
g.gen_range(0, 0xB0) as u8 as char
}
50..=59 => {
loop {
if let Some(x) = char::from_u32(g.gen_range(0, 0x10000)) {
return x;
}
}
}
60..=84 => {
[
' ', ' ', ' ', '\t', '\n', '~', '`', '!', '@', '#', '$',
'%', '^', '&', '*', '(', ')', '_', '-', '=', '+', '[',
']', '{', '}', ':', ';', '\'', '"', '\\', '|', ',', '<',
'>', '.', '/', '?', '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9',
]
.choose(g)
.unwrap()
.to_owned()
}
85..=89 => {
[
'\u{0149}',
'\u{fff0}',
'\u{fff1}',
'\u{fff2}',
'\u{fff3}',
'\u{fff4}',
'\u{fff5}',
'\u{fff6}',
'\u{fff7}',
'\u{fff8}',
'\u{fff9}',
'\u{fffA}',
'\u{fffB}',
'\u{fffC}',
'\u{fffD}',
'\u{fffE}',
'\u{fffF}',
'\u{0600}',
'\u{0601}',
'\u{0602}',
'\u{0603}',
'\u{0604}',
'\u{0605}',
'\u{061C}',
'\u{06DD}',
'\u{070F}',
'\u{180E}',
'\u{110BD}',
'\u{1D173}',
'\u{e0001}',
'\u{e0020}',
'\u{e000}',
'\u{e001}',
'\u{ef8ff}',
'\u{f0000}',
'\u{ffffd}',
'\u{ffffe}',
'\u{fffff}',
'\u{100000}',
'\u{10FFFD}',
'\u{10FFFE}',
'\u{10FFFF}',
'\u{3000}',
'\u{1680}',
]
.choose(g)
.unwrap()
.to_owned()
}
90..=94 => {
char::from_u32(g.gen_range(0x2000, 0x2070)).unwrap()
}
95..=99 => {
g.gen()
}
_ => unreachable!(),
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = char>> {
Box::new((*self as u32).shrink().filter_map(char::from_u32))
}
}
macro_rules! unsigned_shrinker {
($ty:ty) => {
mod shrinker {
pub struct UnsignedShrinker {
x: $ty,
i: $ty,
}
impl UnsignedShrinker {
pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
if x == 0 {
super::empty_shrinker()
} else {
Box::new(
vec![0]
.into_iter()
.chain(UnsignedShrinker { x: x, i: x / 2 }),
)
}
}
}
impl Iterator for UnsignedShrinker {
type Item = $ty;
fn next(&mut self) -> Option<$ty> {
if self.x - self.i < self.x {
let result = Some(self.x - self.i);
self.i = self.i / 2;
result
} else {
None
}
}
}
}
};
}
macro_rules! unsigned_arbitrary {
($($ty:tt),*) => {
$(
impl Arbitrary for $ty {
fn arbitrary<G: Gen>(g: &mut G) -> $ty {
#![allow(trivial_numeric_casts)]
let s = g.size() as $ty;
use std::cmp::{min, max};
g.gen_range(0, max(1, min(s, $ty::max_value())))
}
fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
unsigned_shrinker!($ty);
shrinker::UnsignedShrinker::new(*self)
}
}
)*
}
}
unsigned_arbitrary! {
usize, u8, u16, u32, u64
}
unsigned_arbitrary! {
u128
}
macro_rules! signed_shrinker {
($ty:ty) => {
mod shrinker {
pub struct SignedShrinker {
x: $ty,
i: $ty,
}
impl SignedShrinker {
pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
if x == 0 {
super::empty_shrinker()
} else {
let shrinker = SignedShrinker { x: x, i: x / 2 };
let mut items = vec![0];
if shrinker.i < 0 {
items.push(shrinker.x.abs());
}
Box::new(items.into_iter().chain(shrinker))
}
}
}
impl Iterator for SignedShrinker {
type Item = $ty;
fn next(&mut self) -> Option<$ty> {
if (self.x - self.i).abs() < self.x.abs() {
let result = Some(self.x - self.i);
self.i = self.i / 2;
result
} else {
None
}
}
}
}
};
}
macro_rules! signed_arbitrary {
($($ty:tt),*) => {
$(
impl Arbitrary for $ty {
fn arbitrary<G: Gen>(g: &mut G) -> $ty {
use std::cmp::{min,max};
let upper = min(g.size(), $ty::max_value() as usize);
let lower = if upper > $ty::max_value() as usize {
$ty::min_value()
} else {
-(upper as $ty)
};
g.gen_range(lower, max(1, upper as $ty))
}
fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
signed_shrinker!($ty);
shrinker::SignedShrinker::new(*self)
}
}
)*
}
}
signed_arbitrary! {
isize, i8, i16, i32, i64
}
signed_arbitrary! {
i128
}
impl Arbitrary for f32 {
fn arbitrary<G: Gen>(g: &mut G) -> f32 {
let s = g.size();
g.gen_range(-(s as f32), s as f32)
}
fn shrink(&self) -> Box<dyn Iterator<Item = f32>> {
signed_shrinker!(i32);
let it = shrinker::SignedShrinker::new(*self as i32);
Box::new(it.map(|x| x as f32))
}
}
impl Arbitrary for f64 {
fn arbitrary<G: Gen>(g: &mut G) -> f64 {
let s = g.size();
g.gen_range(-(s as f64), s as f64)
}
fn shrink(&self) -> Box<dyn Iterator<Item = f64>> {
signed_shrinker!(i64);
let it = shrinker::SignedShrinker::new(*self as i64);
Box::new(it.map(|x| x as f64))
}
}
impl<T: Arbitrary> Arbitrary for Wrapping<T> {
fn arbitrary<G: Gen>(g: &mut G) -> Wrapping<T> {
Wrapping(T::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Wrapping<T>>> {
Box::new(self.0.shrink().map(|inner| Wrapping(inner)))
}
}
impl<T: Arbitrary> Arbitrary for Bound<T> {
fn arbitrary<G: Gen>(g: &mut G) -> Bound<T> {
match g.gen_range(0, 3) {
0 => Bound::Included(T::arbitrary(g)),
1 => Bound::Excluded(T::arbitrary(g)),
_ => Bound::Unbounded,
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = Bound<T>>> {
match *self {
Bound::Included(ref x) => {
Box::new(x.shrink().map(Bound::Included))
}
Bound::Excluded(ref x) => {
Box::new(x.shrink().map(Bound::Excluded))
}
Bound::Unbounded => empty_shrinker(),
}
}
}
impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for Range<T> {
fn arbitrary<G: Gen>(g: &mut G) -> Range<T> {
Arbitrary::arbitrary(g)..Arbitrary::arbitrary(g)
}
fn shrink(&self) -> Box<dyn Iterator<Item = Range<T>>> {
Box::new(
(self.start.clone(), self.end.clone()).shrink().map(|(s, e)| s..e),
)
}
}
impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeFrom<T> {
fn arbitrary<G: Gen>(g: &mut G) -> RangeFrom<T> {
Arbitrary::arbitrary(g)..
}
fn shrink(&self) -> Box<dyn Iterator<Item = RangeFrom<T>>> {
Box::new(self.start.clone().shrink().map(|start| start..))
}
}
impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeTo<T> {
fn arbitrary<G: Gen>(g: &mut G) -> RangeTo<T> {
..Arbitrary::arbitrary(g)
}
fn shrink(&self) -> Box<dyn Iterator<Item = RangeTo<T>>> {
Box::new(self.end.clone().shrink().map(|end| ..end))
}
}
impl Arbitrary for RangeFull {
fn arbitrary<G: Gen>(_: &mut G) -> RangeFull {
..
}
}
impl Arbitrary for Duration {
fn arbitrary<G: Gen>(gen: &mut G) -> Self {
let seconds = u64::arbitrary(gen);
let nanoseconds = u32::arbitrary(gen) % 1_000_000;
Duration::new(seconds, nanoseconds)
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
Box::new(
(self.as_secs(), self.subsec_nanos())
.shrink()
.map(|(secs, nanos)| Duration::new(secs, nanos % 1_000_000)),
)
}
}
impl<A: Arbitrary> Arbitrary for Box<A> {
fn arbitrary<G: Gen>(g: &mut G) -> Box<A> {
Box::new(A::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Box<A>>> {
Box::new((**self).shrink().map(Box::new))
}
}
impl<A: Arbitrary + Sync> Arbitrary for Arc<A> {
fn arbitrary<G: Gen>(g: &mut G) -> Arc<A> {
Arc::new(A::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Arc<A>>> {
Box::new((**self).shrink().map(Arc::new))
}
}
impl Arbitrary for SystemTime {
fn arbitrary<G: Gen>(gen: &mut G) -> Self {
let after_epoch = bool::arbitrary(gen);
let duration = Duration::arbitrary(gen);
if after_epoch {
UNIX_EPOCH + duration
} else {
UNIX_EPOCH - duration
}
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let duration = match self.duration_since(UNIX_EPOCH) {
Ok(duration) => duration,
Err(e) => e.duration(),
};
Box::new(
duration
.shrink()
.flat_map(|d| vec![UNIX_EPOCH + d, UNIX_EPOCH - d]),
)
}
}
#[cfg(test)]
mod test {
use super::Arbitrary;
use rand;
use std::collections::{
BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
};
use std::fmt::Debug;
use std::hash::Hash;
use std::num::Wrapping;
use std::path::PathBuf;
#[test]
fn arby_unit() {
assert_eq!(arby::<()>(), ());
}
#[test]
fn arby_int() {
rep(&mut || {
let n: isize = arby();
assert!(n >= -5 && n <= 5);
});
}
#[test]
fn arby_uint() {
rep(&mut || {
let n: usize = arby();
assert!(n <= 5);
});
}
fn arby<A: super::Arbitrary>() -> A {
super::Arbitrary::arbitrary(&mut gen())
}
fn gen() -> super::StdGen<rand::rngs::ThreadRng> {
super::StdGen::new(rand::thread_rng(), 5)
}
fn rep<F>(f: &mut F)
where
F: FnMut() -> (),
{
for _ in 0..100 {
f()
}
}
#[test]
fn unit() {
eq((), vec![]);
}
#[test]
fn bools() {
eq(false, vec![]);
eq(true, vec![false]);
}
#[test]
fn options() {
eq(None::<()>, vec![]);
eq(Some(false), vec![None]);
eq(Some(true), vec![None, Some(false)]);
}
#[test]
fn results() {
ordered_eq(Ok::<bool, ()>(true), vec![Ok(false)]);
ordered_eq(Err::<(), bool>(true), vec![Err(false)]);
}
#[test]
fn tuples() {
eq((false, false), vec![]);
eq((true, false), vec![(false, false)]);
eq((true, true), vec![(false, true), (true, false)]);
}
#[test]
fn triples() {
eq((false, false, false), vec![]);
eq((true, false, false), vec![(false, false, false)]);
eq(
(true, true, false),
vec![(false, true, false), (true, false, false)],
);
}
#[test]
fn quads() {
eq((false, false, false, false), vec![]);
eq((true, false, false, false), vec![(false, false, false, false)]);
eq(
(true, true, false, false),
vec![(false, true, false, false), (true, false, false, false)],
);
}
#[test]
fn ints() {
eq(5isize, vec![0, 3, 4]);
eq(-5isize, vec![5, 0, -3, -4]);
eq(0isize, vec![]);
}
#[test]
fn ints8() {
eq(5i8, vec![0, 3, 4]);
eq(-5i8, vec![5, 0, -3, -4]);
eq(0i8, vec![]);
}
#[test]
fn ints16() {
eq(5i16, vec![0, 3, 4]);
eq(-5i16, vec![5, 0, -3, -4]);
eq(0i16, vec![]);
}
#[test]
fn ints32() {
eq(5i32, vec![0, 3, 4]);
eq(-5i32, vec![5, 0, -3, -4]);
eq(0i32, vec![]);
}
#[test]
fn ints64() {
eq(5i64, vec![0, 3, 4]);
eq(-5i64, vec![5, 0, -3, -4]);
eq(0i64, vec![]);
}
#[test]
fn ints128() {
eq(5i128, vec![0, 3, 4]);
eq(-5i128, vec![5, 0, -3, -4]);
eq(0i128, vec![]);
}
#[test]
fn uints() {
eq(5usize, vec![0, 3, 4]);
eq(0usize, vec![]);
}
#[test]
fn uints8() {
eq(5u8, vec![0, 3, 4]);
eq(0u8, vec![]);
}
#[test]
fn uints16() {
eq(5u16, vec![0, 3, 4]);
eq(0u16, vec![]);
}
#[test]
fn uints32() {
eq(5u32, vec![0, 3, 4]);
eq(0u32, vec![]);
}
#[test]
fn uints64() {
eq(5u64, vec![0, 3, 4]);
eq(0u64, vec![]);
}
#[test]
fn uints128() {
eq(5u128, vec![0, 3, 4]);
eq(0u128, vec![]);
}
macro_rules! define_float_eq {
($ty:ty) => {
fn eq(s: $ty, v: Vec<$ty>) {
let shrunk: Vec<$ty> = s.shrink().collect();
for n in v {
let found = shrunk.iter().any(|&i| i == n);
if !found {
panic!(format!(
"Element {:?} was not found \
in shrink results {:?}",
n, shrunk
));
}
}
}
};
}
#[test]
fn floats32() {
define_float_eq!(f32);
eq(0.0, vec![]);
eq(-0.0, vec![]);
eq(1.0, vec![0.0]);
eq(2.0, vec![0.0, 1.0]);
eq(-2.0, vec![0.0, 2.0, -1.0]);
eq(1.5, vec![0.0]);
}
#[test]
fn floats64() {
define_float_eq!(f64);
eq(0.0, vec![]);
eq(-0.0, vec![]);
eq(1.0, vec![0.0]);
eq(2.0, vec![0.0, 1.0]);
eq(-2.0, vec![0.0, 2.0, -1.0]);
eq(1.5, vec![0.0]);
}
#[test]
fn wrapping_ints32() {
eq(Wrapping(5i32), vec![Wrapping(0), Wrapping(3), Wrapping(4)]);
eq(
Wrapping(-5i32),
vec![Wrapping(5), Wrapping(0), Wrapping(-3), Wrapping(-4)],
);
eq(Wrapping(0i32), vec![]);
}
#[test]
fn vecs() {
eq(
{
let it: Vec<isize> = vec![];
it
},
vec![],
);
eq(
{
let it: Vec<Vec<isize>> = vec![vec![]];
it
},
vec![vec![]],
);
eq(vec![1isize], vec![vec![], vec![0]]);
eq(vec![11isize], vec![vec![], vec![0], vec![6], vec![9], vec![10]]);
eq(
vec![3isize, 5],
vec![
vec![],
vec![5],
vec![3],
vec![0, 5],
vec![2, 5],
vec![3, 0],
vec![3, 3],
vec![3, 4],
],
);
}
macro_rules! map_tests {
($name:ident, $ctor:expr) => {
#[test]
fn $name() {
ordered_eq($ctor, vec![]);
{
let mut map = $ctor;
map.insert(1usize, 1isize);
let shrinks = vec![
$ctor,
{
let mut m = $ctor;
m.insert(0, 1);
m
},
{
let mut m = $ctor;
m.insert(1, 0);
m
},
];
ordered_eq(map, shrinks);
}
}
};
}
map_tests!(btreemap, BTreeMap::<usize, isize>::new());
map_tests!(hashmap, HashMap::<usize, isize>::new());
macro_rules! list_tests {
($name:ident, $ctor:expr, $push:ident) => {
#[test]
fn $name() {
ordered_eq($ctor, vec![]);
{
let mut list = $ctor;
list.$push(2usize);
let shrinks = vec![
$ctor,
{
let mut m = $ctor;
m.$push(0);
m
},
{
let mut m = $ctor;
m.$push(1);
m
},
];
ordered_eq(list, shrinks);
}
}
};
}
list_tests!(btreesets, BTreeSet::<usize>::new(), insert);
list_tests!(hashsets, HashSet::<usize>::new(), insert);
list_tests!(linkedlists, LinkedList::<usize>::new(), push_back);
list_tests!(vecdeques, VecDeque::<usize>::new(), push_back);
#[test]
fn binaryheaps() {
ordered_eq(
BinaryHeap::<usize>::new().into_iter().collect::<Vec<_>>(),
vec![],
);
{
let mut heap = BinaryHeap::<usize>::new();
heap.push(2usize);
let shrinks = vec![vec![], vec![0], vec![1]];
ordered_eq(heap.into_iter().collect::<Vec<_>>(), shrinks);
}
}
#[test]
fn chars() {
eq('\x00', vec![]);
}
fn eq<A: Arbitrary + Eq + Debug + Hash>(s: A, v: Vec<A>) {
let (left, right) = (shrunk(s), set(v));
assert_eq!(left, right);
}
fn shrunk<A: Arbitrary + Eq + Hash>(s: A) -> HashSet<A> {
set(s.shrink().collect())
}
fn set<A: Eq + Hash>(xs: Vec<A>) -> HashSet<A> {
xs.into_iter().collect()
}
fn ordered_eq<A: Arbitrary + Eq + Debug>(s: A, v: Vec<A>) {
let (left, right) = (s.shrink().collect::<Vec<A>>(), v);
assert_eq!(left, right);
}
#[test]
fn bounds() {
use std::ops::Bound::*;
for i in -5..=5 {
ordered_eq(Included(i), i.shrink().map(Included).collect());
ordered_eq(Excluded(i), i.shrink().map(Excluded).collect());
}
eq(Unbounded::<i32>, vec![]);
}
#[test]
fn ranges() {
ordered_eq(0..0, vec![]);
ordered_eq(1..1, vec![0..1, 1..0]);
ordered_eq(3..5, vec![0..5, 2..5, 3..0, 3..3, 3..4]);
ordered_eq(5..3, vec![0..3, 3..3, 4..3, 5..0, 5..2]);
ordered_eq(3.., vec![0.., 2..]);
ordered_eq(..3, vec![..0, ..2]);
ordered_eq(.., vec![]);
}
#[test]
fn pathbuf() {
ordered_eq(
PathBuf::from("/home/foo//.././bar"),
vec![
PathBuf::from("/home/foo//.."),
PathBuf::from("/home/foo/../bar"),
],
);
}
}