From 2ee5a416ad2bb90ce9b800e83d272549b2fc428c Mon Sep 17 00:00:00 2001
From: Erick Tryzelaar <erick.tryzelaar@gmail.com>
Date: Thu, 5 Mar 2015 19:49:17 -0800
Subject: [PATCH] Factor out the remaining json tests into tests/

---
 serde2/src/json/builder.rs        |  54 --------
 serde2/src/json/de.rs             | 221 ------------------------------
 serde2/tests/test_json.rs         | 203 ++++++++++++++-------------
 serde2/tests/test_json_builder.rs |  54 ++++++++
 4 files changed, 159 insertions(+), 373 deletions(-)
 create mode 100644 serde2/tests/test_json_builder.rs

diff --git a/serde2/src/json/builder.rs b/serde2/src/json/builder.rs
index 8b7f0580..3db2c4ed 100644
--- a/serde2/src/json/builder.rs
+++ b/serde2/src/json/builder.rs
@@ -82,57 +82,3 @@ impl ObjectBuilder {
         self
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use std::collections::BTreeMap;
-
-    use json::value::Value;
-    use super::{ArrayBuilder, ObjectBuilder};
-
-    #[test]
-    fn test_array_builder() {
-        let value = ArrayBuilder::new().unwrap();
-        assert_eq!(value, Value::Array(Vec::new()));
-
-        let value = ArrayBuilder::new()
-            .push(1)
-            .push(2)
-            .push(3)
-            .unwrap();
-        assert_eq!(value, Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))));
-
-        let value = ArrayBuilder::new()
-            .push_array(|bld| bld.push(1).push(2).push(3))
-            .unwrap();
-        assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))))));
-
-        let value = ArrayBuilder::new()
-            .push_object(|bld|
-                bld
-                    .insert("a".to_string(), 1)
-                    .insert("b".to_string(), 2))
-            .unwrap();
-
-        let mut map = BTreeMap::new();
-        map.insert("a".to_string(), Value::I64(1));
-        map.insert("b".to_string(), Value::I64(2));
-        assert_eq!(value, Value::Array(vec!(Value::Object(map))));
-    }
-
-    #[test]
-    fn test_object_builder() {
-        let value = ObjectBuilder::new().unwrap();
-        assert_eq!(value, Value::Object(BTreeMap::new()));
-
-        let value = ObjectBuilder::new()
-            .insert("a".to_string(), 1)
-            .insert("b".to_string(), 2)
-            .unwrap();
-
-        let mut map = BTreeMap::new();
-        map.insert("a".to_string(), Value::I64(1));
-        map.insert("b".to_string(), Value::I64(2));
-        assert_eq!(value, Value::Object(map));
-    }
-}
diff --git a/serde2/src/json/de.rs b/serde2/src/json/de.rs
index 8f8b25f5..c5f1a2bb 100644
--- a/serde2/src/json/de.rs
+++ b/serde2/src/json/de.rs
@@ -628,224 +628,3 @@ pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
 {
     from_iter(s.bytes())
 }
