extern crate bytekey2; extern crate rand; extern crate serde; #[macro_use] extern crate serde_derive; use bytekey2::{serialize, serialized_size}; use rand::distributions::{Distribution, Standard}; use rand::{random, Rng}; use serde::Serialize; use std::fmt::Debug; use std::{f32, f64, i16, i64, i8, isize, u16, u64, u8, usize}; #[derive(Debug, PartialEq, PartialOrd, Serialize)] struct TestStruct { u8_: u8, u16_: u16, u32_: u32, u64_: u64, i8_: i8, i16_: i16, i32_: i32, i64_: i64, f32_: f32, f64_: f64, bool_: bool, char_: char, } #[derive(Debug, PartialEq, PartialOrd, Serialize)] enum TestEnum { A(u32, String), B, C(isize), } // `rand` implemetations. impl Distribution for Standard { fn sample(&self, rng: &mut R) -> TestStruct { TestStruct { u8_: rng.gen(), u16_: rng.gen(), u32_: rng.gen(), u64_: rng.gen(), i8_: rng.gen(), i16_: rng.gen(), i32_: rng.gen(), i64_: rng.gen(), f32_: rng.gen(), f64_: rng.gen(), bool_: rng.gen(), char_: rng.gen(), } } } impl Distribution for Standard { fn sample(&self, rng: &mut R) -> TestEnum { match rng.gen_range(0..3) { 0 => { let len = (rng.gen::() * 10.0) as usize; let string = (0..len).map(|_| random::()).collect(); TestEnum::A(rng.gen(), string) } 1 => TestEnum::B, 2 => TestEnum::C(rng.gen()), _ => unreachable!(), } } } // 1. Generate some random values of type `T`. // 2. Collect them into two `Vec`s - one with values, one with the serialized bytes. // 3. Sort both `Vec`s. // 4. Assert that the order of both `Vec`s is identical. fn assert_order_preservation_of_n_elems(n: usize) where T: PartialOrd + Serialize, Standard: Distribution, { let mut values = Vec::with_capacity(n); let mut bytes = Vec::with_capacity(n); for i in 0..n { let val: T = rand::random(); let serialized = serialize(&val).unwrap(); values.push((val, i)); bytes.push((serialized, i)); } values.sort_by(|(a, _), (b, _)| a.partial_cmp(&b).unwrap()); bytes.sort_by(|(a, _), (b, _)| a.partial_cmp(&b).unwrap()); for ((_, value_i), (_, bytes_i)) in values.into_iter().zip(bytes) { assert_eq!(value_i, bytes_i); } } // 1. Generate a random value of type `T`. // 2. Assert that the serialized bytes of the random value equals to the return of `serialized_size` // 3. Repeat the above steps for n times or stop when an assertion fails fn assert_serialized_size(n: usize) where T: PartialOrd + Serialize + Debug, Standard: Distribution, { for _ in 0..n { let val: T = rand::random(); let serialized = serialize(&val).unwrap(); let expected_size = serialized_size(&val).unwrap(); assert_eq!( serialized.len(), expected_size, "{:?} is expected to have size {}.", val, expected_size ); } } #[test] fn test_u8() { assert_order_preservation_of_n_elems::(256); assert_serialized_size::(256); } #[test] fn test_u16() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_u32() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_u64() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_usize() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_i8() { assert_order_preservation_of_n_elems::(256); assert_serialized_size::(256); } #[test] fn test_i16() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_i32() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_i64() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_isize() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_f32() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_f64() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_bool() { assert_order_preservation_of_n_elems::(16); assert_serialized_size::(16); } #[test] fn test_struct() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_enum() { assert_order_preservation_of_n_elems::(1024); assert_serialized_size::(1024); } #[test] fn test_usize_as_u64() { assert_eq!( serialize(&usize::MAX).unwrap(), serialize(&u64::MAX).unwrap() ); assert!(serialize(&usize::MIN).unwrap() < serialize(&usize::MAX).unwrap()); } #[test] fn test_isize_as_i64() { assert_eq!( serialize(&isize::MAX).unwrap(), serialize(&i64::MAX).unwrap() ); assert!(serialize(&isize::MIN).unwrap() < serialize(&isize::MAX).unwrap()); } #[test] fn test_f32_special_values() { assert!(serialize(&f32::MAX).unwrap() < serialize(&f32::NAN).unwrap()); assert!(serialize(&-1.0f32).unwrap() < serialize(&-0.9f32).unwrap()); assert!(serialize(&-10_000.0f32).unwrap() < serialize(&10_000.0f32).unwrap()); assert!(serialize(&9_000.0f32).unwrap() < serialize(&10_000.0f32).unwrap()); assert!(serialize(&9_000.0f32).unwrap() < serialize(&10_000.0f32).unwrap()); assert!(serialize(&0.0f32).unwrap() < serialize(&1.0f32).unwrap()); } #[test] fn test_f64_special_values() { assert!(serialize(&f64::MAX).unwrap() < serialize(&f64::NAN).unwrap()); assert!(serialize(&-1.0f64).unwrap() < serialize(&-0.9f64).unwrap()); assert!(serialize(&-10_000.0f64).unwrap() < serialize(&10_000.0f64).unwrap()); assert!(serialize(&9_000.0f64).unwrap() < serialize(&10_000.0f64).unwrap()); assert!(serialize(&9_000.0f64).unwrap() < serialize(&10_000.0f64).unwrap()); assert!(serialize(&0.0f64).unwrap() < serialize(&1.0f64).unwrap()); }