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