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