• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This crate provides a convenient concise way to write unit tests for
2 //! implementations of [`Serialize`] and [`Deserialize`].
3 //!
4 //! [`Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
5 //! [`Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
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`]: https://docs.serde.rs/serde/ser/trait.Serializer.html
18 //! [`Token`]: https://docs.serde.rs/serde_test/enum.Token.html
19 //! [`assert_ser_tokens`]: https://docs.serde.rs/serde_test/fn.assert_ser_tokens.html
20 //! [`assert_de_tokens`]: https://docs.serde.rs/serde_test/fn.assert_de_tokens.html
21 //! [`assert_tokens`]: https://docs.serde.rs/serde_test/fn.assert_tokens.html
22 //!
23 //! Here is an example from the [`linked-hash-map`] crate.
24 //!
25 //! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
26 //!
27 //! ```edition2018
28 //! # const IGNORE: &str = stringify! {
29 //! use linked_hash_map::LinkedHashMap;
30 //! # };
31 //! use serde_test::{Token, assert_tokens};
32 //!
33 //! # use std::fmt;
34 //! # use std::marker::PhantomData;
35 //! #
36 //! # use serde::ser::{Serialize, Serializer, SerializeMap};
37 //! # use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
38 //! #
39 //! # // Dumb imitation of LinkedHashMap.
40 //! # #[derive(PartialEq, Debug)]
41 //! # struct LinkedHashMap<K, V>(Vec<(K, V)>);
42 //! #
43 //! # impl<K, V> LinkedHashMap<K, V> {
44 //! #     fn new() -> Self {
45 //! #         LinkedHashMap(Vec::new())
46 //! #     }
47 //! #
48 //! #     fn insert(&mut self, k: K, v: V) {
49 //! #         self.0.push((k, v));
50 //! #     }
51 //! # }
52 //! #
53 //! # impl<K, V> Serialize for LinkedHashMap<K, V>
54 //! # where
55 //! #     K: Serialize,
56 //! #     V: Serialize,
57 //! # {
58 //! #     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
59 //! #     where
60 //! #         S: Serializer,
61 //! #     {
62 //! #         let mut map = serializer.serialize_map(Some(self.0.len()))?;
63 //! #         for &(ref k, ref v) in &self.0 {
64 //! #             map.serialize_entry(k, v)?;
65 //! #         }
66 //! #         map.end()
67 //! #     }
68 //! # }
69 //! #
70 //! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
71 //! #
72 //! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
73 //! # where
74 //! #     K: Deserialize<'de>,
75 //! #     V: Deserialize<'de>,
76 //! # {
77 //! #     type Value = LinkedHashMap<K, V>;
78 //! #
79 //! #     fn expecting(&self, _: &mut fmt::Formatter) -> fmt::Result {
80 //! #         unimplemented!()
81 //! #     }
82 //! #
83 //! #     fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
84 //! #     where
85 //! #         M: MapAccess<'de>,
86 //! #     {
87 //! #         let mut map = LinkedHashMap::new();
88 //! #         while let Some((key, value)) = access.next_entry()? {
89 //! #             map.insert(key, value);
90 //! #         }
91 //! #         Ok(map)
92 //! #     }
93 //! # }
94 //! #
95 //! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
96 //! # where
97 //! #     K: Deserialize<'de>,
98 //! #     V: Deserialize<'de>,
99 //! # {
100 //! #     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
101 //! #     where
102 //! #         D: Deserializer<'de>,
103 //! #     {
104 //! #         deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
105 //! #     }
106 //! # }
107 //! #
108 //! #[test]
109 //! # fn not_a_test_ser_de_empty() {}
110 //! fn test_ser_de_empty() {
111 //!     let map = LinkedHashMap::<char, u32>::new();
112 //!
113 //!     assert_tokens(&map, &[
114 //!         Token::Map { len: Some(0) },
115 //!         Token::MapEnd,
116 //!     ]);
117 //! }
118 //!
119 //! #[test]
120 //! # fn not_a_test_ser_de() {}
121 //! fn test_ser_de() {
122 //!     let mut map = LinkedHashMap::new();
123 //!     map.insert('b', 20);
124 //!     map.insert('a', 10);
125 //!     map.insert('c', 30);
126 //!
127 //!     assert_tokens(&map, &[
128 //!         Token::Map { len: Some(3) },
129 //!         Token::Char('b'),
130 //!         Token::I32(20),
131 //!
132 //!         Token::Char('a'),
133 //!         Token::I32(10),
134 //!
135 //!         Token::Char('c'),
136 //!         Token::I32(30),
137 //!         Token::MapEnd,
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.123")]
148 #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
149 #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
150 // Ignored clippy lints
151 #![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
152 // Ignored clippy_pedantic lints
153 #![cfg_attr(
154     feature = "cargo-clippy",
155     allow(
156         empty_line_after_outer_attr,
157         missing_docs_in_private_items,
158         module_name_repetitions,
159         must_use_candidate,
160         redundant_field_names,
161         too_many_lines,
162         use_debug,
163         use_self
164     )
165 )]
166 
167 #[macro_use]
168 extern crate serde;
169 
170 mod de;
171 mod error;
172 mod ser;
173 
174 mod assert;
175 mod configure;
176 mod token;
177 
178 pub use assert::{
179     assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
180     assert_tokens,
181 };
182 pub use token::Token;
183 
184 pub use configure::{Compact, Configure, Readable};
185 
186 // Not public API.
187 #[doc(hidden)]
188 pub use de::Deserializer;
189