diff --git a/serde_test/src/lib.rs b/serde_test/src/lib.rs index 1723e2a1..9aedac20 100644 --- a/serde_test/src/lib.rs +++ b/serde_test/src/lib.rs @@ -6,6 +6,155 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! This crate provides a convenient concise way to write unit tests for +//! implementations of [`Serialize`] and [`Deserialize`]. +//! +//! [`Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html +//! [`Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html +//! +//! The `Serialize` impl for a value can be characterized by the sequence of +//! [`Serializer`] calls that are made in the course of serializing the value, +//! so `serde_test` provides a [`Token`] abstraction which corresponds roughly +//! to `Serializer` method calls. There is an [`assert_ser_tokens`] function to +//! test that a value serializes to a particular sequence of method calls, an +//! [`assert_de_tokens`] function to test that a value can be deserialized from +//! a particular sequence of method calls, and an [`assert_tokens`] function to +//! test both directions. There are also functions to test expected failure +//! conditions. +//! +//! [`Serializer`]: https://docs.serde.rs/serde/ser/trait.Serializer.html +//! [`Token`]: https://docs.serde.rs/serde_test/enum.Token.html +//! [`assert_ser_tokens`]: https://docs.serde.rs/serde_test/fn.assert_ser_tokens.html +//! [`assert_de_tokens`]: https://docs.serde.rs/serde_test/fn.assert_de_tokens.html +//! [`assert_tokens`]: https://docs.serde.rs/serde_test/fn.assert_tokens.html +//! +//! Here is an example from the [`linked-hash-map`] crate. +//! +//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map +//! +//! ```rust +//! # extern crate serde; +//! # +//! # macro_rules! ignore { +//! # ($($tt:tt)+) => {} +//! # } +//! # +//! # ignore! { +//! extern crate linked_hash_map; +//! use linked_hash_map::LinkedHashMap; +//! # } +//! +//! extern crate serde_test; +//! use serde_test::{Token, assert_tokens}; +//! +//! # use std::fmt; +//! # use std::marker::PhantomData; +//! # +//! # use serde::ser::{Serialize, Serializer, SerializeMap}; +//! # use serde::de::{Deserialize, Deserializer, Visitor, MapAccess}; +//! # +//! # // Dumb immitation of LinkedHashMap. +//! # #[derive(PartialEq, Debug)] +//! # struct LinkedHashMap(Vec<(K, V)>); +//! # +//! # impl LinkedHashMap { +//! # fn new() -> Self { +//! # LinkedHashMap(Vec::new()) +//! # } +//! # +//! # fn insert(&mut self, k: K, v: V) { +//! # self.0.push((k, v)); +//! # } +//! # } +//! # +//! # impl Serialize for LinkedHashMap +//! # where K: Serialize, +//! # V: Serialize +//! # { +//! # fn serialize(&self, serializer: S) -> Result +//! # where S: Serializer +//! # { +//! # let mut map = serializer.serialize_map(Some(self.0.len()))?; +//! # for &(ref k, ref v) in &self.0 { +//! # map.serialize_entry(k, v)?; +//! # } +//! # map.end() +//! # } +//! # } +//! # +//! # struct LinkedHashMapVisitor(PhantomData<(K, V)>); +//! # +//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor +//! # where K: Deserialize<'de>, +//! # V: Deserialize<'de> +//! # { +//! # type Value = LinkedHashMap; +//! # +//! # fn expecting(&self, _: &mut fmt::Formatter) -> fmt::Result { +//! # unimplemented!() +//! # } +//! # +//! # fn visit_map(self, mut access: M) -> Result +//! # where M: MapAccess<'de> +//! # { +//! # let mut map = LinkedHashMap::new(); +//! # while let Some((key, value)) = access.next_entry()? { +//! # map.insert(key, value); +//! # } +//! # Ok(map) +//! # } +//! # } +//! # +//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap +//! # where K: Deserialize<'de>, +//! # V: Deserialize<'de> +//! # { +//! # fn deserialize(deserializer: D) -> Result +//! # where D: Deserializer<'de> +//! # { +//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData)) +//! # } +//! # } +//! # +//! #[test] +//! # fn not_a_test_ser_de_empty() {} +//! fn test_ser_de_empty() { +//! let map = LinkedHashMap::::new(); +//! +//! assert_tokens(&map, &[ +//! Token::Map { len: Some(0) }, +//! Token::MapEnd, +//! ]); +//! } +//! +//! #[test] +//! # fn not_a_test_ser_de() {} +//! fn test_ser_de() { +//! let mut map = LinkedHashMap::new(); +//! map.insert('b', 20); +//! map.insert('a', 10); +//! map.insert('c', 30); +//! +//! assert_tokens(&map, &[ +//! Token::Map { len: Some(3) }, +//! Token::Char('b'), +//! Token::I32(20), +//! +//! Token::Char('a'), +//! Token::I32(10), +//! +//! Token::Char('c'), +//! Token::I32(30), +//! Token::MapEnd, +//! ]); +//! } +//! # +//! # fn main() { +//! # test_ser_de_empty(); +//! # test_ser_de(); +//! # } +//! ``` + #![doc(html_root_url = "https://docs.rs/serde_test/0.9.13")] #[macro_use]