serde_test/
lib.rs

1//! This crate provides a convenient concise way to write unit tests for
2//! implementations of [`Serialize`] and [`Deserialize`].
3//!
4//! [`Serialize`]: serde::ser::Serialize
5//! [`Deserialize`]: serde::de::Deserialize
6//!
7//! The `Serialize` impl for a value can be characterized by the sequence of
8//! [`Serializer`] calls that are made in the course of serializing the value,
9//! so `serde_test` provides a [`Token`] abstraction which corresponds roughly
10//! to `Serializer` method calls. There is an [`assert_ser_tokens`] function to
11//! test that a value serializes to a particular sequence of method calls, an
12//! [`assert_de_tokens`] function to test that a value can be deserialized from
13//! a particular sequence of method calls, and an [`assert_tokens`] function to
14//! test both directions. There are also functions to test expected failure
15//! conditions.
16//!
17//! [`Serializer`]: serde::ser::Serializer
18//!
19//! Here is an example from the [`linked-hash-map`] crate.
20//!
21//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
22//!
23//! ```
24//! # const IGNORE: &str = stringify! {
25//! use linked_hash_map::LinkedHashMap;
26//! # };
27//! use serde_test::{assert_tokens, Token};
28//!
29//! # use std::fmt;
30//! # use std::marker::PhantomData;
31//! #
32//! # use serde::ser::{Serialize, Serializer, SerializeMap};
33//! # use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
34//! #
35//! # // Dumb imitation of LinkedHashMap.
36//! # #[derive(PartialEq, Debug)]
37//! # struct LinkedHashMap<K, V>(Vec<(K, V)>);
38//! #
39//! # impl<K, V> LinkedHashMap<K, V> {
40//! #     fn new() -> Self {
41//! #         LinkedHashMap(Vec::new())
42//! #     }
43//! #
44//! #     fn insert(&mut self, k: K, v: V) {
45//! #         self.0.push((k, v));
46//! #     }
47//! # }
48//! #
49//! # impl<K, V> Serialize for LinkedHashMap<K, V>
50//! # where
51//! #     K: Serialize,
52//! #     V: Serialize,
53//! # {
54//! #     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55//! #     where
56//! #         S: Serializer,
57//! #     {
58//! #         let mut map = serializer.serialize_map(Some(self.0.len()))?;
59//! #         for &(ref k, ref v) in &self.0 {
60//! #             map.serialize_entry(k, v)?;
61//! #         }
62//! #         map.end()
63//! #     }
64//! # }
65//! #
66//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
67//! #
68//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
69//! # where
70//! #     K: Deserialize<'de>,
71//! #     V: Deserialize<'de>,
72//! # {
73//! #     type Value = LinkedHashMap<K, V>;
74//! #
75//! #     fn expecting(&self, _: &mut fmt::Formatter) -> fmt::Result {
76//! #         unimplemented!()
77//! #     }
78//! #
79//! #     fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
80//! #     where
81//! #         M: MapAccess<'de>,
82//! #     {
83//! #         let mut map = LinkedHashMap::new();
84//! #         while let Some((key, value)) = access.next_entry()? {
85//! #             map.insert(key, value);
86//! #         }
87//! #         Ok(map)
88//! #     }
89//! # }
90//! #
91//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
92//! # where
93//! #     K: Deserialize<'de>,
94//! #     V: Deserialize<'de>,
95//! # {
96//! #     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97//! #     where
98//! #         D: Deserializer<'de>,
99//! #     {
100//! #         deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
101//! #     }
102//! # }
103//! #
104//! #[test]
105//! # fn not_a_test_ser_de_empty() {}
106//! fn test_ser_de_empty() {
107//!     let map = LinkedHashMap::<char, u32>::new();
108//!
109//!     assert_tokens(
110//!         &map,
111//!         &[
112//!             Token::Map { len: Some(0) },
113//!             Token::MapEnd,
114//!         ],
115//!     );
116//! }
117//!
118//! #[test]
119//! # fn not_a_test_ser_de() {}
120//! fn test_ser_de() {
121//!     let mut map = LinkedHashMap::new();
122//!     map.insert('b', 20);
123//!     map.insert('a', 10);
124//!     map.insert('c', 30);
125//!
126//!     assert_tokens(
127//!         &map,
128//!         &[
129//!             Token::Map { len: Some(3) },
130//!             Token::Char('b'),
131//!             Token::I32(20),
132//!             Token::Char('a'),
133//!             Token::I32(10),
134//!             Token::Char('c'),
135//!             Token::I32(30),
136//!             Token::MapEnd,
137//!         ],
138//!     );
139//! }
140//! #
141//! # fn main() {
142//! #     test_ser_de_empty();
143//! #     test_ser_de();
144//! # }
145//! ```
146
147#![doc(html_root_url = "https://docs.rs/serde_test/1.0.177")]
148// Ignored clippy lints
149#![allow(clippy::float_cmp, clippy::needless_doctest_main)]
150// Ignored clippy_pedantic lints
151#![allow(
152    clippy::manual_assert,
153    clippy::missing_panics_doc,
154    clippy::module_name_repetitions,
155    clippy::too_many_lines
156)]
157
158mod assert;
159mod configure;
160mod de;
161mod error;
162mod ser;
163mod token;
164
165pub use crate::assert::{
166    assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
167    assert_tokens,
168};
169pub use crate::configure::{Compact, Configure, Readable};
170pub use crate::token::Token;