diff options
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | Cargo.toml | 8 | ||||
| -rw-r--r-- | build.rs | 35 | ||||
| -rw-r--r-- | src/de.rs | 3 | ||||
| -rw-r--r-- | src/ser.rs | 3 | ||||
| -rw-r--r-- | tests/serde_/mod.rs | 209 | ||||
| -rw-r--r-- | tests/serde_tests.rs.in | 4 | ||||
| -rw-r--r-- | tests/tests.rs | 2 | 
8 files changed, 265 insertions, 1 deletions
| diff --git a/.travis.yml b/.travis.yml index bdc9561..2c31be2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_script:  script:  - |    travis-cargo build && -  travis-cargo test && +  travis-cargo test -- --features serde_tests &&    travis-cargo --only stable doc  after_success:  - travis-cargo --only stable doc-upload @@ -7,6 +7,10 @@ license = "MIT"  repository = "https://github.com/ebarnard/rust-plist/"  documentation = "https://ebarnard.github.io/rust-plist/"  keywords = ["plist", "parser"] +build = "build.rs" + +[features] +serde_tests = ["serde_codegen", "syntex"]  [dependencies]  rustc-serialize = "0.3.16" @@ -14,3 +18,7 @@ xml-rs = "0.2.2"  byteorder = "0.4.2"  chrono = "0.2.17"  serde = "0.6.6" + +[build-dependencies] +serde_codegen = { version = "0.6.6", optional = true } +syntex = { version = "0.22.0", optional = true } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..df4282a --- /dev/null +++ b/build.rs @@ -0,0 +1,35 @@ +#[cfg(feature = "serde_tests")] +extern crate syntex; + +#[cfg(feature = "serde_tests")] +extern crate serde_codegen; + +#[cfg(feature = "serde_tests")] +mod serde_tests { +    use std::env; +    use std::path::Path; + +    use syntex; +    use serde_codegen; + +    pub fn build() { +        let out_dir = env::var_os("OUT_DIR").unwrap(); + +        let src = Path::new("tests/serde_tests.rs.in"); +        let dst = Path::new(&out_dir).join("serde_tests.rs"); + +        let mut registry = syntex::Registry::new(); + +        serde_codegen::register(&mut registry); +        registry.expand("", &src, &dst).unwrap(); +    } +} + +#[cfg(not(feature = "serde_tests"))] +mod serde_tests { +    pub fn build() {} +} + +fn main() { +    serde_tests::build() +} @@ -1,3 +1,6 @@ +// Tests for the serializer and deserializer are located in tests/serde_/mod.rs. +// They can be run with `cargo test --features serde_tests`. +  use serde::de::{Deserializer as SerdeDeserializer, Error as SerdeError, Visitor, SeqVisitor,                  MapVisitor, VariantVisitor, Deserialize, EnumVisitor};  use std::iter::Peekable; @@ -1,3 +1,6 @@ +// Tests for the serializer and deserializer are located in tests/serde_/mod.rs. +// They can be run with `cargo test --features serde_tests`. +  use serde::ser::{MapVisitor, Serialize, Serializer as SerdeSerializer, SeqVisitor};  use {EventWriter, PlistEvent}; diff --git a/tests/serde_/mod.rs b/tests/serde_/mod.rs new file mode 100644 index 0000000..a2cbd41 --- /dev/null +++ b/tests/serde_/mod.rs @@ -0,0 +1,209 @@ +use plist::{Deserializer, EventWriter, PlistEvent, Serializer}; +use plist::PlistEvent::*; +use serde::{Deserialize, Serialize}; +use std::fmt::Debug; + +struct VecWriter { +    events: Vec<PlistEvent>, +} + +impl VecWriter { +    pub fn new() -> VecWriter { +        VecWriter { events: Vec::new() } +    } + +    pub fn into_inner(self) -> Vec<PlistEvent> { +        self.events +    } +} + +impl EventWriter for VecWriter { +    fn write(&mut self, event: &PlistEvent) -> Result<(), ()> { +        self.events.push(event.clone()); +        Ok(()) +    } +} + +fn new_serializer() -> Serializer<VecWriter> { +    Serializer::new(VecWriter::new()) +} + +fn new_deserializer(events: Vec<PlistEvent>) -> Deserializer<Vec<Result<PlistEvent, ()>>, ()> { +    let result_events = events.into_iter().map(|e| Ok(e)).collect(); +    Deserializer::new(result_events) +} + +fn assert_roundtrip<T>(obj: T, comparison: Option<&[PlistEvent]>) +    where T: Debug + Deserialize + PartialEq + Serialize +{ +    let mut se = new_serializer(); + +    obj.serialize(&mut se).unwrap(); + +    let events = se.into_inner().into_inner(); + +    match comparison { +        Some(comparison) => { +            assert_eq!(&events[..], comparison); +        } +        None => (), +    } + +    let mut de = new_deserializer(events); + +    let new_obj = T::deserialize(&mut de).unwrap(); + +    assert_eq!(new_obj, obj); +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +enum Animal { +    Cow, +    Dog(DogOuter), +    Frog(Result<String, bool>, Vec<f64>), +    Cat { +        age: usize, +        name: String, +        firmware: Option<Vec<u8>>, +    }, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct DogOuter { +    inner: Vec<DogInner>, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct DogInner { +    a: (), +    b: usize, +    c: Vec<String>, +} + +#[test] +fn cow() { +    let cow = Animal::Cow; + +    let comparison = &[StartDictionary(Some(1)), +                       StringValue("Cow".to_owned()), +                       StringValue("".to_owned()), +                       EndDictionary]; + +    assert_roundtrip(cow, Some(comparison)); +} + + +#[test] +fn dog() { +    let dog = Animal::Dog(DogOuter { +        inner: vec![DogInner { +                        a: (), +                        b: 12, +                        c: vec!["a".to_string(), "b".to_string()], +                    }], +    }); + +    let comparison = &[StartDictionary(Some(1)), +                       StringValue("Dog".to_owned()), +                       StartDictionary(Some(1)), +                       StringValue("inner".to_owned()), +                       StartArray(Some(1)), +                       StartDictionary(Some(3)), +                       StringValue("a".to_owned()), +                       StringValue("".to_owned()), +                       StringValue("b".to_owned()), +                       IntegerValue(12), +                       StringValue("c".to_owned()), +                       StartArray(Some(2)), +                       StringValue("a".to_owned()), +                       StringValue("b".to_owned()), +                       EndArray, +                       EndDictionary, +                       EndArray, +                       EndDictionary, +                       EndDictionary]; + +    assert_roundtrip(dog, Some(comparison)); +} + + +#[test] +fn frog() { +    let frog = Animal::Frog(Ok("hello".to_owned()), +                            vec![1.0, 2.0, 3.14159, 0.000000001, 1.27e31]); + +    let comparison = &[StartDictionary(Some(1)), +                       StringValue("Frog".to_owned()), +                       StartArray(Some(2)), +                       StartDictionary(Some(1)), +                       StringValue("Ok".to_owned()), +                       StringValue("hello".to_owned()), +                       EndDictionary, +                       StartArray(Some(5)), +                       RealValue(1.0), +                       RealValue(2.0), +                       RealValue(3.14159), +                       RealValue(0.000000001), +                       RealValue(1.27e31), +                       EndArray, +                       EndArray, +                       EndDictionary]; + +    assert_roundtrip(frog, Some(comparison)); +} + + +#[test] +fn cat() { +    let cat = Animal::Cat { +        age: 12, +        name: "Paws".to_owned(), +        firmware: Some(vec![0, 1, 2, 3, 4, 5, 6, 7, 8]), +    }; + +    let comparison = &[StartDictionary(Some(1)), +                       StringValue("Cat".to_owned()), +                       StartDictionary(Some(3)), +                       StringValue("age".to_owned()), +                       IntegerValue(12), +                       StringValue("name".to_owned()), +                       StringValue("Paws".to_owned()), +                       StringValue("firmware".to_owned()), +                       StartDictionary(Some(1)), +                       StringValue("Some".to_owned()), +                       StartArray(Some(9)), +                       IntegerValue(0), +                       IntegerValue(1), +                       IntegerValue(2), +                       IntegerValue(3), +                       IntegerValue(4), +                       IntegerValue(5), +                       IntegerValue(6), +                       IntegerValue(7), +                       IntegerValue(8), +                       EndArray, +                       EndDictionary, +                       EndDictionary, +                       EndDictionary]; + +    assert_roundtrip(cat, Some(comparison)); +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct NewtypeStruct(NewtypeInner); + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct NewtypeInner(u8, u8, u8); + +#[test] +fn newtype_struct() { +    let newtype = NewtypeStruct(NewtypeInner(34, 32, 13)); + +    let comparison = &[StartArray(Some(3)), +                       IntegerValue(34), +                       IntegerValue(32), +                       IntegerValue(13), +                       EndArray]; + +    assert_roundtrip(newtype, Some(comparison)); +} diff --git a/tests/serde_tests.rs.in b/tests/serde_tests.rs.in new file mode 100644 index 0000000..8e04ab0 --- /dev/null +++ b/tests/serde_tests.rs.in @@ -0,0 +1,4 @@ +extern crate serde; +extern crate plist; + +mod serde_; diff --git a/tests/tests.rs b/tests/tests.rs new file mode 100644 index 0000000..0aaf77c --- /dev/null +++ b/tests/tests.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "serde_tests")] +include!(concat!(env!("OUT_DIR"), "/serde_tests.rs")); | 
