142 lines
3.4 KiB
Rust
142 lines
3.4 KiB
Rust
#![cfg(feature = "derive")]
|
|
|
|
use arbitrary::{Arbitrary, Unstructured};
|
|
|
|
fn arbitrary_from<'a, T: Arbitrary<'a>>(input: &'a [u8]) -> T {
|
|
let mut buf = Unstructured::new(input);
|
|
T::arbitrary(&mut buf).expect("can create arbitrary instance OK")
|
|
}
|
|
|
|
/// This wrapper trait *implies* `Arbitrary`, but the compiler isn't smart enough to work that out
|
|
/// so when using this wrapper we *must* opt-out of the auto-generated `T: Arbitrary` bounds.
|
|
pub trait WrapperTrait: for<'a> Arbitrary<'a> {}
|
|
|
|
impl WrapperTrait for u32 {}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: WrapperTrait")]
|
|
struct GenericSingleBound<T: WrapperTrait> {
|
|
t: T,
|
|
}
|
|
|
|
#[test]
|
|
fn single_bound() {
|
|
let v: GenericSingleBound<u32> = arbitrary_from(&[0, 0, 0, 0]);
|
|
assert_eq!(v.t, 0);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: WrapperTrait, U: WrapperTrait")]
|
|
struct GenericMultipleBoundsSingleAttribute<T: WrapperTrait, U: WrapperTrait> {
|
|
t: T,
|
|
u: U,
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_bounds_single_attribute() {
|
|
let v: GenericMultipleBoundsSingleAttribute<u32, u32> =
|
|
arbitrary_from(&[1, 0, 0, 0, 2, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
assert_eq!(v.u, 2);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: WrapperTrait")]
|
|
#[arbitrary(bound = "U: Default")]
|
|
struct GenericMultipleArbitraryAttributes<T: WrapperTrait, U: Default> {
|
|
t: T,
|
|
#[arbitrary(default)]
|
|
u: U,
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_arbitrary_attributes() {
|
|
let v: GenericMultipleArbitraryAttributes<u32, u32> = arbitrary_from(&[1, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
assert_eq!(v.u, 0);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: WrapperTrait", bound = "U: Default")]
|
|
struct GenericMultipleBoundAttributes<T: WrapperTrait, U: Default> {
|
|
t: T,
|
|
#[arbitrary(default)]
|
|
u: U,
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_bound_attributes() {
|
|
let v: GenericMultipleBoundAttributes<u32, u32> = arbitrary_from(&[1, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
assert_eq!(v.u, 0);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: WrapperTrait", bound = "U: Default")]
|
|
#[arbitrary(bound = "V: WrapperTrait, W: Default")]
|
|
struct GenericMultipleArbitraryAndBoundAttributes<
|
|
T: WrapperTrait,
|
|
U: Default,
|
|
V: WrapperTrait,
|
|
W: Default,
|
|
> {
|
|
t: T,
|
|
#[arbitrary(default)]
|
|
u: U,
|
|
v: V,
|
|
#[arbitrary(default)]
|
|
w: W,
|
|
}
|
|
|
|
#[test]
|
|
fn multiple_arbitrary_and_bound_attributes() {
|
|
let v: GenericMultipleArbitraryAndBoundAttributes<u32, u32, u32, u32> =
|
|
arbitrary_from(&[1, 0, 0, 0, 2, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
assert_eq!(v.u, 0);
|
|
assert_eq!(v.v, 2);
|
|
assert_eq!(v.w, 0);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "T: Default")]
|
|
struct GenericDefault<T: Default> {
|
|
#[arbitrary(default)]
|
|
x: T,
|
|
}
|
|
|
|
#[test]
|
|
fn default_bound() {
|
|
// We can write a generic func without any `Arbitrary` bound.
|
|
fn generic_default<T: Default>() -> GenericDefault<T> {
|
|
arbitrary_from(&[])
|
|
}
|
|
|
|
assert_eq!(generic_default::<u64>().x, 0);
|
|
assert_eq!(generic_default::<String>().x, String::new());
|
|
assert_eq!(generic_default::<Vec<u8>>().x, Vec::new());
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary()]
|
|
struct EmptyArbitraryAttribute {
|
|
t: u32,
|
|
}
|
|
|
|
#[test]
|
|
fn empty_arbitrary_attribute() {
|
|
let v: EmptyArbitraryAttribute = arbitrary_from(&[1, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
}
|
|
|
|
#[derive(Arbitrary)]
|
|
#[arbitrary(bound = "")]
|
|
struct EmptyBoundAttribute {
|
|
t: u32,
|
|
}
|
|
|
|
#[test]
|
|
fn empty_bound_attribute() {
|
|
let v: EmptyBoundAttribute = arbitrary_from(&[1, 0, 0, 0]);
|
|
assert_eq!(v.t, 1);
|
|
}
|