]> git.lizzy.rs Git - rust.git/blob - src/libtest/tests.rs
add a preliminary existential test; not really enough
[rust.git] / src / libtest / tests.rs
1 use crate::bench;
2 use crate::test::{
3     filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored,
4     ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg,
5     TrIgnored, TrOk,
6 };
7 use crate::Bencher;
8 use crate::Concurrent;
9 use std::sync::mpsc::channel;
10
11 fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
12     vec![
13         TestDescAndFn {
14             desc: TestDesc {
15                 name: StaticTestName("1"),
16                 ignore: true,
17                 should_panic: ShouldPanic::No,
18                 allow_fail: false,
19             },
20             testfn: DynTestFn(Box::new(move || {})),
21         },
22         TestDescAndFn {
23             desc: TestDesc {
24                 name: StaticTestName("2"),
25                 ignore: false,
26                 should_panic: ShouldPanic::No,
27                 allow_fail: false,
28             },
29             testfn: DynTestFn(Box::new(move || {})),
30         },
31     ]
32 }
33
34 #[test]
35 pub fn do_not_run_ignored_tests() {
36     fn f() {
37         panic!();
38     }
39     let desc = TestDescAndFn {
40         desc: TestDesc {
41             name: StaticTestName("whatever"),
42             ignore: true,
43             should_panic: ShouldPanic::No,
44             allow_fail: false,
45         },
46         testfn: DynTestFn(Box::new(f)),
47     };
48     let (tx, rx) = channel();
49     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
50     let (_, res, _) = rx.recv().unwrap();
51     assert!(res != TrOk);
52 }
53
54 #[test]
55 pub fn ignored_tests_result_in_ignored() {
56     fn f() {}
57     let desc = TestDescAndFn {
58         desc: TestDesc {
59             name: StaticTestName("whatever"),
60             ignore: true,
61             should_panic: ShouldPanic::No,
62             allow_fail: false,
63         },
64         testfn: DynTestFn(Box::new(f)),
65     };
66     let (tx, rx) = channel();
67     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
68     let (_, res, _) = rx.recv().unwrap();
69     assert!(res == TrIgnored);
70 }
71
72 #[test]
73 fn test_should_panic() {
74     fn f() {
75         panic!();
76     }
77     let desc = TestDescAndFn {
78         desc: TestDesc {
79             name: StaticTestName("whatever"),
80             ignore: false,
81             should_panic: ShouldPanic::Yes,
82             allow_fail: false,
83         },
84         testfn: DynTestFn(Box::new(f)),
85     };
86     let (tx, rx) = channel();
87     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
88     let (_, res, _) = rx.recv().unwrap();
89     assert!(res == TrOk);
90 }
91
92 #[test]
93 fn test_should_panic_good_message() {
94     fn f() {
95         panic!("an error message");
96     }
97     let desc = TestDescAndFn {
98         desc: TestDesc {
99             name: StaticTestName("whatever"),
100             ignore: false,
101             should_panic: ShouldPanic::YesWithMessage("error message"),
102             allow_fail: false,
103         },
104         testfn: DynTestFn(Box::new(f)),
105     };
106     let (tx, rx) = channel();
107     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
108     let (_, res, _) = rx.recv().unwrap();
109     assert!(res == TrOk);
110 }
111
112 #[test]
113 fn test_should_panic_bad_message() {
114     fn f() {
115         panic!("an error message");
116     }
117     let expected = "foobar";
118     let failed_msg = "panic did not include expected string";
119     let desc = TestDescAndFn {
120         desc: TestDesc {
121             name: StaticTestName("whatever"),
122             ignore: false,
123             should_panic: ShouldPanic::YesWithMessage(expected),
124             allow_fail: false,
125         },
126         testfn: DynTestFn(Box::new(f)),
127     };
128     let (tx, rx) = channel();
129     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
130     let (_, res, _) = rx.recv().unwrap();
131     assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
132 }
133
134 #[test]
135 fn test_should_panic_but_succeeds() {
136     fn f() {}
137     let desc = TestDescAndFn {
138         desc: TestDesc {
139             name: StaticTestName("whatever"),
140             ignore: false,
141             should_panic: ShouldPanic::Yes,
142             allow_fail: false,
143         },
144         testfn: DynTestFn(Box::new(f)),
145     };
146     let (tx, rx) = channel();
147     run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
148     let (_, res, _) = rx.recv().unwrap();
149     assert!(res == TrFailed);
150 }
151
152 #[test]
153 fn parse_ignored_flag() {
154     let args = vec![
155         "progname".to_string(),
156         "filter".to_string(),
157         "--ignored".to_string(),
158     ];
159     let opts = parse_opts(&args).unwrap().unwrap();
160     assert_eq!(opts.run_ignored, RunIgnored::Only);
161 }
162
163 #[test]
164 fn parse_include_ignored_flag() {
165     let args = vec![
166         "progname".to_string(),
167         "filter".to_string(),
168         "-Zunstable-options".to_string(),
169         "--include-ignored".to_string(),
170     ];
171     let opts = parse_opts(&args).unwrap().unwrap();
172     assert_eq!(opts.run_ignored, RunIgnored::Yes);
173 }
174
175 #[test]
176 pub fn filter_for_ignored_option() {
177     // When we run ignored tests the test filter should filter out all the
178     // unignored tests and flip the ignore flag on the rest to false
179
180     let mut opts = TestOpts::new();
181     opts.run_tests = true;
182     opts.run_ignored = RunIgnored::Only;
183
184     let tests = one_ignored_one_unignored_test();
185     let filtered = filter_tests(&opts, tests);
186
187     assert_eq!(filtered.len(), 1);
188     assert_eq!(filtered[0].desc.name.to_string(), "1");
189     assert!(!filtered[0].desc.ignore);
190 }
191
192 #[test]
193 pub fn run_include_ignored_option() {
194     // When we "--include-ignored" tests, the ignore flag should be set to false on
195     // all tests and no test filtered out
196
197     let mut opts = TestOpts::new();
198     opts.run_tests = true;
199     opts.run_ignored = RunIgnored::Yes;
200
201     let tests = one_ignored_one_unignored_test();
202     let filtered = filter_tests(&opts, tests);
203
204     assert_eq!(filtered.len(), 2);
205     assert!(!filtered[0].desc.ignore);
206     assert!(!filtered[1].desc.ignore);
207 }
208
209 #[test]
210 pub fn exclude_should_panic_option() {
211     let mut opts = TestOpts::new();
212     opts.run_tests = true;
213     opts.exclude_should_panic = true;
214
215     let mut tests = one_ignored_one_unignored_test();
216     tests.push(TestDescAndFn {
217         desc: TestDesc {
218             name: StaticTestName("3"),
219             ignore: false,
220             should_panic: ShouldPanic::Yes,
221             allow_fail: false,
222         },
223         testfn: DynTestFn(Box::new(move || {})),
224     });
225
226     let filtered = filter_tests(&opts, tests);
227
228     assert_eq!(filtered.len(), 2);
229     assert!(filtered.iter().all(|test| test.desc.should_panic == ShouldPanic::No));
230 }
231
232 #[test]
233 pub fn exact_filter_match() {
234     fn tests() -> Vec<TestDescAndFn> {
235         vec!["base", "base::test", "base::test1", "base::test2"]
236             .into_iter()
237             .map(|name| TestDescAndFn {
238                 desc: TestDesc {
239                     name: StaticTestName(name),
240                     ignore: false,
241                     should_panic: ShouldPanic::No,
242                     allow_fail: false,
243                 },
244                 testfn: DynTestFn(Box::new(move || {})),
245             })
246             .collect()
247     }
248
249     let substr = filter_tests(
250         &TestOpts {
251             filter: Some("base".into()),
252             ..TestOpts::new()
253         },
254         tests(),
255     );
256     assert_eq!(substr.len(), 4);
257
258     let substr = filter_tests(
259         &TestOpts {
260             filter: Some("bas".into()),
261             ..TestOpts::new()
262         },
263         tests(),
264     );
265     assert_eq!(substr.len(), 4);
266
267     let substr = filter_tests(
268         &TestOpts {
269             filter: Some("::test".into()),
270             ..TestOpts::new()
271         },
272         tests(),
273     );
274     assert_eq!(substr.len(), 3);
275
276     let substr = filter_tests(
277         &TestOpts {
278             filter: Some("base::test".into()),
279             ..TestOpts::new()
280         },
281         tests(),
282     );
283     assert_eq!(substr.len(), 3);
284
285     let exact = filter_tests(
286         &TestOpts {
287             filter: Some("base".into()),
288             filter_exact: true,
289             ..TestOpts::new()
290         },
291         tests(),
292     );
293     assert_eq!(exact.len(), 1);
294
295     let exact = filter_tests(
296         &TestOpts {
297             filter: Some("bas".into()),
298             filter_exact: true,
299             ..TestOpts::new()
300         },
301         tests(),
302     );
303     assert_eq!(exact.len(), 0);
304
305     let exact = filter_tests(
306         &TestOpts {
307             filter: Some("::test".into()),
308             filter_exact: true,
309             ..TestOpts::new()
310         },
311         tests(),
312     );
313     assert_eq!(exact.len(), 0);
314
315     let exact = filter_tests(
316         &TestOpts {
317             filter: Some("base::test".into()),
318             filter_exact: true,
319             ..TestOpts::new()
320         },
321         tests(),
322     );
323     assert_eq!(exact.len(), 1);
324 }
325
326 #[test]
327 pub fn sort_tests() {
328     let mut opts = TestOpts::new();
329     opts.run_tests = true;
330
331     let names = vec![
332         "sha1::test".to_string(),
333         "isize::test_to_str".to_string(),
334         "isize::test_pow".to_string(),
335         "test::do_not_run_ignored_tests".to_string(),
336         "test::ignored_tests_result_in_ignored".to_string(),
337         "test::first_free_arg_should_be_a_filter".to_string(),
338         "test::parse_ignored_flag".to_string(),
339         "test::parse_include_ignored_flag".to_string(),
340         "test::filter_for_ignored_option".to_string(),
341         "test::run_include_ignored_option".to_string(),
342         "test::sort_tests".to_string(),
343     ];
344     let tests = {
345         fn testfn() {}
346         let mut tests = Vec::new();
347         for name in &names {
348             let test = TestDescAndFn {
349                 desc: TestDesc {
350                     name: DynTestName((*name).clone()),
351                     ignore: false,
352                     should_panic: ShouldPanic::No,
353                     allow_fail: false,
354                 },
355                 testfn: DynTestFn(Box::new(testfn)),
356             };
357             tests.push(test);
358         }
359         tests
360     };
361     let filtered = filter_tests(&opts, tests);
362
363     let expected = vec![
364         "isize::test_pow".to_string(),
365         "isize::test_to_str".to_string(),
366         "sha1::test".to_string(),
367         "test::do_not_run_ignored_tests".to_string(),
368         "test::filter_for_ignored_option".to_string(),
369         "test::first_free_arg_should_be_a_filter".to_string(),
370         "test::ignored_tests_result_in_ignored".to_string(),
371         "test::parse_ignored_flag".to_string(),
372         "test::parse_include_ignored_flag".to_string(),
373         "test::run_include_ignored_option".to_string(),
374         "test::sort_tests".to_string(),
375     ];
376
377     for (a, b) in expected.iter().zip(filtered) {
378         assert!(*a == b.desc.name.to_string());
379     }
380 }
381
382 #[test]
383 pub fn test_metricmap_compare() {
384     let mut m1 = MetricMap::new();
385     let mut m2 = MetricMap::new();
386     m1.insert_metric("in-both-noise", 1000.0, 200.0);
387     m2.insert_metric("in-both-noise", 1100.0, 200.0);
388
389     m1.insert_metric("in-first-noise", 1000.0, 2.0);
390     m2.insert_metric("in-second-noise", 1000.0, 2.0);
391
392     m1.insert_metric("in-both-want-downwards-but-regressed", 1000.0, 10.0);
393     m2.insert_metric("in-both-want-downwards-but-regressed", 2000.0, 10.0);
394
395     m1.insert_metric("in-both-want-downwards-and-improved", 2000.0, 10.0);
396     m2.insert_metric("in-both-want-downwards-and-improved", 1000.0, 10.0);
397
398     m1.insert_metric("in-both-want-upwards-but-regressed", 2000.0, -10.0);
399     m2.insert_metric("in-both-want-upwards-but-regressed", 1000.0, -10.0);
400
401     m1.insert_metric("in-both-want-upwards-and-improved", 1000.0, -10.0);
402     m2.insert_metric("in-both-want-upwards-and-improved", 2000.0, -10.0);
403 }
404
405 #[test]
406 pub fn test_bench_once_no_iter() {
407     fn f(_: &mut Bencher) {}
408     bench::run_once(f);
409 }
410
411 #[test]
412 pub fn test_bench_once_iter() {
413     fn f(b: &mut Bencher) {
414         b.iter(|| {})
415     }
416     bench::run_once(f);
417 }
418
419 #[test]
420 pub fn test_bench_no_iter() {
421     fn f(_: &mut Bencher) {}
422
423     let (tx, rx) = channel();
424
425     let desc = TestDesc {
426         name: StaticTestName("f"),
427         ignore: false,
428         should_panic: ShouldPanic::No,
429         allow_fail: false,
430     };
431
432     crate::bench::benchmark(desc, tx, true, f);
433     rx.recv().unwrap();
434 }
435
436 #[test]
437 pub fn test_bench_iter() {
438     fn f(b: &mut Bencher) {
439         b.iter(|| {})
440     }
441
442     let (tx, rx) = channel();
443
444     let desc = TestDesc {
445         name: StaticTestName("f"),
446         ignore: false,
447         should_panic: ShouldPanic::No,
448         allow_fail: false,
449     };
450
451     crate::bench::benchmark(desc, tx, true, f);
452     rx.recv().unwrap();
453 }