From 41563ee01b4eb3481207a88bbb2e3a54d6e96b2b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 2 Apr 2015 17:07:26 -0700 Subject: wip --- tests/serde.rs | 476 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 476 insertions(+) create mode 100644 tests/serde.rs (limited to 'tests') diff --git a/tests/serde.rs b/tests/serde.rs new file mode 100644 index 0000000..7e3c325 --- /dev/null +++ b/tests/serde.rs @@ -0,0 +1,476 @@ +#![cfg(feature = "serde")] +#![feature(custom_derive, plugin)] +#![plugin(serde_macros)] + + +extern crate serde; +extern crate toml; + +use std::collections::{BTreeMap, HashSet}; +use serde::{Deserialize, Serialize, Deserializer}; + +use toml::{Encoder, Decoder, DecodeError}; +use toml::Value; +use toml::Value::{Table, Integer, Array, Float}; + +macro_rules! t { + ($e:expr) => (match $e { + Ok(t) => t, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + }) +} + +macro_rules! encode( ($t:expr) => ({ + let mut e = Encoder::new(); + t!($t.serialize(&mut e)); + e.toml +}) ); + +macro_rules! decode( ($t:expr) => ({ + let mut d = Decoder::new($t); + t!(Deserialize::deserialize(&mut d)) +}) ); + +macro_rules! map( ($($k:ident, $v:expr),*) => ({ + let mut _m = BTreeMap::new(); + $(_m.insert(stringify!($k).to_string(), $v);)* + _m +}) ); + +#[test] +fn smoke() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: isize } + + let v = Foo { a: 2 }; + assert_eq!(encode!(v), map! { a, Integer(2) }); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn smoke_hyphen() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a_b: isize } + + let v = Foo { a_b: 2 }; + assert_eq!(encode!(v), map! { a_b, Integer(2) }); + assert_eq!(v, decode!(Table(encode!(v)))); + + let mut m = BTreeMap::new(); + m.insert("a-b".to_string(), Integer(2)); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn nested() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: isize, b: Bar } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { a: String } + + let v = Foo { a: 2, b: Bar { a: "test".to_string() } }; + assert_eq!(encode!(v), + map! { + a, Integer(2), + b, Table(map! { + a, Value::String("test".to_string()) + }) + }); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn application_decode_error() { + #[derive(PartialEq, Debug)] + struct Range10(usize); + impl Deserialize for Range10 { + fn deserialize(d: &mut D) -> Result { + let x: usize = try!(Deserialize::deserialize(d)); + if x > 10 { + Err(serde::de::Error::syntax_error()) + } else { + Ok(Range10(x)) + } + } + } + let mut d_good = Decoder::new(Integer(5)); + let mut d_bad1 = Decoder::new(Value::String("not an isize".to_string())); + let mut d_bad2 = Decoder::new(Integer(11)); + + assert_eq!(Ok(Range10(5)), Deserialize::deserialize(&mut d_good)); + + let err1: Result = Deserialize::deserialize(&mut d_bad1); + assert!(err1.is_err()); + let err2: Result = Deserialize::deserialize(&mut d_bad2); + assert!(err2.is_err()); +} + +#[test] +fn array() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Vec } + + let v = Foo { a: vec![1, 2, 3, 4] }; + assert_eq!(encode!(v), + map! { + a, Array(vec![ + Integer(1), + Integer(2), + Integer(3), + Integer(4) + ]) + }); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn tuple() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: (isize, isize, isize, isize) } + + let v = Foo { a: (1, 2, 3, 4) }; + assert_eq!(encode!(v), + map! { + a, Array(vec![ + Integer(1), + Integer(2), + Integer(3), + Integer(4) + ]) + }); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn inner_structs_with_options() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { + a: Option>, + b: Bar, + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { + a: String, + b: f64, + } + + let v = Foo { + a: Some(Box::new(Foo { + a: None, + b: Bar { a: "foo".to_string(), b: 4.5 }, + })), + b: Bar { a: "bar".to_string(), b: 1.0 }, + }; + assert_eq!(encode!(v), + map! { + a, Table(map! { + b, Table(map! { + a, Value::String("foo".to_string()), + b, Float(4.5) + }) + }), + b, Table(map! { + a, Value::String("bar".to_string()), + b, Float(1.0) + }) + }); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn hashmap() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { + map: BTreeMap, + set: HashSet, + } + + let v = Foo { + map: { + let mut m = BTreeMap::new(); + m.insert("foo".to_string(), 10); + m.insert("bar".to_string(), 4); + m + }, + set: { + let mut s = HashSet::new(); + s.insert('a'); + s + }, + }; + assert_eq!(encode!(v), + map! { + map, Table(map! { + foo, Integer(10), + bar, Integer(4) + }), + set, Array(vec![Value::String("a".to_string())]) + } + ); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn tuple_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo(isize, String, f64); + + let v = Foo(1, "foo".to_string(), 4.5); + assert_eq!( + encode!(v), + map! { + _field0, Integer(1), + _field1, Value::String("foo".to_string()), + _field2, Float(4.5) + } + ); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn table_array() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Vec, } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { a: isize } + + let v = Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] }; + assert_eq!( + encode!(v), + map! { + a, Array(vec![ + Table(map!{ a, Integer(1) }), + Table(map!{ a, Integer(2) }), + ]) + } + ); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn type_errors() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { bar: isize } + + let mut d = Decoder::new(Table(map! { + bar, Float(1.0) + })); + let a: Result = Deserialize::deserialize(&mut d); + match a { + Ok(..) => panic!("should not have decoded"), + Err(e) => { + assert_eq!(format!("{}", e), + "expected a value of type `integer`, but \ + found a value of type `float` for the key `bar`"); + } + } +} + +#[test] +fn missing_errors() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { bar: isize } + + let mut d = Decoder::new(Table(map! { + })); + let a: Result = Deserialize::deserialize(&mut d); + match a { + Ok(..) => panic!("should not have decoded"), + Err(e) => { + assert_eq!(format!("{}", e), + "expected a value of type `integer` for the key `bar`"); + } + } +} + +#[test] +fn parse_enum() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: E } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum E { + Bar(isize), + Baz(f64), + Last(Foo2), + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo2 { + test: String, + } + + let v = Foo { a: E::Bar(10) }; + assert_eq!( + encode!(v), + map! { a, Integer(10) } + ); + assert_eq!(v, decode!(Table(encode!(v)))); + + let v = Foo { a: E::Baz(10.2) }; + assert_eq!( + encode!(v), + map! { a, Float(10.2) } + ); + assert_eq!(v, decode!(Table(encode!(v)))); + + let v = Foo { a: E::Last(Foo2 { test: "test".to_string() }) }; + assert_eq!( + encode!(v), + map! { a, Table(map! { test, Value::String("test".to_string()) }) } + ); + assert_eq!(v, decode!(Table(encode!(v)))); +} + +#[test] +fn unused_fields() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: isize } + + let v = Foo { a: 2 }; + let mut d = Decoder::new(Table(map! { + a, Integer(2), + b, Integer(5) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, Some(Table(map! { + b, Integer(5) + }))); +} + +#[test] +fn unused_fields2() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Bar } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { a: isize } + + let v = Foo { a: Bar { a: 2 } }; + let mut d = Decoder::new(Table(map! { + a, Table(map! { + a, Integer(2), + b, Integer(5) + }) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, Some(Table(map! { + a, Table(map! { + b, Integer(5) + }) + }))); +} + +#[test] +fn unused_fields3() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Bar } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { a: isize } + + let v = Foo { a: Bar { a: 2 } }; + let mut d = Decoder::new(Table(map! { + a, Table(map! { + a, Integer(2) + }) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, None); +} + +#[test] +fn unused_fields4() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: BTreeMap } + + let v = Foo { a: map! { a, "foo".to_string() } }; + let mut d = Decoder::new(Table(map! { + a, Table(map! { + a, Value::String("foo".to_string()) + }) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, None); +} + +#[test] +fn unused_fields5() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Vec } + + let v = Foo { a: vec!["a".to_string()] }; + let mut d = Decoder::new(Table(map! { + a, Array(vec![Value::String("a".to_string())]) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, None); +} + +#[test] +fn unused_fields6() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Option> } + + let v = Foo { a: Some(vec![]) }; + let mut d = Decoder::new(Table(map! { + a, Array(vec![]) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, None); +} + +#[test] +fn unused_fields7() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Vec } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { a: isize } + + let v = Foo { a: vec![Bar { a: 1 }] }; + let mut d = Decoder::new(Table(map! { + a, Array(vec![Table(map! { + a, Integer(1), + b, Integer(2) + })]) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + assert_eq!(d.toml, Some(Table(map! { + a, Array(vec![Table(map! { + b, Integer(2) + })]) + }))); +} + +#[test] +fn empty_arrays() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Vec } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar; + + let v = Foo { a: vec![] }; + let mut d = Decoder::new(Table(map! {})); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); +} + +#[test] +fn empty_arrays2() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo { a: Option> } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar; + + let v = Foo { a: None }; + let mut d = Decoder::new(Table(map! {})); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); + + let v = Foo { a: Some(vec![]) }; + let mut d = Decoder::new(Table(map! { + a, Array(vec![]) + })); + assert_eq!(v, t!(Deserialize::deserialize(&mut d))); +} -- cgit v1.2.3