aboutsummaryrefslogtreecommitdiff
path: root/serde-tests
diff options
context:
space:
mode:
Diffstat (limited to 'serde-tests')
-rw-r--r--serde-tests/Cargo.toml21
-rw-r--r--serde-tests/build.rs17
-rw-r--r--serde-tests/lib.rs1
-rw-r--r--serde-tests/test.rs1
-rw-r--r--serde-tests/test.rs.in482
5 files changed, 522 insertions, 0 deletions
diff --git a/serde-tests/Cargo.toml b/serde-tests/Cargo.toml
new file mode 100644
index 0000000..e2f5a87
--- /dev/null
+++ b/serde-tests/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "serde-tests"
+version = "0.1.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+build = "build.rs"
+
+[dependencies]
+serde = "0.5"
+toml = { path = "..", features = ["serde"] }
+
+[build-dependencies]
+syntex = "0.7"
+serde_codegen = "0.5"
+
+[lib]
+name = "serde_tests"
+path = "lib.rs"
+
+[[test]]
+name = "serde"
+path = "test.rs"
diff --git a/serde-tests/build.rs b/serde-tests/build.rs
new file mode 100644
index 0000000..7acbef5
--- /dev/null
+++ b/serde-tests/build.rs
@@ -0,0 +1,17 @@
+extern crate syntex;
+extern crate serde_codegen;
+
+use std::env;
+use std::path::Path;
+
+fn main() {
+ let out_dir = env::var_os("OUT_DIR").unwrap();
+
+ let src = Path::new("test.rs.in");
+ let dst = Path::new(&out_dir).join("test.rs");
+
+ let mut registry = syntex::Registry::new();
+
+ serde_codegen::register(&mut registry);
+ registry.expand("", &src, &dst).unwrap();
+}
diff --git a/serde-tests/lib.rs b/serde-tests/lib.rs
new file mode 100644
index 0000000..65e2cc3
--- /dev/null
+++ b/serde-tests/lib.rs
@@ -0,0 +1 @@
+// intentionally blank
diff --git a/serde-tests/test.rs b/serde-tests/test.rs
new file mode 100644
index 0000000..e8de9fa
--- /dev/null
+++ b/serde-tests/test.rs
@@ -0,0 +1 @@
+include!(concat!(env!("OUT_DIR"), "/test.rs"));
diff --git a/serde-tests/test.rs.in b/serde-tests/test.rs.in
new file mode 100644
index 0000000..41ec27a
--- /dev/null
+++ b/serde-tests/test.rs.in
@@ -0,0 +1,482 @@
+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: Deserializer>(d: &mut D) -> Result<Range10, D::Error> {
+ let x: usize = try!(Deserialize::deserialize(d));
+ if x > 10 {
+ Err(serde::de::Error::syntax("more than 10"))
+ } 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<Range10, _> = Deserialize::deserialize(&mut d_bad1);
+ assert!(err1.is_err());
+ let err2: Result<Range10, _> = Deserialize::deserialize(&mut d_bad2);
+ assert!(err2.is_err());
+}
+
+#[test]
+fn array() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Foo { a: Vec<isize> }
+
+ 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<Box<Foo>>,
+ 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<String, isize>,
+ set: HashSet<char>,
+ }
+
+ 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);
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Bar {
+ whee: Foo,
+ }
+
+ let v = Bar {
+ whee: Foo(1, "foo".to_string(), 4.5)
+ };
+ assert_eq!(
+ encode!(v),
+ map! {
+ whee, Value::Array(vec![
+ Integer(1),
+ Value::String("foo".to_string()),
+ Float(4.5),
+ ])
+ }
+ );
+ assert_eq!(v, decode!(Table(encode!(v))));
+}
+
+#[test]
+fn table_array() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Foo { a: Vec<Bar>, }
+ #[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<Foo, DecodeError> = Deserialize::deserialize(&mut d);
+ // serde uses FromPrimitive, that's why this works
+ 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<Foo, DecodeError> = Deserialize::deserialize(&mut d);
+ match a {
+ Ok(..) => panic!("should not have decoded"),
+ Err(e) => {
+ assert_eq!(format!("{}", e),
+ "expected a value 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) };
+ // technically serde is correct here. a single element tuple still is a
+ // tuple and therefor a sequence
+ 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<String, String> }
+
+ 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<String> }
+
+ 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<Vec<String>> }
+
+ 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<Bar> }
+ #[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<Bar> }
+ #[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<Vec<Bar>> }
+ #[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)));
+}