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;