#![cfg(feature = "derive")] // Various structs/fields that we are deriving `Arbitrary` for aren't actually // used except to exercise the derive. #![allow(dead_code)] // Various assert_eq! are used to compare result of bool amongst other data types // In this case, using assert! is less explicit and readable #![allow(clippy::bool_assert_comparison)] use arbitrary::*; 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") } #[derive(Copy, Clone, Debug, Eq, PartialEq, Arbitrary)] pub struct Rgb { pub r: u8, pub g: u8, pub b: u8, } #[test] fn struct_with_named_fields() { let rgb: Rgb = arbitrary_from(&[4, 5, 6]); assert_eq!(rgb.r, 4); assert_eq!(rgb.g, 5); assert_eq!(rgb.b, 6); assert_eq!((3, Some(3)), ::size_hint(0)); } #[derive(Copy, Clone, Debug, Arbitrary)] struct MyTupleStruct(u8, bool); #[test] fn tuple_struct() { let s: MyTupleStruct = arbitrary_from(&[43, 42]); assert_eq!(s.0, 43); assert_eq!(s.1, false); let s: MyTupleStruct = arbitrary_from(&[42, 43]); assert_eq!(s.0, 42); assert_eq!(s.1, true); assert_eq!((2, Some(2)), ::size_hint(0)); } #[derive(Clone, Debug, Arbitrary)] struct EndingInVec(u8, bool, u32, Vec); #[derive(Clone, Debug, Arbitrary)] struct EndingInString(u8, bool, u32, String); #[test] fn test_take_rest() { let bytes = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8]; let s1 = EndingInVec::arbitrary_take_rest(Unstructured::new(&bytes)).unwrap(); let s2 = EndingInString::arbitrary_take_rest(Unstructured::new(&bytes)).unwrap(); assert_eq!(s1.0, 1); assert_eq!(s2.0, 1); assert_eq!(s1.1, true); assert_eq!(s2.1, true); assert_eq!(s1.2, 0x4030201); assert_eq!(s2.2, 0x4030201); assert_eq!(s1.3, vec![0x0706]); assert_eq!(s2.3, "\x05\x06\x07\x08"); } #[derive(Copy, Clone, Debug, Arbitrary)] enum MyEnum { Unit, Tuple(u8, u16), Struct { a: u32, b: (bool, u64) }, } #[test] fn derive_enum() { let mut raw = vec![ // The choice of which enum variant takes 4 bytes. 1, 2, 3, 4, // And then we need up to 13 bytes for creating `MyEnum::Struct`, the // largest variant. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ]; let mut saw_unit = false; let mut saw_tuple = false; let mut saw_struct = false; for i in 0..=255 { // Choose different variants each iteration. for el in &mut raw[..4] { *el = i; } let e: MyEnum = arbitrary_from(&raw); match e { MyEnum::Unit => { saw_unit = true; } MyEnum::Tuple(a, b) => { saw_tuple = true; assert_eq!(a, arbitrary_from(&raw[4..5])); assert_eq!(b, arbitrary_from(&raw[5..])); } MyEnum::Struct { a, b } => { saw_struct = true; assert_eq!(a, arbitrary_from(&raw[4..8])); assert_eq!(b, arbitrary_from(&raw[8..])); } } } assert!(saw_unit); assert!(saw_tuple); assert!(saw_struct); assert_eq!((4, Some(17)), ::size_hint(0)); } // This should result in a compiler-error: // #[derive(Arbitrary, Debug)] // enum Never { // #[arbitrary(skip)] // Nope, // } #[derive(Arbitrary, Debug)] enum SkipVariant { Always, #[arbitrary(skip)] Never, } #[test] fn test_skip_variant() { (0..=u8::MAX).for_each(|byte| { let buffer = [byte]; let unstructured = Unstructured::new(&buffer); let skip_variant = SkipVariant::arbitrary_take_rest(unstructured).unwrap(); assert!(!matches!(skip_variant, SkipVariant::Never)); }) } #[derive(Arbitrary, Debug)] enum RecursiveTree { Leaf, Node { left: Box, right: Box, }, } #[derive(Arbitrary, Debug)] struct WideRecursiveStruct { a: Option>, b: Option>, c: Option>, d: Option>, e: Option>, f: Option>, g: Option>, h: Option>, i: Option>, k: Option>, } #[derive(Arbitrary, Debug)] enum WideRecursiveEnum { None, A(Box), B(Box), C(Box), D(Box), E(Box), F(Box), G(Box), H(Box), I(Box), K(Box), } #[derive(Arbitrary, Debug)] enum WideRecursiveMixedEnum { None, A(Box), B(Box), C(Box), D(Box), E(Box), F(Box), G(Box), H(Box), I(Box), K(Box), } #[derive(Arbitrary, Debug)] struct WideRecursiveMixedStruct { a: Option>, b: Option>, c: Option>, d: Option>, e: Option>, f: Option>, g: Option>, h: Option>, i: Option>, k: Option>, } #[test] fn recursive() { let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; let _rec: RecursiveTree = arbitrary_from(&raw); let _rec: WideRecursiveStruct = arbitrary_from(&raw); let _rec: WideRecursiveEnum = arbitrary_from(&raw); let _rec: WideRecursiveMixedStruct = arbitrary_from(&raw); let _rec: WideRecursiveMixedEnum = arbitrary_from(&raw); assert_eq!((0, None), ::size_hint(0)); assert_eq!((0, None), ::size_hint(0)); assert_eq!( (0, None), ::size_hint(0) ); assert_eq!( (0, None), ::size_hint(0) ); let (lower, upper) = ::size_hint(0); assert_eq!(lower, 0, "Cannot compute size hint of recursive structure"); assert!( upper.is_none(), "potentially infinitely recursive, so no upper bound" ); } #[derive(Arbitrary, Debug)] struct Generic { inner: T, } #[test] fn generics() { let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; let gen: Generic = arbitrary_from(&raw); assert!(gen.inner); let (lower, upper) = as Arbitrary>::size_hint(0); assert_eq!(lower, 4); assert_eq!(upper, Some(4)); } #[derive(Arbitrary, Debug)] struct OneLifetime<'a> { alpha: &'a str, } #[test] fn one_lifetime() { // Last byte is used for length let raw: Vec = vec![97, 98, 99, 100, 3]; let lifetime: OneLifetime = arbitrary_from(&raw); assert_eq!("abc", lifetime.alpha); let (lower, upper) = ::size_hint(0); assert_eq!(lower, 0); assert_eq!(upper, None); } #[derive(Arbitrary, Debug)] struct TwoLifetimes<'a, 'b> { alpha: &'a str, beta: &'b str, } #[test] fn two_lifetimes() { // Last byte is used for length let raw: Vec = vec![97, 98, 99, 100, 101, 102, 103, 3]; let lifetime: TwoLifetimes = arbitrary_from(&raw); assert_eq!("abc", lifetime.alpha); assert_eq!("def", lifetime.beta); let (lower, upper) = ::size_hint(0); assert_eq!(lower, 0); assert_eq!(upper, None); } #[test] fn recursive_and_empty_input() { // None of the following derives should result in a stack overflow. See // https://github.com/rust-fuzz/arbitrary/issues/107 for details. #[derive(Debug, Arbitrary)] enum Nat { Succ(Box), Zero, } let _ = Nat::arbitrary(&mut Unstructured::new(&[])); #[derive(Debug, Arbitrary)] enum Nat2 { Zero, Succ(Box), } let _ = Nat2::arbitrary(&mut Unstructured::new(&[])); #[derive(Debug, Arbitrary)] struct Nat3 { f: Option>, } let _ = Nat3::arbitrary(&mut Unstructured::new(&[])); #[derive(Debug, Arbitrary)] struct Nat4(Option>); let _ = Nat4::arbitrary(&mut Unstructured::new(&[])); #[derive(Debug, Arbitrary)] enum Nat5 { Zero, Succ { f: Box }, } let _ = Nat5::arbitrary(&mut Unstructured::new(&[])); } #[test] fn test_field_attributes() { // A type that DOES NOT implement Arbitrary #[derive(Debug)] struct Weight(u8); #[derive(Debug, Arbitrary)] struct Parcel { #[arbitrary(with = arbitrary_weight)] weight: Weight, #[arbitrary(default)] width: u8, #[arbitrary(value = 2 + 2)] length: u8, height: u8, #[arbitrary(with = |u: &mut Unstructured| u.int_in_range(0..=100))] price: u8, } fn arbitrary_weight(u: &mut Unstructured) -> arbitrary::Result { u.int_in_range(45..=56).map(Weight) } let parcel: Parcel = arbitrary_from(&[6, 199, 17]); // 45 + 6 = 51 assert_eq!(parcel.weight.0, 51); // u8::default() assert_eq!(parcel.width, 0); // 2 + 2 = 4 assert_eq!(parcel.length, 4); // 199 is the 2nd byte used by arbitrary assert_eq!(parcel.height, 199); // 17 is the 3rd byte used by arbitrary assert_eq!(parcel.price, 17); } #[test] fn derive_structs_named_same_as_core() { #[derive(Debug, Arbitrary)] struct Option { f: core::option::Option, } let _ = Option::arbitrary(&mut Unstructured::new(&[])); #[derive(Debug, Default, Arbitrary)] struct Default { f: u32, } let _ = Default::arbitrary(&mut Unstructured::new(&[])); }