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