1 use std::cmp::Ord;
2 use std::collections::hash_map::DefaultHasher;
3 use std::collections::{HashMap, HashSet};
4 use std::ffi::CString;
5 use std::hash::BuildHasherDefault;
6 use std::path::PathBuf;
7 
8 use super::{quickcheck, Gen, QuickCheck, TestResult};
9 
10 #[test]
prop_oob()11 fn prop_oob() {
12     fn prop() -> bool {
13         let zero: Vec<bool> = vec![];
14         zero[0]
15     }
16     match QuickCheck::new().quicktest(prop as fn() -> bool) {
17         Ok(n) => panic!(
18             "prop_oob should fail with a runtime error \
19              but instead it passed {} tests.",
20             n
21         ),
22         _ => return,
23     }
24 }
25 
26 #[test]
prop_reverse_reverse()27 fn prop_reverse_reverse() {
28     fn prop(xs: Vec<usize>) -> bool {
29         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
30         let revrev: Vec<_> = rev.into_iter().rev().collect();
31         xs == revrev
32     }
33     quickcheck(prop as fn(Vec<usize>) -> bool);
34 }
35 
36 quickcheck! {
37     fn prop_reverse_reverse_macro(xs: Vec<usize>) -> bool {
38         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
39         let revrev: Vec<_> = rev.into_iter().rev().collect();
40         xs == revrev
41     }
42 
43     #[should_panic]
44     fn prop_macro_panic(_x: u32) -> bool {
45         assert!(false);
46         false
47     }
48 }
49 
50 #[test]
reverse_single()51 fn reverse_single() {
52     fn prop(xs: Vec<usize>) -> TestResult {
53         if xs.len() != 1 {
54             TestResult::discard()
55         } else {
56             TestResult::from_bool(
57                 xs == xs.clone().into_iter().rev().collect::<Vec<_>>(),
58             )
59         }
60     }
61     quickcheck(prop as fn(Vec<usize>) -> TestResult);
62 }
63 
64 #[test]
reverse_app()65 fn reverse_app() {
66     fn prop(xs: Vec<usize>, ys: Vec<usize>) -> bool {
67         let mut app = xs.clone();
68         app.extend(ys.iter().cloned());
69         let app_rev: Vec<usize> = app.into_iter().rev().collect();
70 
71         let rxs: Vec<usize> = xs.into_iter().rev().collect();
72         let mut rev_app = ys.into_iter().rev().collect::<Vec<usize>>();
73         rev_app.extend(rxs.into_iter());
74 
75         app_rev == rev_app
76     }
77     quickcheck(prop as fn(Vec<usize>, Vec<usize>) -> bool);
78 }
79 
80 #[test]
max()81 fn max() {
82     fn prop(x: isize, y: isize) -> TestResult {
83         if x > y {
84             TestResult::discard()
85         } else {
86             TestResult::from_bool(::std::cmp::max(x, y) == y)
87         }
88     }
89     quickcheck(prop as fn(isize, isize) -> TestResult);
90 }
91 
92 #[test]
sort()93 fn sort() {
94     fn prop(mut xs: Vec<isize>) -> bool {
95         xs.sort_by(|x, y| x.cmp(y));
96         for i in xs.windows(2) {
97             if i[0] > i[1] {
98                 return false;
99             }
100         }
101         true
102     }
103     quickcheck(prop as fn(Vec<isize>) -> bool);
104 }
105 
sieve(n: usize) -> Vec<usize>106 fn sieve(n: usize) -> Vec<usize> {
107     if n <= 1 {
108         return vec![];
109     }
110 
111     let mut marked = vec![false; n + 1];
112     marked[0] = true;
113     marked[1] = true;
114     marked[2] = true;
115     for p in 2..n {
116         for i in (2 * p..n).filter(|&n| n % p == 0) {
117             marked[i] = true;
118         }
119     }
120     marked
121         .iter()
122         .enumerate()
123         .filter_map(|(i, &m)| if m { None } else { Some(i) })
124         .collect()
125 }
126 
is_prime(n: usize) -> bool127 fn is_prime(n: usize) -> bool {
128     n != 0 && n != 1 && (2..).take_while(|i| i * i <= n).all(|i| n % i != 0)
129 }
130 
131 #[test]
132 #[should_panic]
sieve_not_prime()133 fn sieve_not_prime() {
134     fn prop_all_prime(n: u8) -> bool {
135         sieve(n as usize).into_iter().all(is_prime)
136     }
137     quickcheck(prop_all_prime as fn(u8) -> bool);
138 }
139 
140 #[test]
141 #[should_panic]
sieve_not_all_primes()142 fn sieve_not_all_primes() {
143     fn prop_prime_iff_in_the_sieve(n: u8) -> bool {
144         let n = n as usize;
145         sieve(n) == (0..(n + 1)).filter(|&i| is_prime(i)).collect::<Vec<_>>()
146     }
147     quickcheck(prop_prime_iff_in_the_sieve as fn(u8) -> bool);
148 }
149 
150 #[test]
testable_result()151 fn testable_result() {
152     fn result() -> Result<bool, String> {
153         Ok(true)
154     }
155     quickcheck(result as fn() -> Result<bool, String>);
156 }
157 
158 #[test]
159 #[should_panic]
testable_result_err()160 fn testable_result_err() {
161     quickcheck(Err::<bool, i32> as fn(i32) -> Result<bool, i32>);
162 }
163 
164 #[test]
testable_unit()165 fn testable_unit() {
166     fn do_nothing() {}
167     quickcheck(do_nothing as fn());
168 }
169 
170 #[test]
testable_unit_panic()171 fn testable_unit_panic() {
172     fn panic() {
173         panic!()
174     }
175     assert!(QuickCheck::new().quicktest(panic as fn()).is_err());
176 }
177 
178 #[test]
regression_issue_83()179 fn regression_issue_83() {
180     fn prop(_: u8) -> bool {
181         true
182     }
183     QuickCheck::new().gen(Gen::new(1024)).quickcheck(prop as fn(u8) -> bool)
184 }
185 
186 #[test]
regression_issue_83_signed()187 fn regression_issue_83_signed() {
188     fn prop(_: i8) -> bool {
189         true
190     }
191     QuickCheck::new().gen(Gen::new(1024)).quickcheck(prop as fn(i8) -> bool)
192 }
193 
194 // Test that we can show the message after panic
195 #[test]
196 #[should_panic(expected = "foo")]
panic_msg_1()197 fn panic_msg_1() {
198     fn prop() -> bool {
199         panic!("foo");
200     }
201     quickcheck(prop as fn() -> bool);
202 }
203 
204 #[test]
205 #[should_panic(expected = "foo")]
panic_msg_2()206 fn panic_msg_2() {
207     fn prop() -> bool {
208         assert!("foo" == "bar");
209         true
210     }
211     quickcheck(prop as fn() -> bool);
212 }
213 
214 #[test]
215 #[should_panic(expected = "foo")]
panic_msg_3()216 fn panic_msg_3() {
217     fn prop() -> bool {
218         assert_eq!("foo", "bar");
219         true
220     }
221     quickcheck(prop as fn() -> bool);
222 }
223 
224 #[test]
225 #[should_panic]
regression_issue_107_hang()226 fn regression_issue_107_hang() {
227     fn prop(a: Vec<u8>) -> bool {
228         a.contains(&1)
229     }
230     quickcheck(prop as fn(_) -> bool);
231 }
232 
233 #[test]
234 #[should_panic(
235     expected = "(Unable to generate enough tests, 0 not discarded.)"
236 )]
all_tests_discarded_min_tests_passed_set()237 fn all_tests_discarded_min_tests_passed_set() {
238     fn prop_discarded(_: u8) -> TestResult {
239         TestResult::discard()
240     }
241 
242     QuickCheck::new()
243         .tests(16)
244         .min_tests_passed(8)
245         .quickcheck(prop_discarded as fn(u8) -> TestResult)
246 }
247 
248 #[test]
all_tests_discarded_min_tests_passed_missing()249 fn all_tests_discarded_min_tests_passed_missing() {
250     fn prop_discarded(_: u8) -> TestResult {
251         TestResult::discard()
252     }
253 
254     QuickCheck::new().quickcheck(prop_discarded as fn(u8) -> TestResult)
255 }
256 
257 quickcheck! {
258     /// The following is a very simplistic test, which only verifies
259     /// that our PathBuf::arbitrary does not panic.  Still, that's
260     /// something!  :)
261     fn pathbuf(_p: PathBuf) -> bool {
262         true
263     }
264 
265     fn basic_hashset(_set: HashSet<u8>) -> bool {
266         true
267     }
268 
269     fn basic_hashmap(_map: HashMap<u8, u8>) -> bool {
270         true
271     }
272 
273     fn substitute_hashset(
274         _set: HashSet<u8, BuildHasherDefault<DefaultHasher>>
275     ) -> bool {
276         true
277     }
278 
279     fn substitute_hashmap(
280         _map: HashMap<u8, u8, BuildHasherDefault<DefaultHasher>>
281     ) -> bool {
282         true
283     }
284 
285     fn cstring(_p: CString) -> bool {
286         true
287     }
288 }
289