diff options
Diffstat (limited to 'vendor/proptest/src/arbitrary')
44 files changed, 3583 insertions, 0 deletions
diff --git a/vendor/proptest/src/arbitrary/_alloc/alloc.rs b/vendor/proptest/src/arbitrary/_alloc/alloc.rs new file mode 100644 index 000000000..598c80ff0 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/alloc.rs @@ -0,0 +1,59 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::hash`. + +use core::cmp; +use core::ops::Range; +use core::usize; + +multiplex_alloc!(::alloc::alloc, ::std::alloc); + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +arbitrary!(self::alloc::Global; self::alloc::Global); + +// Not Debug. +//lazy_just!(System, || System); + +arbitrary!(self::alloc::Layout, SFnPtrMap<(Range<u8>, StrategyFor<usize>), Self>; + // 1. align must be a power of two and <= (1 << 31): + // 2. "when rounded up to the nearest multiple of align, must not overflow". + static_map((0u8..32u8, any::<usize>()), |(align_power, size)| { + let align = 1usize << align_power; + // TODO: This may only work on 64 bit processors, but previously it was broken + // even on 64 bit so still an improvement. 63 -> uint size - 1. + let max_size = (1usize << 63) - (1 << usize::from(align_power)); + // Not quite a uniform distribution due to clamping, + // but probably good enough + self::alloc::Layout::from_size_align(cmp::min(max_size, size), align).unwrap() + }) +); + +arbitrary!(self::alloc::AllocError, Just<Self>; Just(self::alloc::AllocError)); +/* 2018-07-28 CollectionAllocErr is not currently available outside of using + * the `alloc` crate, which would require a different nightly feature. For now, + * disable. +arbitrary!(alloc::collections::CollectionAllocErr, TupleUnion<(WA<Just<Self>>, WA<Just<Self>>)>; + prop_oneof![Just(alloc::collections::CollectionAllocErr::AllocErr), + Just(alloc::collections::CollectionAllocErr::CapacityOverflow)]); + */ + +#[cfg(test)] +mod test { + multiplex_alloc!(::alloc::alloc, ::std::alloc); + + no_panic_test!( + layout => self::alloc::Layout, + alloc_err => self::alloc::AllocError + //collection_alloc_err => alloc::collections::CollectionAllocErr + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/borrow.rs b/vendor/proptest/src/arbitrary/_alloc/borrow.rs new file mode 100644 index 000000000..153115e18 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/borrow.rs @@ -0,0 +1,27 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for std::borrow. + +use crate::std_facade::fmt; +use crate::std_facade::{Cow, ToOwned}; +use core::borrow::Borrow; + +use crate::arbitrary::{any_with, Arbitrary, SMapped}; +use crate::strategy::statics::static_map; + +arbitrary!( + [A: Arbitrary + Borrow<B>, B: ToOwned<Owned = A> + fmt::Debug + ?Sized] + Cow<'static, B>, SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Cow::Owned) +); + +lift1!([Borrow<B> + 'static, B: ToOwned<Owned = A> + fmt::Debug + ?Sized] + Cow<'static, B>; base => static_map(base, Cow::Owned) +); diff --git a/vendor/proptest/src/arbitrary/_alloc/boxed.rs b/vendor/proptest/src/arbitrary/_alloc/boxed.rs new file mode 100644 index 000000000..222362504 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/boxed.rs @@ -0,0 +1,19 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::boxed`. + +use crate::std_facade::Box; + +wrap_from!(Box); + +#[cfg(test)] +mod test { + no_panic_test!(boxed => Box<u8>); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/char.rs b/vendor/proptest/src/arbitrary/_alloc/char.rs new file mode 100644 index 000000000..fab9dd824 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/char.rs @@ -0,0 +1,89 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::char`. + +use crate::std_facade::Vec; +use core::char::*; +use core::iter::once; +use core::ops::Range; + +use crate::collection::vec; + +multiplex_alloc! { + core::char::DecodeUtf16, std::char::DecodeUtf16, + core::char::DecodeUtf16Error, std::char::DecodeUtf16Error, + core::char::decode_utf16, std::char::decode_utf16 +} + +const VEC_MAX: usize = ::core::u16::MAX as usize; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +macro_rules! impl_wrap_char { + ($type: ty, $mapper: expr) => { + arbitrary!($type, SMapped<char, Self>; + static_map(any::<char>(), $mapper)); + }; +} + +impl_wrap_char!(EscapeDebug, char::escape_debug); +impl_wrap_char!(EscapeDefault, char::escape_default); +impl_wrap_char!(EscapeUnicode, char::escape_unicode); +#[cfg(feature = "unstable")] +impl_wrap_char!(ToLowercase, char::to_lowercase); +#[cfg(feature = "unstable")] +impl_wrap_char!(ToUppercase, char::to_uppercase); + +#[cfg(feature = "break-dead-code")] +arbitrary!(DecodeUtf16<<Vec<u16> as IntoIterator>::IntoIter>, + SMapped<Vec<u16>, Self>; + static_map(vec(any::<u16>(), ..VEC_MAX), decode_utf16) +); + +arbitrary!(ParseCharError, IndFlatten<Mapped<bool, Just<Self>>>; + any::<bool>().prop_ind_flat_map(|is_two| + Just((if is_two { "__" } else { "" }).parse::<char>().unwrap_err())) +); + +#[cfg(feature = "unstable")] +arbitrary!(CharTryFromError; { + use core::convert::TryFrom; + char::try_from(0xD800 as u32).unwrap_err() +}); + +arbitrary!(DecodeUtf16Error, SFnPtrMap<Range<u16>, Self>; + static_map(0xD800..0xE000, |x| + decode_utf16(once(x)).next().unwrap().unwrap_err()) +); + +#[cfg(test)] +mod test { + no_panic_test!( + escape_debug => EscapeDebug, + escape_default => EscapeDefault, + escape_unicode => EscapeUnicode, + parse_char_error => ParseCharError, + decode_utf16_error => DecodeUtf16Error + ); + + #[cfg(feature = "break-dead-code")] + no_panic_test!( + decode_utf16 => DecodeUtf16<<Vec<u16> as IntoIterator>::IntoIter> + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + to_lowercase => ToLowercase, + to_uppercase => ToUppercase, + char_try_from_error => CharTryFromError + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/collections.rs b/vendor/proptest/src/arbitrary/_alloc/collections.rs new file mode 100644 index 000000000..20f3a9292 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/collections.rs @@ -0,0 +1,304 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::collections`. + +//#![cfg_attr(feature="cargo-clippy", allow(implicit_hasher))] + +//============================================================================== +// Imports: +//============================================================================== + +use crate::std_facade::{ + binary_heap, btree_map, btree_set, fmt, linked_list, vec, vec_deque, Arc, + BTreeMap, BTreeSet, BinaryHeap, Box, LinkedList, Rc, Vec, VecDeque, +}; +use core::hash::Hash; +use core::ops::{Bound, RangeInclusive}; + +#[cfg(feature = "std")] +use crate::std_facade::{hash_map, hash_set, HashMap, HashSet}; + +use crate::arbitrary::*; +use crate::collection::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +//============================================================================== +// Macros: +//============================================================================== + +/// Parameters for configuring the generation of `StrategyFor<...<A>>`. +type RangedParams1<A> = product_type![SizeRange, A]; + +/// Parameters for configuring the generation of `StrategyFor<...<A, B>>`. +type RangedParams2<A, B> = product_type![SizeRange, A, B]; + +macro_rules! impl_1 { + ($typ: ident, $strat: ident, $($bound : path),* => $fun: ident) => { + arbitrary!([A: Arbitrary $(+ $bound)*] $typ<A>, + $strat<A::Strategy>, RangedParams1<A::Parameters>; + args => { + let product_unpack![range, a] = args; + $fun(any_with::<A>(a), range) + }); + + lift1!([$($bound+)*] $typ<A>, SizeRange; + base, args => $fun(base, args)); + }; +} + +arbitrary!(SizeRange, MapInto<StrategyFor<RangeInclusive<usize>>, Self>; + any::<RangeInclusive<usize>>().prop_map_into() +); + +//============================================================================== +// Vec, VecDeque, LinkedList, BTreeSet, BinaryHeap, HashSet, HashMap: +//============================================================================== + +macro_rules! dst_wrapped { + ($($w: ident),*) => { + $(arbitrary!([A: Arbitrary] $w<[A]>, + MapInto<StrategyFor<Vec<A>>, Self>, + <Vec<A> as Arbitrary>::Parameters; + a => any_with::<Vec<A>>(a).prop_map_into() + );)* + }; +} + +impl_1!(Vec, VecStrategy, => vec); +dst_wrapped!(Box, Rc, Arc); +impl_1!(VecDeque, VecDequeStrategy, => vec_deque); +impl_1!(LinkedList, LinkedListStrategy, => linked_list); +impl_1!(BTreeSet, BTreeSetStrategy, Ord => btree_set); +impl_1!(BinaryHeap, BinaryHeapStrategy, Ord => binary_heap); +#[cfg(feature = "std")] +impl_1!(HashSet, HashSetStrategy, Hash, Eq => hash_set); + +//============================================================================== +// IntoIterator: +//============================================================================== + +macro_rules! into_iter_1 { + ($module: ident, $type: ident $(, $bound : path)*) => { + arbitrary!([A: Arbitrary $(+ $bound)*] + $module::IntoIter<A>, + SMapped<$type<A>, Self>, + <$type<A> as Arbitrary>::Parameters; + args => static_map(any_with::<$type<A>>(args), $type::into_iter)); + + lift1!(['static + $($bound+)*] $module::IntoIter<A>, SizeRange; + base, args => + $module(base, args).prop_map($type::into_iter)); + }; +} + +into_iter_1!(vec, Vec); +into_iter_1!(vec_deque, VecDeque); +into_iter_1!(linked_list, LinkedList); +into_iter_1!(btree_set, BTreeSet, Ord); +into_iter_1!(binary_heap, BinaryHeap, Ord); +#[cfg(feature = "std")] +into_iter_1!(hash_set, HashSet, Hash, Eq); + +//============================================================================== +// HashMap: +//============================================================================== + +#[cfg(feature = "std")] +arbitrary!([A: Arbitrary + Hash + Eq, B: Arbitrary] HashMap<A, B>, +HashMapStrategy<A::Strategy, B::Strategy>, +RangedParams2<A::Parameters, B::Parameters>; +args => { + let product_unpack![range, a, b] = args; + hash_map(any_with::<A>(a), any_with::<B>(b), range) +}); + +#[cfg(feature = "std")] +arbitrary!([A: Arbitrary + Hash + Eq, B: Arbitrary] hash_map::IntoIter<A, B>, + SMapped<HashMap<A, B>, Self>, + <HashMap<A, B> as Arbitrary>::Parameters; + args => static_map(any_with::<HashMap<A, B>>(args), HashMap::into_iter)); + +#[cfg(feature = "std")] +lift1!([, K: Hash + Eq + Arbitrary + 'static] HashMap<K, A>, + RangedParams1<K::Parameters>; + base, args => { + let product_unpack![range, k] = args; + hash_map(any_with::<K>(k), base, range) + } +); + +#[cfg(feature = "std")] +lift1!(['static, K: Hash + Eq + Arbitrary + 'static] hash_map::IntoIter<K, A>, + RangedParams1<K::Parameters>; + base, args => { + let product_unpack![range, k] = args; + static_map(hash_map(any_with::<K>(k), base, range), HashMap::into_iter) + } +); + +#[cfg(feature = "std")] +impl<A: fmt::Debug + Eq + Hash, B: fmt::Debug> functor::ArbitraryF2<A, B> + for HashMap<A, B> +{ + type Parameters = SizeRange; + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + hash_map(fst, snd, args).boxed() + } +} + +#[cfg(feature = "std")] +impl<A: fmt::Debug + Eq + Hash + 'static, B: fmt::Debug + 'static> + functor::ArbitraryF2<A, B> for hash_map::IntoIter<A, B> +{ + type Parameters = SizeRange; + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + static_map(hash_map(fst, snd, args), HashMap::into_iter).boxed() + } +} + +//============================================================================== +// BTreeMap: +//============================================================================== + +arbitrary!([A: Arbitrary + Ord, B: Arbitrary] BTreeMap<A, B>, +BTreeMapStrategy<A::Strategy, B::Strategy>, +RangedParams2<A::Parameters, B::Parameters>; +args => { + let product_unpack![range, a, b] = args; + btree_map(any_with::<A>(a), any_with::<B>(b), range) +}); + +lift1!([, K: Ord + Arbitrary + 'static] BTreeMap<K, A>, + RangedParams1<K::Parameters>; + base, args => { + let product_unpack![range, k] = args; + btree_map(any_with::<K>(k), base, range) + } +); + +impl<A: fmt::Debug + Ord, B: fmt::Debug> functor::ArbitraryF2<A, B> + for BTreeMap<A, B> +{ + type Parameters = SizeRange; + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + btree_map(fst, snd, args).boxed() + } +} + +arbitrary!([A: Arbitrary + Ord, B: Arbitrary] btree_map::IntoIter<A, B>, + SMapped<BTreeMap<A, B>, Self>, + <BTreeMap<A, B> as Arbitrary>::Parameters; + args => static_map(any_with::<BTreeMap<A, B>>(args), BTreeMap::into_iter)); + +impl<A: fmt::Debug + Ord + 'static, B: fmt::Debug + 'static> + functor::ArbitraryF2<A, B> for btree_map::IntoIter<A, B> +{ + type Parameters = SizeRange; + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + static_map(btree_map(fst, snd, args), BTreeMap::into_iter).boxed() + } +} + +//============================================================================== +// Bound: +//============================================================================== + +arbitrary!([A: Arbitrary] Bound<A>, + TupleUnion<( + WA<SFnPtrMap<Arc<A::Strategy>, Self>>, + WA<SFnPtrMap<Arc<A::Strategy>, Self>>, + WA<LazyJustFn<Self>> + )>, + A::Parameters; + args => { + let base = Arc::new(any_with::<A>(args)); + prop_oneof![ + 2 => static_map(base.clone(), Bound::Included), + 2 => static_map(base, Bound::Excluded), + 1 => LazyJust::new(|| Bound::Unbounded), + ] + } +); + +lift1!(['static] Bound<A>; base => { + let base = Rc::new(base); + prop_oneof![ + 2 => base.clone().prop_map(Bound::Included), + 2 => base.prop_map(Bound::Excluded), + 1 => LazyJustFn::new(|| Bound::Unbounded), + ] +}); + +#[cfg(test)] +mod test { + no_panic_test!( + size_bounds => SizeRange, + vec => Vec<u8>, + box_slice => Box<[u8]>, + rc_slice => Rc<[u8]>, + arc_slice => Arc<[u8]>, + vec_deque => VecDeque<u8>, + linked_list => LinkedList<u8>, + btree_set => BTreeSet<u8>, + btree_map => BTreeMap<u8, u8>, + bound => Bound<u8>, + binary_heap => BinaryHeap<u8>, + into_iter_vec => vec::IntoIter<u8>, + into_iter_vec_deque => vec_deque::IntoIter<u8>, + into_iter_linked_list => linked_list::IntoIter<u8>, + into_iter_binary_heap => binary_heap::IntoIter<u8>, + into_iter_btree_set => btree_set::IntoIter<u8>, + into_iter_btree_map => btree_map::IntoIter<u8, u8> + ); + + #[cfg(feature = "std")] + no_panic_test!( + hash_set => HashSet<u8>, + hash_map => HashMap<u8, u8>, + into_iter_hash_set => hash_set::IntoIter<u8>, + into_iter_hash_map => hash_map::IntoIter<u8, u8> + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/hash.rs b/vendor/proptest/src/arbitrary/_alloc/hash.rs new file mode 100644 index 000000000..8979bafca --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/hash.rs @@ -0,0 +1,32 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::hash`. + +#[cfg(feature = "std")] +use crate::std_facade::hash_map::{DefaultHasher, RandomState}; +use core::hash::{BuildHasherDefault, Hasher}; + +// NOTE: don't impl for std::hash::SipHasher.. since deprecated! + +// over-constrain on purpose! +arbitrary!([H: Default + Hasher] BuildHasherDefault<H>; Default::default()); + +#[cfg(feature = "std")] +lazy_just!(DefaultHasher, Default::default; RandomState, Default::default); + +#[cfg(test)] +mod test { + #[cfg(feature = "std")] + no_panic_test!( + default_hasher => DefaultHasher, + random_state => RandomState, + build_hasher_default => BuildHasherDefault<DefaultHasher> + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/mod.rs b/vendor/proptest/src/arbitrary/_alloc/mod.rs new file mode 100644 index 000000000..f286cab6d --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/mod.rs @@ -0,0 +1,22 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for liballoc. + +#[cfg(feature = "unstable")] +mod alloc; +mod borrow; +mod boxed; +mod char; +mod collections; +mod hash; +mod ops; +mod rc; +mod str; +mod sync; diff --git a/vendor/proptest/src/arbitrary/_alloc/ops.rs b/vendor/proptest/src/arbitrary/_alloc/ops.rs new file mode 100644 index 000000000..338f52c50 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/ops.rs @@ -0,0 +1,104 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::ops`. + +use crate::std_facade::Arc; +use core::ops::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +arbitrary!(RangeFull; ..); +wrap_ctor!(RangeFrom, |a| a..); +wrap_ctor!(RangeTo, |a| ..a); + +wrap_ctor!(RangeToInclusive, |a| ..=a); + +arbitrary!( + [A: PartialOrd + Arbitrary] RangeInclusive<A>, + SMapped<(A, A), Self>, product_type![A::Parameters, A::Parameters]; + args => static_map(any_with::<(A, A)>(args), + |(a, b)| if b < a { b..=a } else { a..=b }) +); + +lift1!([PartialOrd] RangeInclusive<A>; base => { + let base = Arc::new(base); + (base.clone(), base).prop_map(|(a, b)| if b < a { b..=a } else { a..=b }) +}); + +arbitrary!( + [A: PartialOrd + Arbitrary] Range<A>, + SMapped<(A, A), Self>, product_type![A::Parameters, A::Parameters]; + args => static_map(any_with::<(A, A)>(args), + |(a, b)| if b < a { b..a } else { a..b }) +); + +lift1!([PartialOrd] Range<A>; base => { + let base = Arc::new(base); + (base.clone(), base).prop_map(|(a, b)| if b < a { b..a } else { a..b }) +}); + +#[cfg(feature = "unstable")] +arbitrary!( + [Y: Arbitrary, R: Arbitrary] GeneratorState<Y, R>, + TupleUnion<(WA<SMapped<Y, Self>>, WA<SMapped<R, Self>>)>, + product_type![Y::Parameters, R::Parameters]; + args => { + let product_unpack![y, r] = args; + prop_oneof![ + static_map(any_with::<Y>(y), GeneratorState::Yielded), + static_map(any_with::<R>(r), GeneratorState::Complete) + ] + } +); + +#[cfg(feature = "unstable")] +use core::fmt; + +#[cfg(feature = "unstable")] +impl<A: fmt::Debug + 'static, B: fmt::Debug + 'static> + functor::ArbitraryF2<A, B> for GeneratorState<A, B> +{ + type Parameters = (); + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + _args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + prop_oneof![ + fst.prop_map(GeneratorState::Yielded), + snd.prop_map(GeneratorState::Complete) + ] + .boxed() + } +} + +#[cfg(test)] +mod test { + no_panic_test!( + range_full => RangeFull, + range_from => RangeFrom<usize>, + range_to => RangeTo<usize>, + range => Range<usize>, + range_inclusive => RangeInclusive<usize>, + range_to_inclusive => RangeToInclusive<usize> + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + generator_state => GeneratorState<u32, u64> + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/rc.rs b/vendor/proptest/src/arbitrary/_alloc/rc.rs new file mode 100644 index 000000000..1ddb6aa00 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/rc.rs @@ -0,0 +1,21 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::rc`. + +use crate::std_facade::Rc; + +// Weak would always give None on upgrade since there's no owned Rc. + +wrap_from!(Rc); + +#[cfg(test)] +mod test { + no_panic_test!(rc => Rc<u8>); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/str.rs b/vendor/proptest/src/arbitrary/_alloc/str.rs new file mode 100644 index 000000000..72ba248da --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/str.rs @@ -0,0 +1,49 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::str`. + +use crate::std_facade::Vec; +use core::iter::repeat; +use core::str::{from_utf8, ParseBoolError, Utf8Error}; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +arbitrary!(ParseBoolError; "".parse::<bool>().unwrap_err()); + +type ELSeq = WA<Just<&'static [u8]>>; +type ELSeqs = TupleUnion<(ELSeq, ELSeq, ELSeq, ELSeq)>; + +fn gen_el_seqs() -> ELSeqs { + prop_oneof![ + Just(&[0xC2]), // None + Just(&[0x80]), // Some(1) + Just(&[0xE0, 0xA0, 0x00]), // Some(2) + Just(&[0xF0, 0x90, 0x80, 0x00]) // Some(3) + ] +} + +arbitrary!(Utf8Error, SFnPtrMap<(StrategyFor<u16>, ELSeqs), Utf8Error>; + static_map((any::<u16>(), gen_el_seqs()), |(vut, elseq)| { + let v = repeat(b'_').take(vut as usize) + .chain(elseq.iter().cloned()) + .collect::<Vec<u8>>(); + from_utf8(&v).unwrap_err() + }) +); + +#[cfg(test)] +mod test { + no_panic_test!( + parse_bool_errror => ParseBoolError, + utf8_error => Utf8Error + ); +} diff --git a/vendor/proptest/src/arbitrary/_alloc/sync.rs b/vendor/proptest/src/arbitrary/_alloc/sync.rs new file mode 100644 index 000000000..ebc222581 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_alloc/sync.rs @@ -0,0 +1,76 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::sync`. + +use crate::std_facade::Arc; +use core::sync::atomic::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +wrap_from!(Arc); + +macro_rules! atomic { + ($($type: ident, $base: ty);+) => { + $(arbitrary!($type, SMapped<$base, Self>; + static_map(any::<$base>(), $type::new) + );)+ + }; +} + +// impl_wrap_gen!(AtomicPtr); // We don't have impl Arbitrary for *mut T yet. +atomic!(AtomicBool, bool; AtomicIsize, isize; AtomicUsize, usize); + +#[cfg(feature = "unstable")] +atomic!(AtomicI8, i8; AtomicI16, i16; AtomicI32, i32; + AtomicU8, u8; AtomicU16, u16; AtomicU32, u32); + +#[cfg(all(feature = "unstable", feature = "atomic64bit"))] +atomic!(AtomicI64, i64; AtomicU64, u64); + +arbitrary!(Ordering, + TupleUnion<(WA<Just<Self>>, WA<Just<Self>>, WA<Just<Self>>, + WA<Just<Self>>, WA<Just<Self>>)>; + prop_oneof![ + Just(Ordering::Relaxed), + Just(Ordering::Release), + Just(Ordering::Acquire), + Just(Ordering::AcqRel), + Just(Ordering::SeqCst) + ] +); + +#[cfg(test)] +mod test { + no_panic_test!( + arc => Arc<u8>, + atomic_bool => AtomicBool, + atomic_isize => AtomicIsize, + atomic_usize => AtomicUsize, + ordering => Ordering + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + atomic_i8 => AtomicI8, + atomic_i16 => AtomicI16, + atomic_i32 => AtomicI32, + atomic_u8 => AtomicU8, + atomic_u16 => AtomicU16, + atomic_u32 => AtomicU32 + ); + + #[cfg(all(feature = "unstable", feature = "atomic64bit"))] + no_panic_test!( + atomic_i64 => AtomicI64, + atomic_u64 => AtomicU64 + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/ascii.rs b/vendor/proptest/src/arbitrary/_core/ascii.rs new file mode 100644 index 000000000..ded19289b --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/ascii.rs @@ -0,0 +1,23 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::ascii`. + +use core::ascii::{escape_default, EscapeDefault}; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; + +arbitrary!(EscapeDefault, SMapped<u8, Self>; + static_map(any::<u8>(), escape_default)); + +#[cfg(test)] +mod test { + no_panic_test!(escape_default => EscapeDefault); +} diff --git a/vendor/proptest/src/arbitrary/_core/cell.rs b/vendor/proptest/src/arbitrary/_core/cell.rs new file mode 100644 index 000000000..c10148fb9 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/cell.rs @@ -0,0 +1,48 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::cell`. + +use core::cell::{BorrowError, BorrowMutError, Cell, RefCell, UnsafeCell}; + +wrap_from!([Copy] Cell); +wrap_from!(RefCell); +wrap_from!(UnsafeCell); + +lazy_just!(BorrowError, || { + // False positive: + #[cfg_attr(feature = "cargo-clippy", allow(let_and_return))] + { + let _rc = RefCell::new(()); + let _bm = _rc.borrow_mut(); + let _tb = _rc.try_borrow(); + let ret = _rc.try_borrow().expect_err("reborrowed RefCell"); + ret + } +}); +lazy_just!(BorrowMutError, || { + // False positive: + #[cfg_attr(feature = "cargo-clippy", allow(let_and_return))] + { + let _rc = RefCell::new(()); + let _bm = _rc.borrow_mut(); + let _tb = _rc.try_borrow(); + let ret = _rc.try_borrow_mut().expect_err("reborrowed RefCell"); + ret + } +}); + +#[cfg(test)] +mod test { + no_panic_test!( + cell => Cell<u8>, + ref_cell => RefCell<u8>, + unsafe_cell => UnsafeCell<u8> + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/cmp.rs b/vendor/proptest/src/arbitrary/_core/cmp.rs new file mode 100644 index 000000000..75637d45c --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/cmp.rs @@ -0,0 +1,33 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::cmp`. + +use core::cmp::{Ordering, Reverse}; + +use crate::strategy::{Just, TupleUnion, WA}; + +wrap_ctor!(Reverse, Reverse); + +type WAJO = WA<Just<Ordering>>; +arbitrary!(Ordering, TupleUnion<(WAJO, WAJO, WAJO)>; + prop_oneof![ + Just(Ordering::Equal), + Just(Ordering::Less), + Just(Ordering::Greater) + ] +); + +#[cfg(test)] +mod test { + no_panic_test!( + reverse => Reverse<u8>, + ordering => Ordering + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/convert.rs b/vendor/proptest/src/arbitrary/_core/convert.rs new file mode 100644 index 000000000..b74d78620 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/convert.rs @@ -0,0 +1,16 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::convert`. + +// No sensible Arbitrary impl exists for void-like types like +// std::convert::Infallible. +// +// Auto-deriving should take care to simply not include such +// types in generation instead! diff --git a/vendor/proptest/src/arbitrary/_core/fmt.rs b/vendor/proptest/src/arbitrary/_core/fmt.rs new file mode 100644 index 000000000..b16b8968c --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/fmt.rs @@ -0,0 +1,18 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::fmt`. + +use core::fmt::Error; +arbitrary!(Error; Error); + +#[cfg(test)] +mod test { + no_panic_test!(error => Error); +} diff --git a/vendor/proptest/src/arbitrary/_core/iter.rs b/vendor/proptest/src/arbitrary/_core/iter.rs new file mode 100644 index 000000000..d9d5364f6 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/iter.rs @@ -0,0 +1,188 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::iter`. + +use core::fmt; +use core::iter::Fuse; +use core::iter::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// TODO: Filter, FilterMap, FlatMap, Map, Inspect, Scan, SkipWhile +// Might be possible with CoArbitrary + +wrap_ctor!(Once, once); +wrap_ctor!([Clone] Repeat, repeat); +wrap_ctor!([Iterator + Clone] Cycle, Iterator::cycle); +wrap_ctor!([Iterator] Enumerate, Iterator::enumerate); +wrap_ctor!([Iterator] Fuse, Iterator::fuse); +wrap_ctor!([Iterator<Item = T>, T: fmt::Debug] Peekable, Iterator::peekable); +wrap_ctor!([DoubleEndedIterator] Rev, Iterator::rev); + +arbitrary!(['a, T: 'a + Clone, A: Arbitrary + Iterator<Item = &'a T>] + Cloned<A>, SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Iterator::cloned)); + +impl< + T: 'static + Clone, + A: fmt::Debug + 'static + Iterator<Item = &'static T>, + > functor::ArbitraryF1<A> for Cloned<A> +{ + type Parameters = (); + + fn lift1_with<S>(base: S, _args: Self::Parameters) -> BoxedStrategy<Self> + where + S: Strategy<Value = A> + 'static, + { + base.prop_map(Iterator::cloned).boxed() + } +} + +arbitrary!([A] Empty<A>; empty()); + +arbitrary!( + [A: Arbitrary + Iterator, B: Arbitrary + Iterator] + Zip<A, B>, SMapped<(A, B), Self>, + product_type![A::Parameters, B::Parameters]; + args => static_map(any_with::<(A, B)>(args), |(a, b)| a.zip(b)) +); + +lift1!( + [fmt::Debug + 'static + Iterator, B: 'static + Arbitrary + Iterator] + Zip<B, A>, + B::Parameters; + base, args => + (any_with::<B>(args), base).prop_map(|(b, a)| b.zip(a)).boxed() +); + +impl<A: fmt::Debug + Iterator, B: fmt::Debug + Iterator> + functor::ArbitraryF2<A, B> for Zip<A, B> +{ + type Parameters = (); + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + _args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + (fst, snd).prop_map(|(a, b)| a.zip(b)).boxed() + } +} + +arbitrary!( + [T, + A: Arbitrary + Iterator<Item = T>, + B: Arbitrary + Iterator<Item = T>] + Chain<A, B>, SMapped<(A, B), Self>, + product_type![A::Parameters, B::Parameters]; + args => static_map(any_with::<(A, B)>(args), |(a, b)| a.chain(b)) +); + +lift1!([fmt::Debug + 'static + Iterator<Item = T>, + B: 'static + Arbitrary + Iterator<Item = T>, + T] + Chain<B, A>, + B::Parameters; + base, args => + (any_with::<B>(args), base).prop_map(|(b, a)| b.chain(a)).boxed() +); + +impl< + T, + A: fmt::Debug + Iterator<Item = T>, + B: fmt::Debug + Iterator<Item = T>, + > functor::ArbitraryF2<A, B> for Chain<A, B> +{ + type Parameters = (); + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + _args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + (fst, snd).prop_map(|(a, b)| a.chain(b)).boxed() + } +} + +macro_rules! usize_mod { + ($type: ident, $mapper: ident) => { + arbitrary!([A: Arbitrary + Iterator] $type<A>, + SMapped<(A, usize), Self>, A::Parameters; + a => static_map( + any_with::<(A, usize)>(product_pack![a, ()]), + |(a, b)| a.$mapper(b) + ) + ); + + lift1!([Iterator] $type<A>; + base => (base, any::<usize>()).prop_map(|(a, b)| a.$mapper(b)) + ); + }; +} + +usize_mod!(Skip, skip); +usize_mod!(Take, take); + +#[cfg(feature = "unstable")] +usize_mod!(StepBy, step_by); + +#[cfg(test)] +mod test { + use super::*; + + use std::ops::Range; + const DUMMY: &'static [u8] = &[0, 1, 2, 3, 4]; + #[derive(Debug)] + struct Dummy(u8); + arbitrary!(Dummy, SFnPtrMap<Range<u8>, Self>; static_map(0..5, Dummy)); + impl Iterator for Dummy { + type Item = &'static u8; + fn next(&mut self) -> Option<Self::Item> { + if self.0 < 5 { + let r = &DUMMY[self.0 as usize]; + self.0 += 1; + Some(r) + } else { + None + } + } + } + + no_panic_test!( + empty => Empty<u8>, + once => Once<u8>, + repeat => Repeat<u8>, + cloned => Cloned<super::Dummy>, + cycle => Cycle<Once<u8>>, + enumerate => Enumerate<Repeat<u8>>, + fuse => Fuse<Once<u8>>, + peekable => Peekable<Repeat<u8>>, + rev => Rev<::std::vec::IntoIter<u8>>, + zip => Zip<Repeat<u8>, Repeat<u16>>, + chain => Chain<Once<u8>, Once<u8>>, + skip => Skip<Repeat<u8>>, + take => Take<Repeat<u8>> + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + step_by => StepBy<Repeat<u8>> + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/marker.rs b/vendor/proptest/src/arbitrary/_core/marker.rs new file mode 100644 index 000000000..6558f57ab --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/marker.rs @@ -0,0 +1,19 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::marker`. + +use core::marker::PhantomData; + +arbitrary!([T: ?Sized] PhantomData<T>; PhantomData); + +#[cfg(test)] +mod test { + no_panic_test!(phantom_data => PhantomData<u8>); +} diff --git a/vendor/proptest/src/arbitrary/_core/mem.rs b/vendor/proptest/src/arbitrary/_core/mem.rs new file mode 100644 index 000000000..700e40fbe --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/mem.rs @@ -0,0 +1,42 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::mem`. + +use core::mem::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; + +arbitrary!([A: Arbitrary] Discriminant<A>, + SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), |x| discriminant(&x)) +); + +lift1!(['static] Discriminant<A>; + base => static_map(base, |x| discriminant(&x)) +); + +// Not supported at the moment since the user won't be able to call +// https://doc.rust-lang.org/nightly/std/mem/union.ManuallyDrop.html#method.drop +// in any case so the use case is not great for this. +//wrap_ctor!(ManuallyDrop); + +#[cfg(test)] +mod test { + #[derive(Copy, Clone, Debug)] + struct DummyStruct; + arbitrary!(DummyStruct; DummyStruct); + + no_panic_test!( + //manually_drop => ManuallyDrop<u8>, // Trivial destructor. + discriminant_struct => Discriminant<super::DummyStruct>, + discriminant_enum => Discriminant<::std::num::FpCategory> + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/mod.rs b/vendor/proptest/src/arbitrary/_core/mod.rs new file mode 100644 index 000000000..5fc3742e4 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/mod.rs @@ -0,0 +1,22 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for libcore. + +mod ascii; +mod cell; +mod cmp; +mod convert; +mod fmt; +mod iter; +mod marker; +mod mem; +mod num; +mod option; +mod result; diff --git a/vendor/proptest/src/arbitrary/_core/num.rs b/vendor/proptest/src/arbitrary/_core/num.rs new file mode 100644 index 000000000..f2988ecf0 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/num.rs @@ -0,0 +1,55 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::num`. + +use core::num::*; + +use crate::strategy::*; + +arbitrary!(ParseFloatError; "".parse::<f32>().unwrap_err()); +arbitrary!(ParseIntError; "".parse::<u32>().unwrap_err()); + +#[cfg(feature = "unstable")] +arbitrary!(TryFromIntError; { + use core::convert::TryFrom; + u8::try_from(-1).unwrap_err() +}); + +wrap_ctor!(Wrapping, Wrapping); + +arbitrary!(FpCategory, + TupleUnion<(WA<Just<Self>>, WA<Just<Self>>, WA<Just<Self>>, + WA<Just<Self>>, WA<Just<Self>>)>; + { + use core::num::FpCategory::*; + prop_oneof![ + Just(Nan), + Just(Infinite), + Just(Zero), + Just(Subnormal), + Just(Normal), + ] + } +); + +#[cfg(test)] +mod test { + no_panic_test!( + parse_float_error => ParseFloatError, + parse_int_error => ParseIntError, + wrapping => Wrapping<u8>, + fp_category => FpCategory + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + try_from_int_error => TryFromIntError + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/option.rs b/vendor/proptest/src/arbitrary/_core/option.rs new file mode 100644 index 000000000..8b93545c8 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/option.rs @@ -0,0 +1,57 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::option`. + +use crate::std_facade::string; +use core::ops::RangeInclusive; +use core::option as opt; + +use crate::arbitrary::*; +use crate::option::{weighted, OptionStrategy, Probability}; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +arbitrary!(Probability, MapInto<RangeInclusive<f64>, Self>; + (0.0..=1.0).prop_map_into() +); + +// These are Option<AnUninhabitedType> impls: + +arbitrary!(Option<string::ParseError>; None); +#[cfg(feature = "unstable")] +arbitrary!(Option<!>; None); + +arbitrary!([A: Arbitrary] opt::Option<A>, OptionStrategy<A::Strategy>, + product_type![Probability, A::Parameters]; + args => { + let product_unpack![prob, a] = args; + weighted(prob, any_with::<A>(a)) + } +); + +lift1!([] Option<A>, Probability; base, prob => weighted(prob, base)); + +arbitrary!([A: Arbitrary] opt::IntoIter<A>, SMapped<Option<A>, Self>, + <Option<A> as Arbitrary>::Parameters; + args => static_map(any_with::<Option<A>>(args), Option::into_iter)); + +lift1!(['static] opt::IntoIter<A>, Probability; + base, prob => weighted(prob, base).prop_map(Option::into_iter) +); + +#[cfg(test)] +mod test { + no_panic_test!( + probability => Probability, + option => Option<u8>, + option_iter => opt::IntoIter<u8>, + option_parse_error => Option<string::ParseError> + ); +} diff --git a/vendor/proptest/src/arbitrary/_core/result.rs b/vendor/proptest/src/arbitrary/_core/result.rs new file mode 100644 index 000000000..147a60309 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_core/result.rs @@ -0,0 +1,108 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::result`. + +use crate::std_facade::string; +use core::fmt; +use core::result::IntoIter; + +use crate::arbitrary::*; +use crate::result::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// These are Result with uninhabited type in some variant: +arbitrary!([A: Arbitrary] Result<A, string::ParseError>, + SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Result::Ok) +); +arbitrary!([A: Arbitrary] Result<string::ParseError, A>, + SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Result::Err) +); +#[cfg(feature = "unstable")] +arbitrary!([A: Arbitrary] Result<A, !>, + SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Result::Ok) +); +#[cfg(feature = "unstable")] +arbitrary!([A: Arbitrary] Result<!, A>, + SMapped<A, Self>, A::Parameters; + args => static_map(any_with::<A>(args), Result::Err) +); + +lift1!([] Result<A, string::ParseError>; Result::Ok); +#[cfg(feature = "unstable")] +lift1!([] Result<A, !>; Result::Ok); + +// We assume that `MaybeOk` is canonical as it's the most likely Strategy +// a user wants. + +arbitrary!([A: Arbitrary, B: Arbitrary] Result<A, B>, + MaybeOk<A::Strategy, B::Strategy>, + product_type![Probability, A::Parameters, B::Parameters]; + args => { + let product_unpack![prob, a, b] = args; + let (p, a, b) = (prob, any_with::<A>(a), any_with::<B>(b)); + maybe_ok_weighted(p, a, b) + } +); + +impl<A: fmt::Debug, E: Arbitrary> functor::ArbitraryF1<A> for Result<A, E> +where + E::Strategy: 'static, +{ + type Parameters = product_type![Probability, E::Parameters]; + + fn lift1_with<AS>(base: AS, args: Self::Parameters) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + { + let product_unpack![prob, e] = args; + let (p, a, e) = (prob, base, any_with::<E>(e)); + maybe_ok_weighted(p, a, e).boxed() + } +} + +impl<A: fmt::Debug, B: fmt::Debug> functor::ArbitraryF2<A, B> for Result<A, B> { + type Parameters = Probability; + + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + maybe_ok_weighted(args, fst, snd).boxed() + } +} + +arbitrary!([A: Arbitrary] IntoIter<A>, + SMapped<Result<A, ()>, Self>, + <Result<A, ()> as Arbitrary>::Parameters; + args => static_map(any_with::<Result<A, ()>>(args), Result::into_iter) +); + +lift1!(['static] IntoIter<A>, Probability; base, args => { + maybe_ok_weighted(args, base, Just(())).prop_map(Result::into_iter) +}); + +#[cfg(test)] +mod test { + no_panic_test!( + result => Result<u8, u16>, + into_iter => IntoIter<u8>, + result_a_parse_error => Result<u8, ::std::string::ParseError>, + result_parse_error_a => Result<::std::string::ParseError, u8> + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/env.rs b/vendor/proptest/src/arbitrary/_std/env.rs new file mode 100644 index 000000000..49bbc2f2f --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/env.rs @@ -0,0 +1,141 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::env`. + +use std::env::*; +use std::ffi::OsString; +use std::iter::once; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// FIXME: SplitPaths when lifetimes in strategies are possible. + +lazy_just!( + Args, args; + ArgsOs, args_os; + Vars, vars; + VarsOs, vars_os; + JoinPathsError, jpe +); + +#[cfg(not(target_os = "windows"))] +fn jpe() -> JoinPathsError { + join_paths(once(":")).unwrap_err() +} + +#[cfg(target_os = "windows")] +fn jpe() -> JoinPathsError { + join_paths(once("\"")).unwrap_err() +} + +// Algorithm from: https://stackoverflow.com/questions/47749164 +#[cfg(any(target_os = "windows", test))] +fn make_utf16_invalid(buf: &mut [u16], p: usize) { + // Verify that length is non-empty. + // An empty string is always valid UTF-16. + assert!(buf.len() > 0); + + // If first elem or previous entry is not a leading surrogate. + let gen_trail = 0 == p || 0xd800 != (buf[p - 1] & 0xfc00); + // If last element or succeeding entry is not a traililng surrogate. + let gen_lead = p == buf.len() - 1 || 0xdc00 != (buf[p + 1] & 0xfc00); + let (force_bits_mask, force_bits_value) = if gen_trail { + if gen_lead { + // Trailing or leading surrogate. + (0xf800, 0xd800) + } else { + // Trailing surrogate. + (0xfc00, 0xdc00) + } + } else { + // Leading surrogate. + // Note that `gen_lead` and `gen_trail` could both be false here if `p` + // lies exactly between a leading and a trailing surrogate. In this + // case, it doesn't matter what we do because the UTF-16 will be + // invalid regardless, so just always force a leading surrogate. + (0xfc00, 0xd800) + }; + debug_assert_eq!(0, (force_bits_value & !force_bits_mask)); + buf[p] = (buf[p] & !force_bits_mask) | force_bits_value; +} + +#[cfg(not(target_arch = "wasm32"))] +mod var_error { + use super::*; + + /// Generates the set of `WTF-16 \ UTF-16` and makes + /// an `OsString` that is not a valid String from it. + #[cfg(target_os = "windows")] + fn osstring_invalid_string() -> impl Strategy<Value = OsString> { + use std::os::windows::ffi::OsStringExt; + let size = 1..::std::u16::MAX as usize; + let vec_gen = crate::collection::vec(..::std::u16::MAX, size.clone()); + (size, vec_gen).prop_map(|(p, mut sbuf)| { + // Not quite a uniform distribution due to clamping, + // but probably good enough + let p = ::std::cmp::min(p, sbuf.len() - 1); + make_utf16_invalid(&mut sbuf, p); + OsString::from_wide(sbuf.as_slice()) + .into_string() + .unwrap_err() + }) + } + + #[cfg(not(target_os = "windows"))] + fn osstring_invalid_string() -> impl Strategy<Value = OsString> { + use crate::arbitrary::_std::string::not_utf8_bytes; + use std::os::unix::ffi::OsStringExt; + static_map(not_utf8_bytes(true), OsString::from_vec) + } + + arbitrary!(VarError, + TupleUnion<( + WA<Just<Self>>, + WA<SFnPtrMap<BoxedStrategy<OsString>, Self>> + )>; + prop_oneof![ + Just(VarError::NotPresent), + static_map(osstring_invalid_string().boxed(), VarError::NotUnicode) + ] + ); +} + +#[cfg(test)] +mod test { + use super::*; + use crate::num; + use crate::test_runner::Config; + + no_panic_test!( + args => Args, + args_os => ArgsOs, + vars => Vars, + vars_os => VarsOs, + join_paths_error => JoinPathsError, + var_error => VarError + ); + + proptest! { + #![proptest_config(Config { + cases: 65536, + .. Config::default() + })] + + #[test] + fn make_utf16_invalid_doesnt_panic( + mut buf in [num::u16::ANY; 3], + p in 0usize..3 + ) { + make_utf16_invalid(&mut buf, p); + } + } +} diff --git a/vendor/proptest/src/arbitrary/_std/ffi.rs b/vendor/proptest/src/arbitrary/_std/ffi.rs new file mode 100644 index 000000000..288b3947a --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/ffi.rs @@ -0,0 +1,100 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::ffi`. + +use crate::std_facade::{Box, String, Vec}; +use std::ffi::*; +use std::ops::RangeInclusive; + +use crate::arbitrary::*; +use crate::collection::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +use super::string::not_utf8_bytes; + +arbitrary!(CString, + SFnPtrMap<VecStrategy<RangeInclusive<u8>>, Self>, SizeRange; + args => static_map(vec(1..=::std::u8::MAX, args + 1), |mut vec| { + vec.pop().unwrap(); + // Could use: Self::from_vec_unchecked(vec) safely. + Self::new(vec).unwrap() + }) +); + +arbitrary!(OsString, MapInto<StrategyFor<String>, Self>, + <String as Arbitrary>::Parameters; + a => any_with::<String>(a).prop_map_into() +); + +macro_rules! dst_wrapped { + ($($w: ident),*) => { + $(arbitrary!($w<CStr>, MapInto<StrategyFor<CString>, Self>, SizeRange; + a => any_with::<CString>(a).prop_map_into() + );)* + $(arbitrary!($w<OsStr>, MapInto<StrategyFor<OsString>, Self>, + <String as Arbitrary>::Parameters; + a => any_with::<OsString>(a).prop_map_into() + );)* + }; +} + +dst_wrapped!(Box); + +#[cfg(feature = "unstable")] +use std::rc::Rc; +#[cfg(feature = "unstable")] +use std::sync::Arc; +#[cfg(feature = "unstable")] +dst_wrapped!(Rc, Arc); + +arbitrary!(FromBytesWithNulError, SMapped<Option<u16>, Self>; { + static_map(any::<Option<u16>>(), |opt_pos| { + // We make some assumptions about the internal structure of + // FromBytesWithNulError. However, these assumptions do not + // involve any non-public API. + if let Some(pos) = opt_pos { + let pos = pos as usize; + // Allocate pos + 2 so that we never reallocate: + let mut v = Vec::<u8>::with_capacity(pos + 2); + v.extend(::std::iter::repeat(1).take(pos)); + v.push(0); + v.push(1); + CStr::from_bytes_with_nul(v.as_slice()).unwrap_err() + } else { + CStr::from_bytes_with_nul(b"").unwrap_err() + } + }) +}); + +arbitrary!(IntoStringError, SFnPtrMap<BoxedStrategy<Vec<u8>>, Self>; + static_map(not_utf8_bytes(false).boxed(), |bytes| + CString::new(bytes).unwrap().into_string().unwrap_err() + ) +); + +#[cfg(test)] +mod test { + no_panic_test!( + c_string => CString, + os_string => OsString, + box_c_str => Box<CStr>, + box_os_str => Box<OsStr>, + into_string_error => IntoStringError, + from_bytes_with_nul => FromBytesWithNulError + ); + #[cfg(feature = "unstable")] + no_panic_test!( + rc_c_str => Rc<CStr>, + rc_os_str => Rc<OsStr>, + arc_c_str => Arc<CStr>, + arc_os_str => Arc<OsStr> + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/fs.rs b/vendor/proptest/src/arbitrary/_std/fs.rs new file mode 100644 index 000000000..66d18ca1a --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/fs.rs @@ -0,0 +1,30 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::fs`. + +use std::fs::DirBuilder; + +use crate::arbitrary::{any, SMapped}; +use crate::strategy::statics::static_map; + +// TODO: other parts (figure out workable semantics). + +arbitrary!(DirBuilder, SMapped<bool, Self>; { + static_map(any::<bool>(), |recursive| { + let mut db = DirBuilder::new(); + db.recursive(recursive); + db + }) +}); + +#[cfg(test)] +mod test { + no_panic_test!(dir_builder => DirBuilder); +} diff --git a/vendor/proptest/src/arbitrary/_std/io.rs b/vendor/proptest/src/arbitrary/_std/io.rs new file mode 100644 index 000000000..34ee9da32 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/io.rs @@ -0,0 +1,164 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::io`. + +use crate::std_facade::String; +#[cfg(test)] +use crate::std_facade::Vec; +use std::io::ErrorKind::*; +use std::io::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// TODO: IntoInnerError +// Consider: std::io::Initializer + +macro_rules! buffer { + ($type: ident, $bound: path) => { + arbitrary!( + [A: Arbitrary + $bound] $type<A>, + SMapped<(A, Option<u16>), Self>, A::Parameters; + args => static_map( + arbitrary_with(product_pack![args, Default::default()]), + |(inner, cap)| { + if let Some(cap) = cap { + $type::with_capacity(cap as usize, inner) + } else { + $type::new(inner) + } + } + ) + ); + + lift1!([$bound] $type<A>; base => + (base, any::<Option<u16>>()).prop_map(|(inner, cap)| { + if let Some(cap) = cap { + $type::with_capacity(cap as usize, inner) + } else { + $type::new(inner) + } + }) + ); + }; +} + +buffer!(BufReader, Read); +buffer!(BufWriter, Write); +buffer!(LineWriter, Write); + +arbitrary!( + [A: Read + Arbitrary, B: Read + Arbitrary] Chain<A, B>, + SMapped<(A, B), Self>, product_type![A::Parameters, B::Parameters]; + args => static_map(arbitrary_with(args), |(a, b)| a.chain(b)) +); + +wrap_ctor!(Cursor); + +lazy_just!( + Empty, empty + ; Sink, sink + ; Stderr, stderr + ; Stdin, stdin + ; Stdout, stdout +); + +wrap_ctor!([BufRead] Lines, BufRead::lines); + +arbitrary!(Repeat, SMapped<u8, Self>; static_map(any::<u8>(), repeat)); + +arbitrary!( + [A: BufRead + Arbitrary] Split<A>, SMapped<(A, u8), Self>, A::Parameters; + args => static_map( + arbitrary_with(product_pack![args, Default::default()]), + |(a, b)| a.split(b) + ) +); +lift1!(['static + BufRead] Split<A>; + base => (base, any::<u8>()).prop_map(|(a, b)| a.split(b))); + +arbitrary!( + [A: Read + Arbitrary] Take<A>, SMapped<(A, u64), Self>, A::Parameters; + args => static_map( + arbitrary_with(product_pack![args, Default::default()]), + |(a, b)| a.take(b) + ) +); +lift1!(['static + Read] Take<A>; + base => (base, any::<u64>()).prop_map(|(a, b)| a.take(b))); + +arbitrary!(ErrorKind, Union<Just<Self>>; + Union::new( + [ NotFound + , PermissionDenied + , ConnectionRefused + , ConnectionReset + , ConnectionAborted + , NotConnected + , AddrInUse + , AddrNotAvailable + , BrokenPipe + , AlreadyExists + , WouldBlock + , InvalidInput + , InvalidData + , TimedOut + , WriteZero + , Interrupted + , Other + , UnexpectedEof + // TODO: watch this type for variant-additions. + ].iter().cloned().map(Just)) +); + +arbitrary!( + SeekFrom, + TupleUnion<( + WA<SMapped<u64, SeekFrom>>, + WA<SMapped<i64, SeekFrom>>, + WA<SMapped<i64, SeekFrom>>, + )>; + prop_oneof![ + static_map(any::<u64>(), SeekFrom::Start), + static_map(any::<i64>(), SeekFrom::End), + static_map(any::<i64>(), SeekFrom::Current) + ] +); + +arbitrary!(Error, SMapped<(ErrorKind, Option<String>), Self>; + static_map(arbitrary(), |(k, os)| + if let Some(s) = os { Error::new(k, s) } else { k.into() } + ) +); + +#[cfg(test)] +mod test { + + no_panic_test!( + buf_reader => BufReader<Repeat>, + buf_writer => BufWriter<Sink>, + line_writer => LineWriter<Sink>, + chain => Chain<Empty, BufReader<Repeat>>, + cursor => Cursor<Empty>, + empty => Empty, + sink => Sink, + stderr => Stderr, + stdin => Stdin, + stdout => Stdout, + lines => Lines<Empty>, + repeat => Repeat, + split => Split<Cursor<Vec<u8>>>, + take => Take<Repeat>, + error_kind => ErrorKind, + seek_from => SeekFrom, + error => Error + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/mod.rs b/vendor/proptest/src/arbitrary/_std/mod.rs new file mode 100644 index 000000000..4360f5e07 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/mod.rs @@ -0,0 +1,22 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for libstd. + +mod env; +mod ffi; +mod fs; +mod io; +mod net; +mod panic; +mod path; +mod string; +mod sync; +mod thread; +mod time; diff --git a/vendor/proptest/src/arbitrary/_std/net.rs b/vendor/proptest/src/arbitrary/_std/net.rs new file mode 100644 index 000000000..fcbec4d61 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/net.rs @@ -0,0 +1,117 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::net`. + +use std::net::*; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// TODO: Can we design a workable semantic for PBT wrt. actual networking +// connections? + +arbitrary!(AddrParseError; "".parse::<Ipv4Addr>().unwrap_err()); + +arbitrary!(Ipv4Addr, + TupleUnion<( + WA<Just<Self>>, + WA<Just<Self>>, + WA<MapInto<StrategyFor<u32>, Self>> + )>; + prop_oneof![ + 1 => Just(Self::new(0, 0, 0, 0)), + 4 => Just(Self::new(127, 0, 0, 1)), + 10 => any::<u32>().prop_map_into() + ] +); + +arbitrary!(Ipv6Addr, + TupleUnion<( + WA<SMapped<Ipv4Addr, Self>>, + WA<MapInto<StrategyFor<[u16; 8]>, Self>> + )>; + prop_oneof![ + 2 => static_map(any::<Ipv4Addr>(), |ip| ip.to_ipv6_mapped()), + 1 => any::<[u16; 8]>().prop_map_into() + ] +); + +arbitrary!(SocketAddrV4, SMapped<(Ipv4Addr, u16), Self>; + static_map(any::<(Ipv4Addr, u16)>(), |(a, b)| Self::new(a, b)) +); + +arbitrary!(SocketAddrV6, SMapped<(Ipv6Addr, u16, u32, u32), Self>; + static_map(any::<(Ipv6Addr, u16, u32, u32)>(), + |(a, b, c, d)| Self::new(a, b, c, d)) +); + +arbitrary!(IpAddr, + TupleUnion<(WA<MapInto<StrategyFor<Ipv4Addr>, Self>>, + WA<MapInto<StrategyFor<Ipv6Addr>, Self>>)>; + prop_oneof![ + any::<Ipv4Addr>().prop_map_into(), + any::<Ipv6Addr>().prop_map_into() + ] +); + +arbitrary!(Shutdown, + TupleUnion<(WA<Just<Self>>, WA<Just<Self>>, WA<Just<Self>>)>; + { + use std::net::Shutdown::*; + prop_oneof![Just(Both), Just(Read), Just(Write)] + } +); +arbitrary!(SocketAddr, + TupleUnion<(WA<MapInto<StrategyFor<SocketAddrV4>, Self>>, + WA<MapInto<StrategyFor<SocketAddrV6>, Self>>)>; + prop_oneof![ + any::<SocketAddrV4>().prop_map_into(), + any::<SocketAddrV6>().prop_map_into() + ] +); + +#[cfg(feature = "unstable")] +arbitrary!(Ipv6MulticastScope, + TupleUnion<(WA<Just<Self>>, WA<Just<Self>>, WA<Just<Self>>, + WA<Just<Self>>, WA<Just<Self>>, WA<Just<Self>>, + WA<Just<Self>>)>; + { + use std::net::Ipv6MulticastScope::*; + prop_oneof![ + Just(InterfaceLocal), + Just(LinkLocal), + Just(RealmLocal), + Just(AdminLocal), + Just(SiteLocal), + Just(OrganizationLocal), + Just(Global), + ] + } +); + +#[cfg(test)] +mod test { + no_panic_test!( + addr_parse_error => AddrParseError, + ipv4_addr => Ipv4Addr, + ipv6_addr => Ipv6Addr, + socket_addr_v4 => SocketAddrV4, + socket_addr_v6 => SocketAddrV6, + ip_addr => IpAddr, + shutdown => Shutdown, + socket_addr => SocketAddr + ); + + #[cfg(feature = "unstable")] + no_panic_test!( + ipv6_multicast_scope => Ipv6MulticastScope + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/panic.rs b/vendor/proptest/src/arbitrary/_std/panic.rs new file mode 100644 index 000000000..c2bd40cd4 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/panic.rs @@ -0,0 +1,19 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::panic`. + +use std::panic::AssertUnwindSafe; + +wrap_ctor!(AssertUnwindSafe, AssertUnwindSafe); + +#[cfg(test)] +mod test { + no_panic_test!(assert_unwind_safe => AssertUnwindSafe<u8>); +} diff --git a/vendor/proptest/src/arbitrary/_std/path.rs b/vendor/proptest/src/arbitrary/_std/path.rs new file mode 100644 index 000000000..e7d063c17 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/path.rs @@ -0,0 +1,23 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::path`. + +use std::path::*; + +// TODO: Figure out PathBuf and then Box/Rc/Box<Path>. + +arbitrary!(StripPrefixError; Path::new("").strip_prefix("a").unwrap_err()); + +#[cfg(test)] +mod test { + no_panic_test!( + strip_prefix_error => StripPrefixError + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/string.rs b/vendor/proptest/src/arbitrary/_std/string.rs new file mode 100644 index 000000000..fd8138a39 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/string.rs @@ -0,0 +1,318 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::string`. + +use crate::std_facade::{Box, String, Vec}; +use std::iter; +use std::rc::Rc; +use std::slice; +use std::sync::Arc; + +multiplex_alloc! { + alloc::string::FromUtf8Error, ::std::string::FromUtf8Error, + alloc::string::FromUtf16Error, ::std::string::FromUtf16Error +} + +use crate::arbitrary::*; +use crate::collection; +use crate::strategy::statics::static_map; +use crate::strategy::*; +use crate::string::StringParam; + +impl Arbitrary for String { + type Parameters = StringParam; + type Strategy = &'static str; + + /// ## Panics + /// + /// This implementation panics if the input is not a valid regex proptest + /// can handle. + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + args.into() + } +} + +macro_rules! dst_wrapped { + ($($w: ident),*) => { + $(arbitrary!($w<str>, MapInto<StrategyFor<String>, Self>, StringParam; + a => any_with::<String>(a).prop_map_into() + );)* + }; +} + +dst_wrapped!(Box, Rc, Arc); + +lazy_just!(FromUtf16Error, || String::from_utf16(&[0xD800]) + .unwrap_err()); + +// This is a void-like type, it needs to be handled by the user of +// the type by simply never constructing the variant in an enum or for +// structs by inductively not generating the struct. +// The same applies to ! and Infallible. +// generator!(ParseError, || panic!()); + +arbitrary!(FromUtf8Error, SFnPtrMap<BoxedStrategy<Vec<u8>>, Self>; + static_map(not_utf8_bytes(true).boxed(), + |bs| String::from_utf8(bs).unwrap_err()) +); + +/// This strategy produces sequences of bytes that are guaranteed to be illegal +/// wrt. UTF-8 with the goal of producing a suffix of bytes in the end of +/// an otherwise legal UTF-8 string that causes the string to be illegal. +/// This is used primarily to generate the `Utf8Error` type and similar. +pub(crate) fn not_utf8_bytes( + allow_null: bool, +) -> impl Strategy<Value = Vec<u8>> { + let prefix = collection::vec(any::<char>(), ..::std::u16::MAX as usize); + let suffix = gen_el_bytes(allow_null); + (prefix, suffix).prop_map(move |(prefix_bytes, el_bytes)| { + let iter = prefix_bytes.iter(); + let string: String = if allow_null { + iter.collect() + } else { + iter.filter(|&&x| x != '\u{0}').collect() + }; + let mut bytes = string.into_bytes(); + bytes.extend(el_bytes.into_iter()); + bytes + }) +} + +/// Stands for "error_length" bytes and contains a suffix of bytes that +/// will cause the whole string to become invalid UTF-8. +/// See `gen_el_bytes` for more details. +#[derive(Debug)] +enum ELBytes { + B1([u8; 1]), + B2([u8; 2]), + B3([u8; 3]), + B4([u8; 4]), +} + +impl<'a> IntoIterator for &'a ELBytes { + type Item = u8; + type IntoIter = iter::Cloned<slice::Iter<'a, u8>>; + fn into_iter(self) -> Self::IntoIter { + use self::ELBytes::*; + (match *self { + B1(ref a) => a.iter(), + B2(ref a) => a.iter(), + B3(ref a) => a.iter(), + B4(ref a) => a.iter(), + }) + .cloned() + } +} + +// By analysis of run_utf8_validation defined at: +// https://doc.rust-lang.org/nightly/src/core/str/mod.rs.html#1429 +// we know that .error_len() \in {None, Some(1), Some(2), Some(3)}. +// We represent this with the range [0..4) and generate a valid +// sequence from that. +fn gen_el_bytes(allow_null: bool) -> impl Strategy<Value = ELBytes> { + fn b1(a: u8) -> ELBytes { + ELBytes::B1([a]) + } + fn b2(a: (u8, u8)) -> ELBytes { + ELBytes::B2([a.0, a.1]) + } + fn b3(a: ((u8, u8), u8)) -> ELBytes { + ELBytes::B3([(a.0).0, (a.0).1, a.1]) + } + fn b4(a: ((u8, u8), u8, u8)) -> ELBytes { + ELBytes::B4([(a.0).0, (a.0).1, a.1, a.2]) + } + + /* + // https://tools.ietf.org/html/rfc3629 + static UTF8_CHAR_WIDTH: [u8; 256] = [ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF + 0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF + 4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF + ]; + + /// Mask of the value bits of a continuation byte. + const CONT_MASK: u8 = 0b0011_1111; + /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte. + const TAG_CONT_U8: u8 = 0b1000_0000; + */ + + // Continuation byte: + let succ_byte = 0x80u8..0xC0u8; + + // Do we allow the nul byte or not? + let start_byte = if allow_null { 0x00u8 } else { 0x01u8 }; + + // Invalid continuation byte: + let fail_byte = prop_oneof![start_byte..0x7Fu8, 0xC1u8..]; + + // Matches zero in the UTF8_CHAR_WIDTH table above. + let byte0_w0 = prop_oneof![0x80u8..0xC0u8, 0xF5u8..]; + + // Start of a 3 (width) byte sequence: + // Leads here: https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1479 + let byte0_w2 = 0xC2u8..0xE0u8; + + // Start of a 3 (width) byte sequence: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1484 + // See the left column in the match. + let byte0_w3 = 0xE0u8..0xF0u8; + + // Start of a 4 (width) byte sequence: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1495 + // See the left column in the match. + let byte0_w4 = 0xF0u8..0xF5u8; + + // The 2 first (valid) bytes of a 3 (width) byte sequence: + // The first byte is byte0_w3. The second is the ones produced on the right. + let byte01_w3 = byte0_w3.clone().prop_flat_map(|x| { + ( + Just(x), + match x { + 0xE0u8 => 0xA0u8..0xC0u8, + 0xE1u8..=0xECu8 => 0x80u8..0xC0u8, + 0xEDu8 => 0x80u8..0xA0u8, + 0xEEu8..=0xEFu8 => 0x80u8..0xA0u8, + _ => panic!(), + }, + ) + }); + + // In a 3 (width) byte sequence, an invalid second byte is chosen such that + // it will yield an error length of Some(1). The second byte is on + // the right of the match arms. + let byte01_w3_e1 = byte0_w3.clone().prop_flat_map(move |x| { + ( + Just(x), + match x { + 0xE0u8 => prop_oneof![start_byte..0xA0u8, 0xC0u8..], + 0xE1u8..=0xECu8 => prop_oneof![start_byte..0x80u8, 0xC0u8..], + 0xEDu8 => prop_oneof![start_byte..0x80u8, 0xA0u8..], + 0xEEu8..=0xEFu8 => prop_oneof![start_byte..0x80u8, 0xA0u8..], + _ => panic!(), + }, + ) + }); + + // In a 4 (width) byte sequence, an invalid second byte is chosen such that + // it will yield an error length of Some(1). The second byte is on + // the right of the match arms. + let byte01_w4_e1 = byte0_w4.clone().prop_flat_map(move |x| { + ( + Just(x), + match x { + 0xF0u8 => prop_oneof![start_byte..0x90u8, 0xA0u8..], + 0xF1u8..=0xF3u8 => prop_oneof![start_byte..0x80u8, 0xA0u8..], + 0xF4u8 => prop_oneof![start_byte..0x80u8, 0x90u8..], + _ => panic!(), + }, + ) + }); + + // The 2 first (valid) bytes of a 4 (width) byte sequence: + // The first byte is byte0_w4. The second is the ones produced on the right. + let byte01_w4 = byte0_w4.clone().prop_flat_map(|x| { + ( + Just(x), + match x { + 0xF0u8 => 0x90u8..0xA0u8, + 0xF1u8..=0xF3u8 => 0x80u8..0xA0u8, + 0xF4u8 => 0x80u8..0x90u8, + _ => panic!(), + }, + ) + }); + + prop_oneof![ + // error_len = None + // These are all happen when next!() fails to provide a byte. + prop_oneof![ + // width = 2 + // lacking 1 bytes: + static_map(byte0_w2.clone(), b1), + // width = 3 + // lacking 2 bytes: + static_map(byte0_w3, b1), + // lacking 1 bytes: + static_map(byte01_w3.clone(), b2), + // width = 4 + // lacking 3 bytes: + static_map(byte0_w4, b1), + // lacking 2 bytes: + static_map(byte01_w4.clone(), b2), + // lacking 1 byte: + static_map((byte01_w4.clone(), succ_byte.clone()), b3), + ], + // error_len = Some(1) + prop_oneof![ + // width = 1 is not represented. + // width = 0 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1508 + static_map(byte0_w0, b1), + // width = 2 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1480 + static_map((byte0_w2, fail_byte.clone()), b2), + // width = 3 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1488 + static_map(byte01_w3_e1, b2), + // width = 4 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1499 + static_map(byte01_w4_e1, b2), + ], + // error_len = Some(2) + static_map( + prop_oneof![ + // width = 3 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1491 + (byte01_w3, fail_byte.clone()), + // width = 4 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1502 + (byte01_w4.clone(), fail_byte.clone()) + ], + b3 + ), + // error_len = Some(3), width = 4 + // path taken: + // https://doc.rust-lang.org/1.23.0/src/core/str/mod.rs.html#1505 + static_map((byte01_w4, succ_byte, fail_byte), b4), + ] + .boxed() +} + +#[cfg(test)] +mod test { + no_panic_test!( + string => String, + str_box => Box<str>, + str_rc => Rc<str>, + str_arc => Arc<str>, + from_utf16_error => FromUtf16Error, + from_utf8_error => FromUtf8Error + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/sync.rs b/vendor/proptest/src/arbitrary/_std/sync.rs new file mode 100644 index 000000000..e372b2544 --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/sync.rs @@ -0,0 +1,166 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::sync`. + +use std::fmt; +use std::sync::mpsc::*; +use std::sync::*; +use std::thread; +use std::time::Duration; + +use crate::arbitrary::*; +use crate::strategy::statics::static_map; +use crate::strategy::*; + +// OnceState can not escape Once::call_once_force. +// PoisonError depends implicitly on the lifetime on MutexGuard, etc. +// This transitively applies to TryLockError. + +// Not doing Weak because .upgrade() would always return None. + +#[cfg(not(feature = "unstable"))] +wrap_ctor!(Mutex); +#[cfg(feature = "unstable")] +wrap_from!(Mutex); + +#[cfg(not(feature = "unstable"))] +wrap_ctor!(RwLock); +#[cfg(feature = "unstable")] +wrap_from!(RwLock); + +arbitrary!(Barrier, SMapped<u16, Self>; // usize would be extreme! + static_map(any::<u16>(), |n| Barrier::new(n as usize)) +); + +arbitrary!(BarrierWaitResult, + TupleUnion<(WA<LazyJustFn<Self>>, WA<LazyJustFn<Self>>)>; + prop_oneof![LazyJust::new(bwr_true), LazyJust::new(bwr_false)] +); + +lazy_just!( + Condvar, Default::default; + Once, Once::new +); + +arbitrary!(WaitTimeoutResult, TupleUnion<(WA<Just<Self>>, WA<Just<Self>>)>; + prop_oneof![Just(wtr_true()), Just(wtr_false())] +); + +fn bwr_true() -> BarrierWaitResult { + Barrier::new(1).wait() +} + +fn bwr_false() -> BarrierWaitResult { + let barrier = Arc::new(Barrier::new(2)); + let b2 = barrier.clone(); + let jh = thread::spawn(move || b2.wait()); + let bwr1 = barrier.wait(); + let bwr2 = jh.join().unwrap(); + if bwr1.is_leader() { + bwr2 + } else { + bwr1 + } +} + +fn wtr_false() -> WaitTimeoutResult { + let cvar = Arc::new(Condvar::new()); + let cvar2 = cvar.clone(); + thread::spawn(move || { + cvar2.notify_one(); + }); + let lock = Mutex::new(()); + let wt = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(1)); + let (_, wtr) = wt.unwrap(); + wtr +} + +fn wtr_true() -> WaitTimeoutResult { + let cvar = Condvar::new(); + let lock = Mutex::new(()); + let wt = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(0)); + let (_, wtr) = wt.unwrap(); + wtr +} + +arbitrary!(RecvError; RecvError); + +arbitrary!([T: Arbitrary] SendError<T>, SMapped<T, Self>, T::Parameters; + args => static_map(any_with::<T>(args), SendError) +); + +arbitrary!(RecvTimeoutError, TupleUnion<(WA<Just<Self>>, WA<Just<Self>>)>; + prop_oneof![ + Just(RecvTimeoutError::Disconnected), + Just(RecvTimeoutError::Timeout) + ] +); + +arbitrary!(TryRecvError, TupleUnion<(WA<Just<Self>>, WA<Just<Self>>)>; + prop_oneof![ + Just(TryRecvError::Disconnected), + Just(TryRecvError::Empty) + ] +); + +arbitrary!( + [P: Clone + Default, T: Arbitrary<Parameters = P>] TrySendError<T>, + TupleUnion<(WA<SMapped<T, Self>>, WA<SMapped<T, Self>>)>, P; + args => prop_oneof![ + static_map(any_with::<T>(args.clone()), TrySendError::Disconnected), + static_map(any_with::<T>(args), TrySendError::Full), + ] +); + +// If only half of a pair is generated then you will get a hang-up. +// Thus the only meaningful impls are in pairs. +arbitrary!([A] (Sender<A>, Receiver<A>), LazyJustFn<Self>; + LazyJust::new(channel) +); + +arbitrary!([A: fmt::Debug] (Sender<A>, IntoIter<A>), LazyJustFn<Self>; + LazyJust::new(|| { + let (rx, tx) = channel(); + (rx, tx.into_iter()) + }) +); + +arbitrary!([A] (SyncSender<A>, Receiver<A>), SMapped<u16, Self>; + static_map(any::<u16>(), |size| sync_channel(size as usize)) +); + +arbitrary!([A: fmt::Debug] (SyncSender<A>, IntoIter<A>), SMapped<u16, Self>; + static_map(any::<u16>(), |size| { + let (rx, tx) = sync_channel(size as usize); + (rx, tx.into_iter()) + }) +); + +#[cfg(test)] +mod test { + no_panic_test!( + mutex => Mutex<u8>, + rw_lock => RwLock<u8>, + barrier => Barrier, + barrier_wait_result => BarrierWaitResult, + condvar => Condvar, + once => Once, + wait_timeout_result => WaitTimeoutResult, + recv_error => RecvError, + send_error => SendError<u8>, + recv_timeout_error => RecvTimeoutError, + try_recv_error => TryRecvError, + try_send_error => TrySendError<u8>, + rx_tx => (Sender<u8>, Receiver<u8>), + rx_txiter => (Sender<u8>, IntoIter<u8>), + syncrx_tx => (SyncSender<u8>, Receiver<u8>), + syncrx_txiter => (SyncSender<u8>, IntoIter<u8>) + ); +} diff --git a/vendor/proptest/src/arbitrary/_std/thread.rs b/vendor/proptest/src/arbitrary/_std/thread.rs new file mode 100644 index 000000000..3a9b2b3fe --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/thread.rs @@ -0,0 +1,81 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::thread`. + +use crate::std_facade::String; +use std::thread::*; + +use crate::arbitrary::*; +use crate::option::prob; +use crate::strategy::statics::static_map; + +arbitrary!(Builder, SMapped<(Option<usize>, Option<String>), Self>; { + let prob = prob(0.7); + let args = product_pack![ + product_pack![prob, Default::default()], + product_pack![prob, Default::default()] + ]; + static_map(arbitrary_with(args), |(os, on)| { + let mut b = Builder::new(); + b = if let Some(size) = os { b.stack_size(size) } else { b }; + if let Some(name) = on { b.name(name) } else { b } + }) +}); + +/* + * The usefulness of this impl is debatable - as are its semantics. + * Perhaps a CoArbitrary-based solution is preferable. + +arbitrary!([A: 'static + Send + Arbitrary<'a>] JoinHandle<A>, + SMapped<'a, (A, Option<()>, u8), Self>, A::Parameters; + args => { + let prob = prob(0.1); + let args2 = product_pack![ + args, + product_pack![prob, default()], + default() + ]; + any_with_smap(args2, |(val, panic, sleep)| thread::spawn(move || { + // Sleep a random amount: + use std::time::Duration; + thread::sleep(Duration::from_millis(sleep as u64)); + + // Randomly panic: + if panic.is_some() { + panic!("Arbitrary for JoinHandle randomly paniced!"); + } + + // Move value into thread and then just return it: + val + })) + } +); +*/ + +#[cfg(test)] +mod test { + no_panic_test!( + builder => Builder + ); + + /* + use super::*; + proptest! { + #[test] + fn join_handle_works(ref jh in any::<JoinHandle<u8>>()) { + use std::panic::catch_unwind; + catch_unwind(|| { + jh.join(); + () + }) + } + } + */ +} diff --git a/vendor/proptest/src/arbitrary/_std/time.rs b/vendor/proptest/src/arbitrary/_std/time.rs new file mode 100644 index 000000000..7d940439a --- /dev/null +++ b/vendor/proptest/src/arbitrary/_std/time.rs @@ -0,0 +1,50 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for `std::time`. + +use core::ops::Range; +use std::time::*; + +use crate::arbitrary::*; +use crate::num; +use crate::strategy::statics::{self, static_map}; + +arbitrary!(Duration, SMapped<(u64, u32), Self>; + static_map(any::<(u64, u32)>(), |(a, b)| Duration::new(a, b)) +); + +// Instant::now() "never" returns the same Instant, so no shrinking may occur! +arbitrary!(Instant; Self::now()); + +arbitrary!( + // We can't use `any::<Duration>()` because the addition to `SystemTime` + // can overflow and panic. To be conservative, we only allow seconds to go + // to i32::MAX since a certain popular OS still uses `i32` to represent the + // seconds counter. + SystemTime, statics::Map<(num::i32::Any, Range<u32>), + fn ((i32, u32)) -> SystemTime>; + static_map((num::i32::ANY, 0..1_000_000_000u32), + |(sec, ns)| { + if sec >= 0 { + UNIX_EPOCH + Duration::new(sec as u64, ns) + } else { + UNIX_EPOCH - Duration::new((-(sec as i64)) as u64, ns) + } + }) +); + +#[cfg(test)] +mod test { + no_panic_test!( + duration => Duration, + instant => Instant, + system_time => SystemTime + ); +} diff --git a/vendor/proptest/src/arbitrary/arrays.rs b/vendor/proptest/src/arbitrary/arrays.rs new file mode 100644 index 000000000..85a13321c --- /dev/null +++ b/vendor/proptest/src/arbitrary/arrays.rs @@ -0,0 +1,34 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for arrays. + +use crate::arbitrary::{any_with, Arbitrary}; +use crate::array::UniformArrayStrategy; + +impl<A: Arbitrary, const N: usize> Arbitrary for [A; N] { + type Parameters = A::Parameters; + type Strategy = UniformArrayStrategy<A::Strategy, [A; N]>; + + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + let base = any_with::<A>(args); + UniformArrayStrategy::new(base) + } +} + +#[cfg(test)] +mod test { + no_panic_test!( + array_16 => [u8; 16] + ); + + no_panic_test!( + array_1024 => [u8; 1024] + ); +} diff --git a/vendor/proptest/src/arbitrary/functor.rs b/vendor/proptest/src/arbitrary/functor.rs new file mode 100644 index 000000000..153ce9949 --- /dev/null +++ b/vendor/proptest/src/arbitrary/functor.rs @@ -0,0 +1,220 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Provides higher order `Arbitrary` traits. +//! This is mainly for use by `proptest_derive`. +//! +//! ## Stability note +//! +//! This trait is mainly defined for `proptest_derive` to simplify the +//! mechanics of deriving recursive types. If you have custom containers +//! and want to support recursive for those, it is a good idea to implement +//! this trait. +//! +//! There are clearer and terser ways that work better with +//! inference such as using `proptest::collection::vec(..)` +//! to achieve the same result. +//! +//! For these reasons, the traits here are deliberately +//! not exported in a convenient way. + +use crate::std_facade::fmt; + +use crate::strategy::{BoxedStrategy, Strategy}; + +/// `ArbitraryF1` lets you lift a [`Strategy`] to unary +/// type constructors such as `Box`, `Vec`, and `Option`. +/// +/// The trait corresponds to +/// [Haskell QuickCheck's `Arbitrary1` type class][HaskellQC]. +/// +/// [HaskellQC]: +/// https://hackage.haskell.org/package/QuickCheck-2.10.1/docs/Test-QuickCheck-Arbitrary.html#t:Arbitrary1 +/// +/// [`Strategy`]: ../proptest/strategy/trait.Strategy.html +pub trait ArbitraryF1<A: fmt::Debug>: fmt::Debug + Sized { + //========================================================================== + // Implementation note #1 + //========================================================================== + // It might be better to do this with generic associated types by + // having an associated type: + // + // `type Strategy<A>: Strategy<Value = Self>;` + // + // But with this setup we will likely loose the ability to add bounds + // such as `Hash + Eq` on `A` which is needed for `HashSet`. We might + // be able to regain this ability with a ConstraintKinds feature. + // + // This alternate formulation will likely work better with type inference. + // + //========================================================================== + // Implementation note #2 + //========================================================================== + // + // Until `-> impl Trait` has been stabilized, `BoxedStrategy` must be + // used. This incurs an unfortunate performance penalty - but since + // we are dealing with testing, it is better to provide slowed down and + // somewhat less general functionality than no functionality at all. + // Implementations should just use `.boxed()` in the end. + //========================================================================== + + /// The type of parameters that [`lift1_with`] accepts for + /// configuration of the lifted and generated [`Strategy`]. Parameters + /// must implement [`Default`]. + /// + /// [`lift1_with`]: + /// trait.ArbitraryF1.html#tymethod.lift1_with + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// [`Default`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + type Parameters: Default; + + /// Lifts a given [`Strategy`] to a new [`Strategy`] for the (presumably) + /// bigger type. This is useful for lifting a `Strategy` for `SomeType` + /// to a container such as `Vec<SomeType>`. + /// + /// Calling this for the type `X` is the equivalent of using + /// [`X::lift1_with(base, Default::default())`]. + /// + /// This method is defined in the trait for optimization for the + /// default if you want to do that. It is a logic error to not + /// preserve the semantics when overriding. + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// + /// [`X::lift1_with(base, Default::default())`]: + /// trait.ArbitraryF1.html#tymethod.lift1_with + fn lift1<AS>(base: AS) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + { + Self::lift1_with(base, Self::Parameters::default()) + } + + /// Lifts a given [`Strategy`] to a new [`Strategy`] for the (presumably) + /// bigger type. This is useful for lifting a `Strategy` for `SomeType` + /// to a container such as `Vec` of `SomeType`. The composite strategy is + /// passed the arguments given in `args`. + /// + /// If you wish to use the [`default()`] arguments, + /// use [`lift1`] instead. + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// + /// [`lift1`]: trait.ArbitraryF1.html#method.lift1 + /// + /// [`default()`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + fn lift1_with<AS>(base: AS, args: Self::Parameters) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static; +} + +/// `ArbitraryF2` lets you lift [`Strategy`] to binary +/// type constructors such as `Result`, `HashMap`. +/// +/// The trait corresponds to +/// [Haskell QuickCheck's `Arbitrary2` type class][HaskellQC]. +/// +/// [HaskellQC]: +/// https://hackage.haskell.org/package/QuickCheck-2.10.1/docs/Test-QuickCheck-Arbitrary.html#t:Arbitrary2 +/// +/// [`Strategy`]: ../proptest/strategy/trait.Strategy.html +pub trait ArbitraryF2<A: fmt::Debug, B: fmt::Debug>: + fmt::Debug + Sized +{ + /// The type of parameters that [`lift2_with`] accepts for + /// configuration of the lifted and generated [`Strategy`]. Parameters + /// must implement [`Default`]. + /// + /// [`lift2_with`]: trait.ArbitraryF2.html#tymethod.lift2_with + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// + /// [`Default`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + type Parameters: Default; + + /// Lifts two given strategies to a new [`Strategy`] for the (presumably) + /// bigger type. This is useful for lifting a `Strategy` for `Type1` + /// and one for `Type2` to a container such as `HashMap<Type1, Type2>`. + /// + /// Calling this for the type `X` is the equivalent of using + /// [`X::lift2_with(base, Default::default())`]. + /// + /// This method is defined in the trait for optimization for the + /// default if you want to do that. It is a logic error to not + /// preserve the semantics when overriding. + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// + /// [`X::lift2_with(base, Default::default())`]: + /// trait.Arbitrary.html#tymethod.lift2_with + fn lift2<AS, BS>(fst: AS, snd: BS) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static, + { + Self::lift2_with(fst, snd, Self::Parameters::default()) + } + + /// Lifts two given strategies to a new [`Strategy`] for the (presumably) + /// bigger type. This is useful for lifting a `Strategy` for `Type1` + /// and one for `Type2` to a container such as `HashMap<Type1, Type2>`. + /// The composite strategy is passed the arguments given in `args`. + /// + /// If you wish to use the [`default()`] arguments, + /// use [`lift2`] instead. + /// + /// [`Strategy`]: ../proptest/strategy/trait.Strategy.html + /// + /// [`lift2`]: trait.ArbitraryF2.html#method.lift2 + /// + /// [`default()`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + fn lift2_with<AS, BS>( + fst: AS, + snd: BS, + args: Self::Parameters, + ) -> BoxedStrategy<Self> + where + AS: Strategy<Value = A> + 'static, + BS: Strategy<Value = B> + 'static; +} + +macro_rules! lift1 { + ([$($bounds : tt)*] $typ: ty, $params: ty; + $base: ident, $args: ident => $logic: expr) => { + impl<A: ::core::fmt::Debug + $($bounds)*> + $crate::arbitrary::functor::ArbitraryF1<A> + for $typ { + type Parameters = $params; + + fn lift1_with<S>($base: S, $args: Self::Parameters) + -> $crate::strategy::BoxedStrategy<Self> + where + S: $crate::strategy::Strategy<Value = A> + 'static + { + $crate::strategy::Strategy::boxed($logic) + } + } + }; + ([$($bounds : tt)*] $typ: ty; $base: ident => $logic: expr) => { + lift1!([$($bounds)*] $typ, (); $base, _args => $logic); + }; + ([$($bounds : tt)*] $typ: ty; $mapper: expr) => { + lift1!(['static + $($bounds)*] $typ; base => + $crate::strategy::Strategy::prop_map(base, $mapper)); + }; + ([$($bounds : tt)*] $typ: ty) => { + lift1!(['static + $($bounds)*] $typ; base => + $crate::strategy::Strategy::prop_map_into(base)); + }; +} diff --git a/vendor/proptest/src/arbitrary/macros.rs b/vendor/proptest/src/arbitrary/macros.rs new file mode 100644 index 000000000..8edf2a6ea --- /dev/null +++ b/vendor/proptest/src/arbitrary/macros.rs @@ -0,0 +1,115 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![cfg_attr(not(feature = "std"), allow(unused_macros))] + +//============================================================================== +// Macros for quick implementing: +//============================================================================== + +macro_rules! arbitrary { + ([$($bounds : tt)*] $typ: ty, $strat: ty, $params: ty; + $args: ident => $logic: expr) => { + impl<$($bounds)*> $crate::arbitrary::Arbitrary for $typ { + type Parameters = $params; + type Strategy = $strat; + fn arbitrary_with($args: Self::Parameters) -> Self::Strategy { + $logic + } + } + }; + ([$($bounds : tt)*] $typ: ty, $strat: ty; $logic: expr) => { + arbitrary!([$($bounds)*] $typ, $strat, (); _args => $logic); + }; + ([$($bounds : tt)*] $typ: ty; $logic: expr) => { + arbitrary!([$($bounds)*] $typ, + $crate::strategy::Just<Self>, (); + _args => $crate::strategy::Just($logic) + ); + }; + ($typ: ty, $strat: ty, $params: ty; $args: ident => $logic: expr) => { + arbitrary!([] $typ, $strat, $params; $args => $logic); + }; + ($typ: ty, $strat: ty; $logic: expr) => { + arbitrary!([] $typ, $strat; $logic); + }; + ($strat: ty; $logic: expr) => { + arbitrary!([] $strat; $logic); + }; + ($($typ: ident),*) => { + $(arbitrary!($typ, $typ::Any; $typ::ANY);)* + }; +} + +macro_rules! wrap_ctor { + ($wrap: ident) => { + wrap_ctor!([] $wrap); + }; + ($wrap: ident, $maker: expr) => { + wrap_ctor!([] $wrap, $maker); + }; + ([$($bound : tt)*] $wrap: ident) => { + wrap_ctor!([$($bound)*] $wrap, $wrap::new); + }; + ([$($bound : tt)*] $wrap: ident, $maker: expr) => { + arbitrary!([A: $crate::arbitrary::Arbitrary + $($bound)*] $wrap<A>, + $crate::arbitrary::SMapped<A, Self>, A::Parameters; + args => $crate::strategy::statics::static_map( + $crate::arbitrary::any_with::<A>(args), $maker)); + + lift1!([$($bound)*] $wrap<A>; $maker); + }; +} + +macro_rules! wrap_from { + ($wrap: ident) => { + wrap_from!([] $wrap); + }; + ([$($bound : tt)*] $wrap: ident) => { + arbitrary!([A: $crate::arbitrary::Arbitrary + $($bound)*] $wrap<A>, + $crate::strategy::MapInto<A::Strategy, Self>, A::Parameters; + args => $crate::strategy::Strategy::prop_map_into( + $crate::arbitrary::any_with::<A>(args))); + + lift1!([$($bound)*] $wrap<A>); + }; +} + +macro_rules! lazy_just { + ($($self: ty, $fun: expr);+) => { + $( + arbitrary!($self, $crate::strategy::LazyJust<Self, fn() -> Self>; + $crate::strategy::LazyJust::new($fun)); + )+ + }; +} + +//============================================================================== +// Macros for testing: +//============================================================================== + +/// We are mostly interested in ensuring that generating input from our +/// strategies is able to construct a value, therefore ensuring that +/// no panic occurs is mostly sufficient. Shrinking for strategies that +/// use special shrinking methods can be handled separately. +#[cfg(test)] +macro_rules! no_panic_test { + ($($module: ident => $self: ty),+) => { + $( + mod $module { + #[allow(unused_imports)] + use super::super::*; + proptest! { + #[test] + fn no_panic(_ in $crate::arbitrary::any::<$self>()) {} + } + } + )+ + }; +} diff --git a/vendor/proptest/src/arbitrary/mod.rs b/vendor/proptest/src/arbitrary/mod.rs new file mode 100644 index 000000000..51ac48bae --- /dev/null +++ b/vendor/proptest/src/arbitrary/mod.rs @@ -0,0 +1,69 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Defines the `Arbitrary` trait and related free functions +//! and type aliases. +//! +//! See the [`Arbitrary`] trait for more information. +//! +//! [`Arbitrary`]: trait.Arbitrary.html + +use crate::strategy::statics; +use crate::strategy::{Map, Strategy}; + +//============================================================================== +// Trait and impls +//============================================================================== + +mod traits; + +#[macro_use] +pub mod functor; + +#[macro_use] +mod macros; + +mod arrays; +mod non_zero; +mod primitives; +mod sample; +mod tuples; + +mod _core; + +#[cfg(any(feature = "std", feature = "alloc"))] +mod _alloc; + +#[cfg(feature = "std")] +mod _std; + +pub use self::traits::*; + +//============================================================================== +// SMapped + Mapped aliases to make documentation clearer. +//============================================================================== + +pub(crate) type SFnPtrMap<S, O> = + statics::Map<S, fn(<S as Strategy>::Value) -> O>; + +/// A static map from a strategy of `I` to `O`. +/// +/// # Stability +/// +/// This is provided to make documentation more readable. +/// Do not rely on it existing in your own code. +pub type SMapped<I, O> = statics::Map<StrategyFor<I>, fn(I) -> O>; + +/// A normal map from a strategy of `I` to `O`. +/// +/// # Stability +/// +/// This is provided to make documentation more readable. +/// Do not rely on it existing in your own code. +pub type Mapped<I, O> = Map<StrategyFor<I>, fn(I) -> O>; diff --git a/vendor/proptest/src/arbitrary/non_zero.rs b/vendor/proptest/src/arbitrary/non_zero.rs new file mode 100644 index 000000000..55a775beb --- /dev/null +++ b/vendor/proptest/src/arbitrary/non_zero.rs @@ -0,0 +1,66 @@ +//- +// Copyright 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::convert::TryFrom; +use core::num::{ + NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, + NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, +}; + +use crate::strategy::{FilterMap, Strategy}; + +use super::{any, Arbitrary, StrategyFor}; + +macro_rules! non_zero_impl { + ($nz:ty, $prim:ty) => { + impl Arbitrary for $nz { + type Parameters = (); + type Strategy = + FilterMap<StrategyFor<$prim>, fn($prim) -> Option<Self>>; + + fn arbitrary_with((): Self::Parameters) -> Self::Strategy { + any::<$prim>().prop_filter_map("must be non zero", |i| { + Self::try_from(i).ok() + }) + } + } + }; +} + +non_zero_impl!(NonZeroU8, u8); +non_zero_impl!(NonZeroU16, u16); +non_zero_impl!(NonZeroU32, u32); +non_zero_impl!(NonZeroU64, u64); +non_zero_impl!(NonZeroU128, u128); +non_zero_impl!(NonZeroUsize, usize); + +non_zero_impl!(NonZeroI8, i8); +non_zero_impl!(NonZeroI16, i16); +non_zero_impl!(NonZeroI32, i32); +non_zero_impl!(NonZeroI64, i64); +non_zero_impl!(NonZeroI128, i128); +non_zero_impl!(NonZeroIsize, isize); + +#[cfg(test)] +mod test { + no_panic_test!( + u8 => core::num::NonZeroU8, + u16 => core::num::NonZeroU16, + u32 => core::num::NonZeroU32, + u64 => core::num::NonZeroU64, + u128 => core::num::NonZeroU128, + usize => core::num::NonZeroUsize, + i8 => core::num::NonZeroI8, + i16 => core::num::NonZeroI16, + i32 => core::num::NonZeroI32, + i64 => core::num::NonZeroI64, + i128 => core::num::NonZeroI128, + isize => core::num::NonZeroIsize + ); +} diff --git a/vendor/proptest/src/arbitrary/primitives.rs b/vendor/proptest/src/arbitrary/primitives.rs new file mode 100644 index 000000000..cea57f4c9 --- /dev/null +++ b/vendor/proptest/src/arbitrary/primitives.rs @@ -0,0 +1,46 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for primitive types. + +use crate::bool; +use crate::char; +use crate::num::{ + f32, f64, i16, i32, i64, i8, isize, u16, u32, u64, u8, usize, +}; +#[cfg(not(target_arch = "wasm32"))] +use crate::num::{i128, u128}; + +arbitrary!(bool, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); + +#[cfg(not(target_arch = "wasm32"))] +arbitrary!(i128, u128); + +// Note that for floating point types we limit the space since a lot of code +// isn't prepared for (and is not intended to be) things like NaN and infinity. +arbitrary!(f32, f32::Any; { + f32::POSITIVE | f32::NEGATIVE | f32::ZERO | f32::SUBNORMAL | f32::NORMAL +}); +arbitrary!(f64, f64::Any; { + f64::POSITIVE | f64::NEGATIVE | f64::ZERO | f64::SUBNORMAL | f64::NORMAL +}); + +arbitrary!(char, char::CharStrategy<'static>; char::any()); + +#[cfg(test)] +mod test { + no_panic_test!( + bool => bool, + char => char, + f32 => f32, f64 => f64, + isize => isize, usize => usize, + i8 => i8, i16 => i16, i32 => i32, i64 => i64, i128 => i128, + u8 => u8, u16 => u16, u32 => u32, u64 => u64, u128 => u128 + ); +} diff --git a/vendor/proptest/src/arbitrary/sample.rs b/vendor/proptest/src/arbitrary/sample.rs new file mode 100644 index 000000000..81758213d --- /dev/null +++ b/vendor/proptest/src/arbitrary/sample.rs @@ -0,0 +1,31 @@ +//- +// Copyright 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::arbitrary::Arbitrary; +use crate::sample::{Index, IndexStrategy, Selector, SelectorStrategy}; + +impl Arbitrary for Index { + type Parameters = (); + + type Strategy = IndexStrategy; + + fn arbitrary_with(_: ()) -> IndexStrategy { + IndexStrategy::new() + } +} + +impl Arbitrary for Selector { + type Parameters = (); + + type Strategy = SelectorStrategy; + + fn arbitrary_with(_: ()) -> SelectorStrategy { + SelectorStrategy::new() + } +} diff --git a/vendor/proptest/src/arbitrary/traits.rs b/vendor/proptest/src/arbitrary/traits.rs new file mode 100644 index 000000000..83f021425 --- /dev/null +++ b/vendor/proptest/src/arbitrary/traits.rs @@ -0,0 +1,295 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::fmt; + +use crate::strategy::Strategy; + +//============================================================================== +// Arbitrary trait +//============================================================================== + +/// Arbitrary determines a canonical [`Strategy`] for the implementing type. +/// +/// It provides the method `arbitrary_with` which generates a `Strategy` for +/// producing arbitrary values of the implementing type *(`Self`)*. In general, +/// these strategies will produce the entire set of values possible for the +/// type, up to some size limitation or constraints set by their parameters. +/// When this is not desired, strategies to produce the desired values can be +/// built by combining [`Strategy`]s as described in the crate documentation. +/// +/// This trait analogous to +/// [Haskell QuickCheck's implementation of `Arbitrary`][HaskellQC]. +/// In this interpretation of `Arbitrary`, `Strategy` is the equivalent of +/// the `Gen` monad. Unlike in QuickCheck, `Arbitrary` is not a core component; +/// types do not need to implement `Arbitrary` unless one wants to use +/// [`any`](fn.any.html) or other free functions in this module. +/// +/// `Arbitrary` currently only works for types which represent owned data as +/// opposed to borrowed data. This is a fundamental restriction of `proptest` +/// which may be lifted in the future as the [generic associated types (GAT)] +/// feature of Rust is implemented and stabilized. +/// +/// [generic associated types (GAT)]: https://github.com/rust-lang/rust/issues/44265 +/// +/// [`Strategy`]: ../strategy/trait.Strategy.html +/// +/// [HaskellQC]: +/// https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck-Arbitrary.html +pub trait Arbitrary: Sized + fmt::Debug { + /// The type of parameters that [`arbitrary_with`] accepts for configuration + /// of the generated [`Strategy`]. Parameters must implement [`Default`]. + /// + /// [`arbitrary_with`]: trait.Arbitrary.html#tymethod.arbitrary_with + /// + /// [`Strategy`]: ../strategy/trait.Strategy.html + /// [`Default`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + type Parameters: Default; + + /// Generates a [`Strategy`] for producing arbitrary values + /// of type the implementing type (`Self`). + /// + /// Calling this for the type `X` is the equivalent of using + /// [`X::arbitrary_with(Default::default())`]. + /// + /// This method is defined in the trait for optimization for the + /// default if you want to do that. It is a logic error to not + /// preserve the semantics when overriding. + /// + /// [`Strategy`]: ../strategy/trait.Strategy.html + /// [`X::arbitrary_with(Default::default())`]: + /// trait.Arbitrary.html#tymethod.arbitrary_with + fn arbitrary() -> Self::Strategy { + Self::arbitrary_with(Default::default()) + } + + /// Generates a [`Strategy`] for producing arbitrary values of type the + /// implementing type (`Self`). The strategy is passed the arguments given + /// in args. + /// + /// If you wish to use the [`default()`] arguments, + /// use [`arbitrary`] instead. + /// + /// [`Strategy`]: ../strategy/trait.Strategy.html + /// + /// [`arbitrary`]: trait.Arbitrary.html#method.arbitrary + /// + /// [`default()`]: + /// https://doc.rust-lang.org/nightly/std/default/trait.Default.html + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy; + + /// The type of [`Strategy`] used to generate values of type `Self`. + /// + /// [`Strategy`]: ../strategy/trait.Strategy.html + type Strategy: Strategy<Value = Self>; +} + +//============================================================================== +// Type aliases for associated types +//============================================================================== + +/// `StrategyFor` allows you to mention the type of [`Strategy`] for the input +/// type `A` without directly using associated types or without resorting to +/// existential types. This way, if implementation of [`Arbitrary`] changes, +/// your tests should not break. This can be especially beneficial when the +/// type of `Strategy` that you are dealing with is very long in name +/// (the case with generics). +/// +/// [`Arbitrary`]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +pub type StrategyFor<A> = <A as Arbitrary>::Strategy; + +/// `ParamsFor` allows you to mention the type of [`Parameters`] for the input +/// type `A` without directly using associated types or without resorting to +/// existential types. This way, if implementation of [`Arbitrary`] changes, +/// your tests should not break. +/// +/// [`Parameters`]: trait.Arbitrary.html#associatedtype.Parameters +/// [`Arbitrary`]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +pub type ParamsFor<A> = <A as Arbitrary>::Parameters; + +//============================================================================== +// Free functions that people should use +//============================================================================== + +/// Generates a [`Strategy`] producing [`Arbitrary`][trait Arbitrary] values of +/// `A`. Unlike [`arbitrary`][fn arbitrary], it should be used for being +/// explicit on what `A` is. For clarity, this may be a good idea. +/// +/// Use this version instead of [`arbitrary`][fn arbitrary] if you want to be +/// clear which type you want to generate a `Strategy` for, or if you don't +/// have an anchoring type for type inference to work with. +/// +/// If you want to customize how the strategy is generated, use +/// [`any_with::<A>(args)`] where `args` are any arguments accepted by +/// the `Arbitrary` impl in question. +/// +/// # Example +/// +/// The function can be used as: +/// +/// ```rust +/// use proptest::prelude::*; +/// +/// proptest! { +/// fn reverse_reverse_is_identity(ref vec in any::<Vec<u32>>()) { +/// let vec2 = vec.iter().cloned().rev().rev().collect::<Vec<u32>>(); +/// prop_assert_eq!(vec, &vec2); +/// } +/// } +/// +/// fn main() { +/// reverse_reverse_is_identity(); +/// } +/// ``` +/// +/// [`any_with::<A>(args)`]: fn.any_with.html +/// [fn arbitrary]: fn.arbitrary.html +/// [trait Arbitrary]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +#[must_use = "strategies do nothing unless used"] +pub fn any<A: Arbitrary>() -> StrategyFor<A> { + // ^-- We use a shorter name so that turbofish becomes more ergonomic. + A::arbitrary() +} + +/// Generates a [`Strategy`] producing [`Arbitrary`] values of `A` with the +/// given configuration arguments passed in `args`. Unlike [`arbitrary_with`], +/// it should be used for being explicit on what `A` is. +/// For clarity, this may be a good idea. +/// +/// Use this version instead of [`arbitrary_with`] if you want to be clear which +/// type you want to generate a `Strategy` for, or if you don't have an anchoring +/// type for type inference to work with. +/// +/// If you don't want to specify any arguments and instead use the default +/// behavior, you should use [`any::<A>()`]. +/// +/// # Example +/// +/// The function can be used as: +/// +/// ```rust +/// use proptest::prelude::*; +/// use proptest::collection::size_range; +/// +/// proptest! { +/// fn reverse_reverse_is_identity +/// (ref vec in any_with::<Vec<u32>>(size_range(1000).lift())) +/// { +/// let vec2 = vec.iter().cloned().rev().rev().collect::<Vec<u32>>(); +/// prop_assert_eq!(vec, &vec2); +/// } +/// } +/// +/// fn main() { +/// reverse_reverse_is_identity(); +/// } +/// ``` +/// +/// [`any::<A>()`]: fn.any.html +/// [`arbitrary_with`]: fn.arbitrary_with.html +/// [`Arbitrary`]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +#[must_use = "strategies do nothing unless used"] +pub fn any_with<A: Arbitrary>(args: ParamsFor<A>) -> StrategyFor<A> { + // ^-- We use a shorter name so that turbofish becomes more ergonomic. + A::arbitrary_with(args) +} + +/// Generates a [`Strategy`] producing [`Arbitrary`] values of `A`. +/// Works better with type inference than [`any::<A>()`]. +/// +/// With this version, you shouldn't need to specify any of the (many) type +/// parameters explicitly. This can have a positive effect on type inference. +/// However, if you want specify `A`, you should use [`any::<A>()`] instead. +/// +/// For clarity, it is often a good idea to specify the type generated, and +/// so using [`any::<A>()`] can be a good idea. +/// +/// If you want to customize how the strategy is generated, use +/// [`arbitrary_with(args)`] where `args` is of type +/// `<A as Arbitrary>::Parameters`. +/// +/// # Example +/// +/// The function can be used as: +/// +/// ```rust +/// extern crate proptest; +/// use proptest::arbitrary::{arbitrary, StrategyFor}; +/// +/// fn gen_vec_usize() -> StrategyFor<Vec<usize>> { +/// arbitrary() +/// } +/// +/// # fn main() {} +/// ``` +/// +/// [`arbitrary_with(args)`]: fn.arbitrary_with.html +/// [`any::<A>()`]: fn.any.html +/// [`Arbitrary`]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +#[must_use = "strategies do nothing unless used"] +pub fn arbitrary<A, S>() -> S +where + // The backlinking here cause an injection which helps type inference. + S: Strategy<Value = A>, + A: Arbitrary<Strategy = S>, +{ + A::arbitrary() +} + +/// Generates a [`Strategy`] producing [`Arbitrary`] values of `A` with the +/// given configuration arguments passed in `args`. +/// Works better with type inference than [`any_with::<A>(args)`]. +/// +/// With this version, you shouldn't need to specify any of the (many) type +/// parameters explicitly. This can have a positive effect on type inference. +/// However, if you want specify `A`, you should use +/// [`any_with::<A>(args)`] instead. +/// +/// For clarity, it is often a good idea to specify the type generated, and +/// so using [`any_with::<A>(args)`] can be a good idea. +/// +/// If you don't want to specify any arguments and instead use the default +/// behavior, you should use [`arbitrary()`]. +/// +/// # Example +/// +/// The function can be used as: +/// +/// ```rust +/// extern crate proptest; +/// use proptest::arbitrary::{arbitrary_with, StrategyFor}; +/// use proptest::collection::size_range; +/// +/// fn gen_vec_10_u32() -> StrategyFor<Vec<u32>> { +/// arbitrary_with(size_range(10).lift()) +/// } +/// +/// # fn main() {} +/// ``` +/// +/// [`any_with::<A>(args)`]: fn.any_with.html +/// [`arbitrary()`]: fn.arbitrary.html +/// [`Arbitrary`]: trait.Arbitrary.html +/// [`Strategy`]: ../strategy/trait.Strategy.html +#[must_use = "strategies do nothing unless used"] +pub fn arbitrary_with<A, S, P>(args: P) -> S +where + P: Default, + // The backlinking here cause an injection which helps type inference. + S: Strategy<Value = A>, + A: Arbitrary<Strategy = S, Parameters = P>, +{ + A::arbitrary_with(args) +} diff --git a/vendor/proptest/src/arbitrary/tuples.rs b/vendor/proptest/src/arbitrary/tuples.rs new file mode 100644 index 000000000..5df3088a3 --- /dev/null +++ b/vendor/proptest/src/arbitrary/tuples.rs @@ -0,0 +1,45 @@ +//- +// Copyright 2017, 2018 The proptest developers +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Arbitrary implementations for tuples. + +use crate::arbitrary::{any_with, Arbitrary}; + +macro_rules! impl_tuple { + ($($typ: ident),*) => { + impl<$($typ : Arbitrary),*> Arbitrary for ($($typ,)*) { + type Parameters = product_type![$($typ::Parameters,)*]; + type Strategy = ($($typ::Strategy,)*); + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + #[allow(non_snake_case)] + let product_unpack![$($typ),*] = args; + ($(any_with::<$typ>($typ)),*,) + } + } + }; +} + +arbitrary!((); ()); +impl_tuple!(T0); +impl_tuple!(T0, T1); +impl_tuple!(T0, T1, T2); +impl_tuple!(T0, T1, T2, T3); +impl_tuple!(T0, T1, T2, T3, T4); +impl_tuple!(T0, T1, T2, T3, T4, T5); +impl_tuple!(T0, T1, T2, T3, T4, T5, T6); +impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7); +impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8); +impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9); + +#[cfg(test)] +mod test { + no_panic_test!( + tuple_n10 => ((), bool, u8, u16, u32, u64, i8, i16, i32, i64) + ); +} |