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 158 mod assert; 159 mod configure; 160 mod de; 161 mod error; 162 mod ser; 163 mod token; 164 165 pub use crate::assert::{ 166 assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error, 167 assert_tokens, 168 }; 169 pub use crate::configure::{Compact, Configure, Readable}; 170 pub use crate::token::Token; 171