aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Barnard2015-12-24 19:39:31 +0000
committerEdward Barnard2015-12-24 22:22:31 +0000
commitbc194fc8ef70a0b6a88a5b23cd5da443c403ea34 (patch)
tree494634fba9242b2c58ff65f61d5a3ac7cb0e1f3d
parent8868a6880b67fce7c7147526b2973ba59376d93a (diff)
downloadrust-plist-bc194fc8ef70a0b6a88a5b23cd5da443c403ea34.tar.bz2
Add serde serialization tests
-rw-r--r--.travis.yml2
-rw-r--r--Cargo.toml8
-rw-r--r--build.rs35
-rw-r--r--src/de.rs3
-rw-r--r--src/ser.rs3
-rw-r--r--tests/serde_/mod.rs209
-rw-r--r--tests/serde_tests.rs.in4
-rw-r--r--tests/tests.rs2
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
diff --git a/Cargo.toml b/Cargo.toml
index 9cd4ec8..61add16 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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()
+}
diff --git a/src/de.rs b/src/de.rs
index 9d77e4d..4290254 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -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;
diff --git a/src/ser.rs b/src/ser.rs
index 059bbd7..d0833bb 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -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"));