quickcheck/lib.rs
1/*!
2This crate is a port of
3[Haskell's QuickCheck](https://hackage.haskell.org/package/QuickCheck).
4
5QuickCheck is a library for random testing of program properties. The
6programmer provides a specification of the program, in the form of properties
7which functions should satisfy, and QuickCheck then tests that the properties
8hold in a large number of randomly generated cases.
9
10For detailed examples, please see the
11[README](https://github.com/BurntSushi/quickcheck).
12
13# Compatibility
14
15In general, this crate considers the `Arbitrary` implementations provided as
16implementation details. Strategies may or may not change over time, which may
17cause new test failures, presumably due to the discovery of new bugs due to a
18new kind of witness being generated. These sorts of changes may happen in
19semver compatible releases.
20*/
21
22pub use crate::arbitrary::{
23 empty_shrinker, single_shrinker, Arbitrary, Gen, NoShrink,
24};
25pub use crate::tester::{quickcheck, QuickCheck, TestResult, Testable};
26
27/// A macro for writing quickcheck tests.
28///
29/// This macro takes as input one or more property functions to test, and
30/// produces a proper `#[test]` function for each property. If the property
31/// fails, the behavior is as if `quickcheck` were called on the property
32/// (i.e., it panics and fails the test).
33///
34/// Note that this macro doesn't support `mut` or patterns in parameters.
35///
36/// # Example
37///
38/// ```rust
39/// # #[macro_use] extern crate quickcheck; fn main() {
40/// quickcheck! {
41/// fn prop_reverse_reverse(xs: Vec<usize>) -> bool {
42/// let rev: Vec<_> = xs.clone().into_iter().rev().collect();
43/// let revrev: Vec<_> = rev.into_iter().rev().collect();
44/// xs == revrev
45/// }
46/// };
47/// # }
48/// ```
49#[macro_export]
50macro_rules! quickcheck {
51 (@as_items $($i:item)*) => ($($i)*);
52 {
53 $(
54 $(#[$m:meta])*
55 fn $fn_name:ident($($arg_name:ident : $arg_ty:ty),*) -> $ret:ty {
56 $($code:tt)*
57 }
58 )*
59 } => (
60 $crate::quickcheck! {
61 @as_items
62 $(
63 #[test]
64 $(#[$m])*
65 fn $fn_name() {
66 fn prop($($arg_name: $arg_ty),*) -> $ret {
67 $($code)*
68 }
69 $crate::quickcheck(prop as fn($($arg_ty),*) -> $ret);
70 }
71 )*
72 }
73 )
74}
75
76#[cfg(feature = "use_logging")]
77fn env_logger_init() -> Result<(), log::SetLoggerError> {
78 env_logger::try_init()
79}
80#[cfg(feature = "use_logging")]
81macro_rules! info {
82 ($($tt:tt)*) => {
83 log::info!($($tt)*)
84 };
85}
86
87#[cfg(not(feature = "use_logging"))]
88fn env_logger_init() {}
89#[cfg(not(feature = "use_logging"))]
90macro_rules! info {
91 ($($_ignore:tt)*) => {
92 ()
93 };
94}
95
96mod arbitrary;
97mod tester;
98
99#[cfg(test)]
100mod tests;