default_test/
lib.rs

1//! Provides a Rust trait similar to [Default](https://doc.rust-lang.org/std/default/trait.Default.html) that can be used in tests.
2//!
3//! Often tests need to construct mock instances of structs.  For example:
4//! ```rust
5//! struct User {
6//!     id: usize,
7//!     name: String,
8//!     email: String,
9//!     admin: bool
10//! }
11//! ```
12//!
13//! While it's tempting to define Default, often tests need mock values for types that
14//! shouldn't apply in production code.  Sometimes, tests need values for types that don't even implement Default.
15//!
16//! This crate provides [DefaultTest](./trait.DefaultTest.html), a trait which can provide default instances with mock values.
17//! Tests can construct instances, and use the spread operator to override values.
18//! ```rust
19//! # struct User {
20//! #    id: usize,
21//! #    name: String,
22//! #    email: String,
23//! #    admin: bool
24//! # }
25//! use default_test::DefaultTest;
26//!
27//! impl DefaultTest for User {
28//!     fn default_test() -> Self {
29//!         User {
30//!             id: 0,
31//!             name: "name".into(),
32//!             email: "email".into(),
33//!             admin: false
34//!         }
35//!     }
36//! }
37//!
38//! #[cfg(test)]
39//! mod tests {
40//!     #[test]
41//!     fn test() {
42//!         let user = User {
43//!             id: 99
44//!             ..User::test_default()
45//!         };
46//!         // ...
47//!     }
48//! }
49//! ```
50//!
51//! This style makes tests much more stable, and when adding a field to a struct, it reduces the amount of required edits in your unit tests.
52//!
53//! ## Roadmap:
54//! - Derive macro which fills sensible defaults that would be useful in unit test implementations.  
55//! String files would be filled with their property name, and other types may use T::default() or unique values.
56
57/// A trait for giving a type a useful default value, in the scope of unit tests.
58///
59/// Sometimes, unit tests need to construct a mock value when working with structs, such as:
60/// ```rust
61/// struct User {
62///     id: usize,
63///     name: String,
64///     email: String,
65///     admin: bool
66/// }
67/// ```
68///
69/// DefaultTest can be used to define default mocked values for use in tests.
70/// Tests can construct instances, and use the spread operator to override values.
71/// ```rust
72/// # struct User {
73/// #    id: usize,
74/// #    name: String,
75/// #    email: String,
76/// #    admin: bool
77/// # }
78/// use default_test::DefaultTest;
79///
80/// impl DefaultTest for User {
81///     fn default_test() -> Self {
82///         User {
83///             id: 0,
84///             name: "name".into(),
85///             email: "email".into(),
86///             admin: false
87///         }
88///     }
89/// }
90///
91/// #[cfg(test)]
92/// mod tests {
93///     #[test]
94///     fn test() {
95///         let user = User {
96///             id: 99
97///             ..User::test_default()
98///         };
99///         // ...
100///     }
101/// }
102/// ```
103pub trait DefaultTest {
104    /// Returns a "default value" for a type, containing mocked values suitable for use in tests.
105    /// Default values may contain literals, unique numbers, etc, to make test assertions easier to work with.
106    /// # Examples
107    /// ```
108    /// use default_test::DefaultTest;
109    /// let x: String = DefaultTest::default_test();
110    /// ```
111    /// Make your own:
112    /// ```
113    /// use default_test::DefaultTest;
114    ///
115    /// struct Foo {
116    ///     bar: String   
117    /// }
118    ///
119    /// impl DefaultTest for Foo {
120    ///     fn default_test() -> Self {
121    ///         Self {
122    ///             bar: "bar".into()
123    ///         }
124    ///     }  
125    /// }
126    fn default_test() -> Self;
127}
128
129impl DefaultTest for bool {
130    fn default_test() -> Self {
131        false
132    }
133}
134
135impl DefaultTest for char {
136    fn default_test() -> Self {
137        '-'
138    }
139}
140
141impl DefaultTest for &str {
142    fn default_test() -> Self {
143        "string"
144    }
145}
146
147impl DefaultTest for String {
148    fn default_test() -> Self {
149        "string".into()
150    }
151}
152
153impl DefaultTest for usize {
154    fn default_test() -> Self {
155        0
156    }
157}
158
159impl DefaultTest for isize {
160    fn default_test() -> Self {
161        0
162    }
163}
164
165impl DefaultTest for u8 {
166    fn default_test() -> Self {
167        0
168    }
169}
170
171impl DefaultTest for i8 {
172    fn default_test() -> Self {
173        0
174    }
175}
176
177impl DefaultTest for u16 {
178    fn default_test() -> Self {
179        0
180    }
181}
182
183impl DefaultTest for i16 {
184    fn default_test() -> Self {
185        0
186    }
187}
188
189impl DefaultTest for u32 {
190    fn default_test() -> Self {
191        0
192    }
193}
194
195impl DefaultTest for i32 {
196    fn default_test() -> Self {
197        0
198    }
199}
200
201impl DefaultTest for u64 {
202    fn default_test() -> Self {
203        0
204    }
205}
206
207impl DefaultTest for i64 {
208    fn default_test() -> Self {
209        0
210    }
211}
212
213impl DefaultTest for u128 {
214    fn default_test() -> Self {
215        0
216    }
217}
218
219impl DefaultTest for i128 {
220    fn default_test() -> Self {
221        0
222    }
223}
224
225impl DefaultTest for f32 {
226    fn default_test() -> Self {
227        0.0
228    }
229}
230
231impl DefaultTest for f64 {
232    fn default_test() -> Self {
233        0.0
234    }
235}
236
237// impl<T, E> DefaultTest for Result<T, E>
238// where
239//     T: DefaultTest,
240// {
241//     fn default_test() -> Self {
242//         Ok(T::default_test())
243//     }
244// }
245
246// impl<T> DefaultTest for Option<T>
247// where
248//     T: DefaultTest,
249// {
250//     fn default_test() -> Self {
251//         Some(T::default_test())
252//     }
253// }