extern crate gob; extern crate partial_io; extern crate serde; extern crate serde_bytes; #[macro_use] extern crate serde_derive; #[macro_use] extern crate quickcheck; use std::collections::HashMap; use std::io::Cursor; use gob::{error::ErrorKind, Deserializer, StreamDeserializer}; use partial_io::{GenWouldBlock, PartialRead, PartialWithErrors}; use serde::Deserialize; use serde_bytes::{ByteBuf, Bytes}; #[test] fn bool_true() { let deserializer = Deserializer::from_slice(&[3, 2, 0, 1]); let decoded = bool::deserialize(deserializer).unwrap(); assert_eq!(decoded, true); } #[test] fn bool_false() { let deserializer = Deserializer::from_slice(&[3, 2, 0, 0]); let decoded = bool::deserialize(deserializer).unwrap(); assert_eq!(decoded, false); } #[test] fn u8_zero() { let deserializer = Deserializer::from_slice(&[3, 6, 0, 0]); let decoded = u8::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn u8_overflow() { let deserializer = Deserializer::from_slice(&[5, 6, 0, 254, 4, 210]); let result = u8::deserialize(deserializer); assert!(result.is_err()); } #[test] fn u16_zero() { let deserializer = Deserializer::from_slice(&[3, 6, 0, 0]); let decoded = u16::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn u32_zero() { let deserializer = Deserializer::from_slice(&[3, 6, 0, 0]); let decoded = u32::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn u64_zero() { let deserializer = Deserializer::from_slice(&[3, 6, 0, 0]); let decoded = u64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn u64_small() { let deserializer = Deserializer::from_slice(&[3, 6, 0, 42]); let decoded = u64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 42); } #[test] fn u64_big() { let deserializer = Deserializer::from_slice(&[5, 6, 0, 254, 4, 210]); let decoded = u64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 1234); } #[test] fn u64_max() { let deserializer = Deserializer::from_slice(&[11, 6, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255]); let decoded = u64::deserialize(deserializer).unwrap(); assert_eq!(decoded, ::std::u64::MAX); } #[test] fn i8_zero() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 0]); let decoded = i8::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn i8_overflow() { let deserializer = Deserializer::from_slice(&[5, 4, 0, 254, 4, 210]); let result = i8::deserialize(deserializer); assert!(result.is_err()); } #[test] fn i16_zero() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 0]); let decoded = i16::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn i32_zero() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 0]); let decoded = i32::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn i64_zero() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 0]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0); } #[test] fn i64_small_pos() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 84]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 42); } #[test] fn i64_small_neg() { let deserializer = Deserializer::from_slice(&[3, 4, 0, 83]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, -42); } #[test] fn i64_big_pos() { let deserializer = Deserializer::from_slice(&[5, 4, 0, 254, 9, 164]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 1234); } #[test] fn i64_big_neg() { let deserializer = Deserializer::from_slice(&[5, 4, 0, 254, 9, 163]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, -1234); } #[test] fn i64_min() { let deserializer = Deserializer::from_slice(&[11, 4, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, ::std::i64::MIN); } #[test] fn i64_max() { let deserializer = Deserializer::from_slice(&[11, 4, 0, 248, 255, 255, 255, 255, 255, 255, 255, 254]); let decoded = i64::deserialize(deserializer).unwrap(); assert_eq!(decoded, ::std::i64::MAX); } #[test] fn f32_zero() { let deserializer = Deserializer::from_slice(&[3, 8, 0, 0]); let decoded = f32::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0f32); } #[test] fn f64_zero() { let deserializer = Deserializer::from_slice(&[3, 8, 0, 0]); let decoded = f64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 0f64); } #[test] fn f64_pos() { let deserializer = Deserializer::from_slice(&[5, 8, 0, 254, 69, 64]); let decoded = f64::deserialize(deserializer).unwrap(); assert_eq!(decoded, 42f64); } #[test] fn f64_neg() { let deserializer = Deserializer::from_slice(&[5, 8, 0, 254, 69, 192]); let decoded = f64::deserialize(deserializer).unwrap(); assert_eq!(decoded, -42f64); } #[test] fn char_ascii() { let deserializer = Deserializer::from_slice(&[4, 4, 0, 255, 204]); let decoded = char::deserialize(deserializer).unwrap(); assert_eq!(decoded, 'f'); } #[test] fn char_unicode() { let deserializer = Deserializer::from_slice(&[6, 4, 0, 253, 1, 21, 60]); let decoded = char::deserialize(deserializer).unwrap(); assert_eq!(decoded, '語'); } #[test] fn bytes_empty() { let deserializer = Deserializer::from_slice(&[3, 10, 0, 0]); let decoded = Bytes::deserialize(deserializer).unwrap(); assert_eq!(&*decoded, &[]); } #[test] fn bytes_non_empty() { let deserializer = Deserializer::from_slice(&[7, 10, 0, 4, 1, 2, 3, 4]); let decoded = Bytes::deserialize(deserializer).unwrap(); assert_eq!(&*decoded, &[1, 2, 3, 4]); } #[test] fn bytebuf_empty() { let deserializer = Deserializer::from_slice(&[3, 10, 0, 0]); let decoded = ByteBuf::deserialize(deserializer).unwrap(); assert_eq!(&*decoded, &[]); } #[test] fn bytebuf_non_empty() { let deserializer = Deserializer::from_slice(&[7, 10, 0, 4, 1, 2, 3, 4]); let decoded = ByteBuf::deserialize(deserializer).unwrap(); assert_eq!(&*decoded, &[1, 2, 3, 4]); } #[test] fn str_empty() { let deserializer = Deserializer::from_slice(&[3, 12, 0, 0]); let decoded = <&str>::deserialize(deserializer).unwrap(); assert_eq!(decoded, ""); } #[test] fn str_non_empty() { let deserializer = Deserializer::from_slice(&[6, 12, 0, 3, 102, 111, 111]); let decoded = <&str>::deserialize(deserializer).unwrap(); assert_eq!(decoded, "foo"); } #[test] fn string_empty() { let deserializer = Deserializer::from_slice(&[3, 12, 0, 0]); let decoded = String::deserialize(deserializer).unwrap(); assert_eq!(decoded, ""); } #[test] fn string_non_empty() { let deserializer = Deserializer::from_slice(&[6, 12, 0, 3, 102, 111, 111]); let decoded = String::deserialize(deserializer).unwrap(); assert_eq!(decoded, "foo"); } #[test] fn vec_of_bool_from_empty_slice() { let deserializer = Deserializer::from_slice(include_bytes!("reference/output/slice_of_bool_empty.gob")); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded, &[]); } #[test] fn vec_of_bool_from_empty_array() { let deserializer = Deserializer::from_slice(include_bytes!("reference/output/array_of_bool_empty.gob")); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded, &[]); } #[test] fn vec_of_bool_from_non_empty_slice() { let deserializer = Deserializer::from_slice(include_bytes!( "reference/output/slice_of_bool_non_empty.gob" )); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded, &[true, false]); } #[test] fn vec_of_bool_from_non_empty_array() { let deserializer = Deserializer::from_slice(include_bytes!( "reference/output/array_of_bool_non_empty.gob" )); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded, &[true, false]); } #[test] fn vec_of_bool_from_empty_slice_twice() { let buffer = include_bytes!("reference/output/slice_of_bool_empty_twice.gob"); let cursor = Cursor::new(buffer); let mut stream = StreamDeserializer::new(cursor); let decoded1 = stream.deserialize::>().unwrap().unwrap(); assert_eq!(decoded1, &[]); let decoded2 = stream.deserialize::>().unwrap().unwrap(); assert_eq!(decoded2, &[]); } #[test] fn vec_of_bool_from_non_empty_slice_twice() { let buffer = include_bytes!("reference/output/slice_of_bool_non_empty_twice.gob"); let cursor = Cursor::new(buffer); let mut stream = StreamDeserializer::new(cursor); let decoded1 = stream.deserialize::>().unwrap().unwrap(); assert_eq!(decoded1, &[true, false]); let decoded2 = stream.deserialize::>().unwrap().unwrap(); assert_eq!(decoded2, &[false, true]); } #[test] fn map_empty() { let deserializer = Deserializer::from_slice(include_bytes!("reference/output/map_empty.gob")); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded.len(), 0); } #[test] fn map_non_empty() { let deserializer = Deserializer::from_slice(include_bytes!("reference/output/map_non_empty.gob")); let decoded = >::deserialize(deserializer).unwrap(); assert_eq!(decoded.len(), 2); assert_eq!(decoded["foo"], true); assert_eq!(decoded["bar"], false); } #[test] fn complex_64() { let deserializer = Deserializer::from_slice(&[6, 14, 0, 254, 240, 63, 64]); let decoded = <(f32, f32)>::deserialize(deserializer).unwrap(); assert_eq!(decoded.0, 1f32); assert_eq!(decoded.1, 2f32); } #[test] fn complex_128() { let deserializer = Deserializer::from_slice(&[6, 14, 0, 254, 240, 63, 64]); let decoded = <(f64, f64)>::deserialize(deserializer).unwrap(); assert_eq!(decoded.0, 1f64); assert_eq!(decoded.1, 2f64); } #[test] fn point_struct() { #[derive(Deserialize)] struct Point { #[serde(rename = "X")] x: i64, #[serde(rename = "Y")] y: i64, } let deserializer = Deserializer::from_slice(include_bytes!("reference/output/point_struct.gob")); let decoded = Point::deserialize(deserializer).unwrap(); assert_eq!(decoded.x, 22); assert_eq!(decoded.y, 33); } #[test] fn unit_struct() { #[derive(Deserialize)] struct EmptyStruct {}; let deserializer = Deserializer::from_slice(include_bytes!("reference/output/empty_struct.gob")); EmptyStruct::deserialize(deserializer).unwrap(); } #[test] fn enum_with_newtype_variants_and_external_tags() { #[derive(Deserialize, Debug, PartialEq, Eq)] enum Enum { #[serde(rename = "Var1")] V1(bool), #[serde(rename = "Var2")] V2(i64), #[serde(rename = "Var3")] V3(String), } let deserializer = Deserializer::from_slice(include_bytes!( "reference/output/enum_with_newtype_variants.gob" )); let decoded = Enum::deserialize(deserializer).unwrap(); assert_eq!(decoded, Enum::V2(42)); } #[test] fn enum_with_struct_variants_and_external_tags() { #[derive(Deserialize, Debug, PartialEq, Eq)] enum Enum { V1 { #[serde(rename = "Foo")] foo: bool, }, V2 { #[serde(rename = "Bar")] bar: i64, #[serde(rename = "Baz")] baz: u64, }, V3 { #[serde(rename = "Quux")] quux: String, }, } let deserializer = Deserializer::from_slice(include_bytes!( "reference/output/enum_with_struct_variants.gob" )); let decoded = Enum::deserialize(deserializer).unwrap(); assert_eq!(decoded, Enum::V2 { bar: 42, baz: 1234 }); } #[test] fn unit_from_any() { let buffer = include_bytes!("reference/output/non_empty_values.gob"); let cursor = Cursor::new(buffer.as_ref()); let mut stream = StreamDeserializer::new(cursor); for _ in 0..7 { let () = stream.deserialize::<()>().unwrap().unwrap(); } assert!(stream.deserialize::<()>().unwrap().is_none()); } quickcheck! { fn non_blocking_io(seq: PartialWithErrors) -> bool { macro_rules! block { ($e:expr) => { loop { #[allow(unreachable_patterns)] match $e { Err(e) => { if e.kind() == ErrorKind::Io(::std::io::ErrorKind::WouldBlock) { continue; } else { break Err(e); } } Ok(x) => break Ok(x), } } }; } let buffer = include_bytes!("reference/output/non_empty_values.gob"); let reader = Cursor::new(buffer.as_ref().to_vec()); let partial_reader = PartialRead::new(reader, seq); let mut stream = StreamDeserializer::new(partial_reader); assert_eq!(true, block!(stream.deserialize::()).unwrap().unwrap()); assert_eq!(42u64, block!(stream.deserialize::()).unwrap().unwrap()); assert_eq!(42i64, block!(stream.deserialize::()).unwrap().unwrap()); assert_eq!(42f64, block!(stream.deserialize::()).unwrap().unwrap()); assert_eq!( "foo", block!(stream.deserialize::()).unwrap().unwrap() ); assert_eq!( ByteBuf::from(vec![0x1, 0x2]), block!(stream.deserialize::()).unwrap().unwrap() ); assert_eq!( vec![true, false], block!(stream.deserialize::>()).unwrap().unwrap() ); block!(stream.deserialize::<()>()).unwrap().is_none() } }