-
-#[cfg(test)]
-mod tests {
-    use std::fmt::Debug;
-    use std::collections::BTreeMap;
-
-    use de::Deserialize;
-    use super::from_str;
-    use super::super::error::{Error, ErrorCode};
-
-    macro_rules! treemap {
-        ($($k:expr => $v:expr),*) => ({
-            let mut _m = BTreeMap::new();
-            $(_m.insert($k, $v);)*
-            _m
-        })
-    }
-
-    fn test_parse_ok<'a, T>(errors: Vec<(&'a str, T)>)
-        where T: PartialEq + Debug + Deserialize,
-    {
-        for (s, value) in errors {
-            let v: Result<T, Error> = from_str(s);
-            assert_eq!(v, Ok(value));
-
-            /*
-            let v: Json = from_iter(s.chars()).unwrap();
-            assert_eq!(v, value.to_json());
-            */
-        }
-    }
-
-    fn test_parse_err<'a, T>(errors: Vec<(&'a str, Error)>)
-        where T: PartialEq + Debug + Deserialize
-    {
-        for (s, err) in errors {
-            let v: Result<T, Error> = from_str(s);
-            assert_eq!(v, Err(err));
-        }
-    }
-
-    #[test]
-    fn test_parse_null() {
-        test_parse_ok(vec![
-            ("null", ()),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_bool() {
-        test_parse_err::<bool>(vec![
-            ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
-            ("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
-            ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
-            ("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
-            ("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
-            ("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
-        ]);
-
-        test_parse_ok(vec![
-            ("true", true),
-            ("false", false),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_numbers() {
-        test_parse_err::<f64>(vec![
-            ("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
-            (".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
-            ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
-            ("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
-            ("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
-            ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
-            ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
-            ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
-        ]);
-
-        test_parse_ok(vec![
-            ("3", 3i64),
-            ("-2", -2),
-            ("-1234", -1234),
-        ]);
-
-        test_parse_ok(vec![
-            ("3.0", 3.0f64),
-            ("3.1", 3.1),
-            ("-1.2", -1.2),
-            ("0.4", 0.4),
-            ("0.4e5", 0.4e5),
-            ("0.4e15", 0.4e15),
-            ("0.4e-01", 0.4e-01),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_string() {
-        test_parse_err::<String>(vec![
-            ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
-            ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
-            ("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
-        ]);
-
-        test_parse_ok(vec![
-            ("\"\"", "".to_string()),
-            ("\"foo\"", "foo".to_string()),
-            ("\"\\\"\"", "\"".to_string()),
-            ("\"\\b\"", "\x08".to_string()),
-            ("\"\\n\"", "\n".to_string()),
-            ("\"\\r\"", "\r".to_string()),
-            ("\"\\t\"", "\t".to_string()),
-            ("\"\\u12ab\"", "\u{12ab}".to_string()),
-            ("\"\\uAB12\"", "\u{AB12}".to_string()),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_list() {
-        test_parse_err::<Vec<f64>>(vec![
-            ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
-            ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
-            ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList,  1, 3)),
-            ("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
-            ("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
-            ("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
-            ("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
-        ]);
-
-        test_parse_ok(vec![
-            ("[]", vec![]),
-            ("[ ]", vec![]),
-            ("[null]", vec![()]),
-            ("[ null ]", vec![()]),
-        ]);
-
-        test_parse_ok(vec![
-            ("[true]", vec![true]),
-        ]);
-
-        test_parse_ok(vec![
-            ("[3,1]", vec![3, 1]),
-            ("[ 3 , 1 ]", vec![3, 1]),
-        ]);
-
-        test_parse_ok(vec![
-            ("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
-        ]);
-
-        test_parse_ok(vec![
-            ("[]", ()),
-        ]);
-
-        test_parse_ok(vec![
-            ("[1]", (1,)),
-        ]);
-
-        test_parse_ok(vec![
-            ("[1, 2]", (1, 2)),
-        ]);
-
-        test_parse_ok(vec![
-            ("[1, 2, 3]", (1, 2, 3)),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_object() {
-        test_parse_err::<BTreeMap<String, i32>>(vec![
-            ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
-            ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
-            ("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
-            ("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
-            ("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
-            ("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
-            ("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
-            ("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
-            ("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
-            ("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
-            ("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
-            ("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
-        ]);
-
-        test_parse_ok(vec![
-            ("{}", treemap!()),
-            ("{ }", treemap!()),
-            (
-                "{\"a\":3}",
-                treemap!("a".to_string() => 3)
-            ),
-            (
-                "{ \"a\" : 3 }",
-                treemap!("a".to_string() => 3)
-            ),
-            (
-                "{\"a\":3,\"b\":4}",
-                treemap!("a".to_string() => 3, "b".to_string() => 4)
-            ),
-            (
-                "{ \"a\" : 3 , \"b\" : 4 }",
-                treemap!("a".to_string() => 3, "b".to_string() => 4),
-            ),
-        ]);
-
-        test_parse_ok(vec![
-            (
-                "{\"a\": {\"b\": 3, \"c\": 4}}",
-                treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
-            ),
-        ]);
-    }
-
-    #[test]
-    fn test_parse_trailing_whitespace() {
-        test_parse_ok(vec![
-            ("[1, 2] ", vec![1, 2]),
-            ("[1, 2]\n", vec![1, 2]),
-            ("[1, 2]\t", vec![1, 2]),
-            ("[1, 2]\t \n", vec![1, 2]),
-        ]);
-    }
-}
diff --git a/serde2/tests/test_json.rs b/serde2/tests/test_json.rs
index e0b8efdc..2fe4723a 100644
--- a/serde2/tests/test_json.rs
+++ b/serde2/tests/test_json.rs
@@ -5,7 +5,6 @@ extern crate test;
 extern crate serde2;
 
 use std::fmt::Debug;
-use std::string;
 use std::collections::BTreeMap;
 
 use serde2::de;
@@ -13,35 +12,17 @@ use serde2::ser;
 
 use serde2::json::{
     self,
-    Error,
     Value,
     from_str,
     from_value,
     to_value,
 };
 
-use serde2::json::error::Error::{
-    SyntaxError,
-};
-
-use serde2::json::error::ErrorCode::{
-    EOFWhileParsingList,
-    EOFWhileParsingObject,
-    EOFWhileParsingString,
-    EOFWhileParsingValue,
-    ExpectedColon,
-    ExpectedListCommaOrEnd,
-    ExpectedObjectCommaOrEnd,
-    ExpectedSomeIdent,
-    ExpectedSomeValue,
-    InvalidNumber,
-    KeyMustBeAString,
-    TrailingCharacters,
-};
+use serde2::json::error::{Error, ErrorCode};
 
 macro_rules! treemap {
     ($($k:expr => $v:expr),*) => ({
-        let mut _m = ::std::collections::BTreeMap::new();
+        let mut _m = BTreeMap::new();
         $(_m.insert($k, $v);)*
         _m
     })
@@ -63,7 +44,7 @@ enum Animal {
 struct Inner {
     a: (),
     b: usize,
-    c: Vec<string::String>,
+    c: Vec<String>,
 }
 
 #[derive(PartialEq, Debug)]
@@ -456,16 +437,6 @@ fn test_write_option() {
     */
 }
 
-// FIXME (#5527): these could be merged once UFCS is finished.
-fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
-    where T: Debug + de::Deserialize,
-{
-    for &(s, ref err) in errors {
-        let v: Result<T, Error> = from_str(s);
-        assert_eq!(v.unwrap_err(), *err);
-    }
-}
-
 fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
     where T: PartialEq + Debug + ser::Serialize + de::Deserialize,
 {
@@ -487,12 +458,22 @@ fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
     }
 }
 
+// FIXME (#5527): these could be merged once UFCS is finished.
+fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
+    where T: Debug + de::Deserialize,
+{
+    for &(s, ref err) in errors {
+        let v: Result<T, Error> = from_str(s);
+        assert_eq!(v.unwrap_err(), *err);
+    }
+}
+
 #[test]
 fn test_parse_null() {
     test_parse_err::<()>(&[
-        ("n", SyntaxError(ExpectedSomeIdent, 1, 2)),
-        ("nul", SyntaxError(ExpectedSomeIdent, 1, 4)),
-        ("nulla", SyntaxError(TrailingCharacters, 1, 5)),
+        ("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
+        ("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
+        ("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
     ]);
 
     test_parse_ok(&[
@@ -503,31 +484,33 @@ fn test_parse_null() {
 #[test]
 fn test_parse_bool() {
     test_parse_err::<bool>(&[
-        ("t", SyntaxError(ExpectedSomeIdent, 1, 2)),
-        ("truz", SyntaxError(ExpectedSomeIdent, 1, 4)),
-        ("f", SyntaxError(ExpectedSomeIdent, 1, 2)),
-        ("faz", SyntaxError(ExpectedSomeIdent, 1, 3)),
-        ("truea", SyntaxError(TrailingCharacters, 1, 5)),
-        ("falsea", SyntaxError(TrailingCharacters, 1, 6)),
+        ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
+        ("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
+        ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
+        ("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
+        ("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
+        ("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
     ]);
 
     test_parse_ok(&[
         ("true", true),
+        (" true ", true),
         ("false", false),
+        (" false ", false),
     ]);
 }
 
 #[test]
 fn test_parse_number_errors() {
     test_parse_err::<f64>(&[
-        ("+", SyntaxError(ExpectedSomeValue, 1, 1)),
-        (".", SyntaxError(ExpectedSomeValue, 1, 1)),
-        ("-", SyntaxError(InvalidNumber, 1, 2)),
-        ("00", SyntaxError(InvalidNumber, 1, 2)),
-        ("1.", SyntaxError(InvalidNumber, 1, 3)),
-        ("1e", SyntaxError(InvalidNumber, 1, 3)),
-        ("1e+", SyntaxError(InvalidNumber, 1, 4)),
-        ("1a", SyntaxError(TrailingCharacters, 1, 2)),
+        ("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
+        (".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
+        ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
+        ("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
+        ("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
+        ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
+        ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
+        ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
     ]);
 }
 
@@ -537,6 +520,7 @@ fn test_parse_i64() {
         ("3", 3),
         ("-2", -2),
         ("-1234", -1234),
+        (" -1234 ", -1234),
     ]);
 }
 
@@ -550,15 +534,16 @@ fn test_parse_f64() {
         ("0.4e5", 0.4e5),
         ("0.4e15", 0.4e15),
         ("0.4e-01", 0.4e-01),
+        (" 0.4e-01 ", 0.4e-01),
     ]);
 }
 
 #[test]
 fn test_parse_string() {
-    test_parse_err::<string::String>(&[
-        ("\"", SyntaxError(EOFWhileParsingString, 1, 2)),
-        ("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)),
-        ("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)),
+    test_parse_err::<String>(&[
+        ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
+        ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
+        ("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
     ]);
 
     test_parse_ok(&[
@@ -578,58 +563,70 @@ fn test_parse_string() {
 #[test]
 fn test_parse_list() {
     test_parse_err::<Vec<f64>>(&[
-        ("[", SyntaxError(EOFWhileParsingValue, 1, 2)),
-        ("[ ", SyntaxError(EOFWhileParsingValue, 1, 3)),
-        ("[1", SyntaxError(EOFWhileParsingList,  1, 3)),
-        ("[1,", SyntaxError(EOFWhileParsingValue, 1, 4)),
-        ("[1,]", SyntaxError(ExpectedSomeValue, 1, 4)),
-        ("[1 2]", SyntaxError(ExpectedListCommaOrEnd, 1, 4)),
-        ("[]a", SyntaxError(TrailingCharacters, 1, 3)),
+        ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
+        ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
+        ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList,  1, 3)),
+        ("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
+        ("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
+        ("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
+        ("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
     ]);
 
     test_parse_ok(&[
-        ("[]", vec!()),
-        ("[ ]", vec!()),
-        ("[null]", vec!(())),
-        (" [ null ] ", vec!(())),
+        ("[]", vec![]),
+        ("[ ]", vec![]),
+        ("[null]", vec![()]),
+        (" [ null ] ", vec![()]),
     ]);
 
     test_parse_ok(&[
-        ("[true]", vec!(true)),
+        ("[true]", vec![true]),
     ]);
 
     test_parse_ok(&[
-        ("[3,1]", vec!(3, 1)),
-        (" [ 3 , 1 ] ", vec!(3, 1)),
+        ("[3,1]", vec![3, 1]),
+        (" [ 3 , 1 ] ", vec![3, 1]),
     ]);
 
     test_parse_ok(&[
-        ("[[3], [1, 2]]", vec!(vec!(3), vec!(1, 2))),
+        ("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
     ]);
 
-    let v: () = from_str("[]").unwrap();
-    assert_eq!(v, ());
+    test_parse_ok(&[
+        ("[1]", (1,)),
+    ]);
+
+    test_parse_ok(&[
+        ("[1, 2]", (1, 2)),
+    ]);
 
     test_parse_ok(&[
         ("[1, 2, 3]", (1, 2, 3)),
     ]);
+
+    test_parse_ok(&[
+        ("[1, [2, 3]]", (1, (2, 3))),
+    ]);
+
+    let v: () = from_str("[]").unwrap();
+    assert_eq!(v, ());
 }
 
 #[test]
 fn test_parse_object() {
-    test_parse_err::<BTreeMap<string::String, isize>>(&[
-        ("{", SyntaxError(EOFWhileParsingValue, 1, 2)),
-        ("{ ", SyntaxError(EOFWhileParsingValue, 1, 3)),
-        ("{1", SyntaxError(KeyMustBeAString, 1, 2)),
-        ("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)),
-        ("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)),
-        ("{\"a\" ", SyntaxError(EOFWhileParsingObject, 1, 6)),
-        ("{\"a\" 1", SyntaxError(ExpectedColon, 1, 6)),
-        ("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)),
-        ("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)),
-        ("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)),
-        ("{\"a\":1,", SyntaxError(EOFWhileParsingValue, 1, 8)),
-        ("{}a", SyntaxError(TrailingCharacters, 1, 3)),
+    test_parse_err::<BTreeMap<String, u32>>(&[
+        ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
+        ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
+        ("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
+        ("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
+        ("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
+        ("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
+        ("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
+        ("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
+        ("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
+        ("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
+        ("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
+        ("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
     ]);
 
     test_parse_ok(&[
@@ -716,18 +713,18 @@ fn test_parse_option() {
 fn test_parse_enum() {
     /*
     test_parse_err::<Animal>(&[
-        ("{", SyntaxError(EOFWhileParsingString, 1, 2)),
-        ("{ ", SyntaxError(EOFWhileParsingString, 1, 3)),
-        ("{1", SyntaxError(KeyMustBeAString, 1, 2)),
-        ("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)),
-        ("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)),
-        ("{\"a\" ", SyntaxError(EOFWhileParsingObject, 1, 6)),
-        ("{\"a\" 1", SyntaxError(ExpectedColon, 1, 6)),
-        ("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)),
-        ("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)),
-        ("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)),
-        ("{\"a\":1,", SyntaxError(EOFWhileParsingValue, 1, 8)),
-        ("{}a", SyntaxError(TrailingCharacters, 1, 3)),
+        ("{", Error::SyntaxError(EOFWhileParsingString, 1, 2)),
+        ("{ ", Error::SyntaxError(EOFWhileParsingString, 1, 3)),
+        ("{1", Error::SyntaxError(KeyMustBeAString, 1, 2)),
+        ("{ \"a\"", Error::SyntaxError(EOFWhileParsingObject, 1, 6)),
+        ("{\"a\"", Error::SyntaxError(EOFWhileParsingObject, 1, 5)),
+        ("{\"a\" ", Error::SyntaxError(EOFWhileParsingObject, 1, 6)),
+        ("{\"a\" 1", Error::SyntaxError(ExpectedColon, 1, 6)),
+        ("{\"a\":", Error::SyntaxError(EOFWhileParsingValue, 1, 6)),
+        ("{\"a\":1", Error::SyntaxError(EOFWhileParsingObject, 1, 7)),
+        ("{\"a\":1 1", Error::SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)),
+        ("{\"a\":1,", Error::SyntaxError(EOFWhileParsingValue, 1, 8)),
+        ("{}a", Error::SyntaxError(TrailingCharacters, 1, 3)),
     ]);
     */
 
@@ -770,12 +767,22 @@ fn test_parse_enum() {
     */
 }
 
+#[test]
+fn test_parse_trailing_whitespace() {
+    test_parse_ok(&[
+        ("[1, 2] ", vec![1, 2]),
+        ("[1, 2]\n", vec![1, 2]),
+        ("[1, 2]\t", vec![1, 2]),
+        ("[1, 2]\t \n", vec![1, 2]),
+    ]);
+}
+
 /*
 
 #[test]
 fn test_multiline_errors() {
-    test_parse_err::<BTreeMap<string::String, string::String>>(&[
-        ("{\n  \"foo\":\n \"bar\"", SyntaxError(EOFWhileParsingObject, 3us, 8us)),
+    test_parse_err::<BTreeMap<String, String>>(&[
+        ("{\n  \"foo\":\n \"bar\"", Error::SyntaxError(EOFWhileParsingObject, 3us, 8us)),
     ]);
 }
 
@@ -869,7 +876,7 @@ fn test_is_object() {
 #[test]
 fn test_as_object() {
     let json_value: Value = from_str("{}").unwrap();
-    let map = BTreeMap::<string::String, Value>::new();
+    let map = BTreeMap::<String, Value>::new();
     let json_object = json_value.as_object();
     assert_eq!(json_object, Some(&map));
 }
diff --git a/serde2/tests/test_json_builder.rs b/serde2/tests/test_json_builder.rs
new file mode 100644
index 00000000..ed1733d5
--- /dev/null
+++ b/serde2/tests/test_json_builder.rs
@@ -0,0 +1,54 @@
+#![feature(test)]
+
+extern crate serde2;
+
+use std::collections::BTreeMap;
+
+use serde2::json::value::Value;
+use serde2::json::builder::{ArrayBuilder, ObjectBuilder};
+
+#[test]
+fn test_array_builder() {
+    let value = ArrayBuilder::new().unwrap();
+    assert_eq!(value, Value::Array(Vec::new()));
+
+    let value = ArrayBuilder::new()
+        .push(1)
+        .push(2)
+        .push(3)
+        .unwrap();
+    assert_eq!(value, Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))));
+
+    let value = ArrayBuilder::new()
+        .push_array(|bld| bld.push(1).push(2).push(3))
+        .unwrap();
+    assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))))));
+
+    let value = ArrayBuilder::new()
+        .push_object(|bld|
+            bld
+                .insert("a".to_string(), 1)
+                .insert("b".to_string(), 2))
+        .unwrap();
+
+    let mut map = BTreeMap::new();
+    map.insert("a".to_string(), Value::I64(1));
+    map.insert("b".to_string(), Value::I64(2));
+    assert_eq!(value, Value::Array(vec!(Value::Object(map))));
+}
+
+#[test]
+fn test_object_builder() {
+    let value = ObjectBuilder::new().unwrap();
+    assert_eq!(value, Value::Object(BTreeMap::new()));
+
+    let value = ObjectBuilder::new()
+        .insert("a".to_string(), 1)
+        .insert("b".to_string(), 2)
+        .unwrap();
+
+    let mut map = BTreeMap::new();
+    map.insert("a".to_string(), Value::I64(1));
+    map.insert("b".to_string(), Value::I64(2));
+    assert_eq!(value, Value::Object(map));
+}