4 filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored,
5 ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg,
8 use std::sync::mpsc::channel;
11 fn new() -> TestOpts {
16 exclude_should_panic: false,
17 run_ignored: RunIgnored::No,
19 bench_benchmarks: false,
23 format: OutputFormat::Pretty,
26 options: Options::new(),
31 fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
35 name: StaticTestName("1"),
37 should_panic: ShouldPanic::No,
40 testfn: DynTestFn(Box::new(move || {})),
44 name: StaticTestName("2"),
46 should_panic: ShouldPanic::No,
49 testfn: DynTestFn(Box::new(move || {})),
55 pub fn do_not_run_ignored_tests() {
59 let desc = TestDescAndFn {
61 name: StaticTestName("whatever"),
63 should_panic: ShouldPanic::No,
66 testfn: DynTestFn(Box::new(f)),
68 let (tx, rx) = channel();
69 run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
70 let (_, res, _) = rx.recv().unwrap();
75 pub fn ignored_tests_result_in_ignored() {
77 let desc = TestDescAndFn {
79 name: StaticTestName("whatever"),
81 should_panic: ShouldPanic::No,
84 testfn: DynTestFn(Box::new(f)),
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);
93 fn test_should_panic() {
97 let desc = TestDescAndFn {
99 name: StaticTestName("whatever"),
101 should_panic: ShouldPanic::Yes,
104 testfn: DynTestFn(Box::new(f)),
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);
113 fn test_should_panic_good_message() {
115 panic!("an error message");
117 let desc = TestDescAndFn {
119 name: StaticTestName("whatever"),
121 should_panic: ShouldPanic::YesWithMessage("error message"),
124 testfn: DynTestFn(Box::new(f)),
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);
133 fn test_should_panic_bad_message() {
135 panic!("an error message");
137 let expected = "foobar";
138 let failed_msg = "panic did not include expected string";
139 let desc = TestDescAndFn {
141 name: StaticTestName("whatever"),
143 should_panic: ShouldPanic::YesWithMessage(expected),
146 testfn: DynTestFn(Box::new(f)),
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)));
155 fn test_should_panic_but_succeeds() {
157 let desc = TestDescAndFn {
159 name: StaticTestName("whatever"),
161 should_panic: ShouldPanic::Yes,
164 testfn: DynTestFn(Box::new(f)),
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);
173 fn parse_ignored_flag() {
175 "progname".to_string(),
176 "filter".to_string(),
177 "--ignored".to_string(),
179 let opts = parse_opts(&args).unwrap().unwrap();
180 assert_eq!(opts.run_ignored, RunIgnored::Only);
184 fn parse_include_ignored_flag() {
186 "progname".to_string(),
187 "filter".to_string(),
188 "-Zunstable-options".to_string(),
189 "--include-ignored".to_string(),
191 let opts = parse_opts(&args).unwrap().unwrap();
192 assert_eq!(opts.run_ignored, RunIgnored::Yes);
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
200 let mut opts = TestOpts::new();
201 opts.run_tests = true;
202 opts.run_ignored = RunIgnored::Only;
204 let tests = one_ignored_one_unignored_test();
205 let filtered = filter_tests(&opts, tests);
207 assert_eq!(filtered.len(), 1);
208 assert_eq!(filtered[0].desc.name.to_string(), "1");
209 assert!(!filtered[0].desc.ignore);
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
217 let mut opts = TestOpts::new();
218 opts.run_tests = true;
219 opts.run_ignored = RunIgnored::Yes;
221 let tests = one_ignored_one_unignored_test();
222 let filtered = filter_tests(&opts, tests);
224 assert_eq!(filtered.len(), 2);
225 assert!(!filtered[0].desc.ignore);
226 assert!(!filtered[1].desc.ignore);
230 pub fn exclude_should_panic_option() {
231 let mut opts = TestOpts::new();
232 opts.run_tests = true;
233 opts.exclude_should_panic = true;
235 let mut tests = one_ignored_one_unignored_test();
236 tests.push(TestDescAndFn {
238 name: StaticTestName("3"),
240 should_panic: ShouldPanic::Yes,
243 testfn: DynTestFn(Box::new(move || {})),
246 let filtered = filter_tests(&opts, tests);
248 assert_eq!(filtered.len(), 2);
249 assert!(filtered.iter().all(|test| test.desc.should_panic == ShouldPanic::No));
253 pub fn exact_filter_match() {
254 fn tests() -> Vec<TestDescAndFn> {
255 vec!["base", "base::test", "base::test1", "base::test2"]
257 .map(|name| TestDescAndFn {
259 name: StaticTestName(name),
261 should_panic: ShouldPanic::No,
264 testfn: DynTestFn(Box::new(move || {})),
269 let substr = filter_tests(
271 filter: Some("base".into()),
276 assert_eq!(substr.len(), 4);
278 let substr = filter_tests(
280 filter: Some("bas".into()),
285 assert_eq!(substr.len(), 4);
287 let substr = filter_tests(
289 filter: Some("::test".into()),
294 assert_eq!(substr.len(), 3);
296 let substr = filter_tests(
298 filter: Some("base::test".into()),
303 assert_eq!(substr.len(), 3);
305 let exact = filter_tests(
307 filter: Some("base".into()),
313 assert_eq!(exact.len(), 1);
315 let exact = filter_tests(
317 filter: Some("bas".into()),
323 assert_eq!(exact.len(), 0);
325 let exact = filter_tests(
327 filter: Some("::test".into()),
333 assert_eq!(exact.len(), 0);
335 let exact = filter_tests(
337 filter: Some("base::test".into()),
343 assert_eq!(exact.len(), 1);
347 pub fn sort_tests() {
348 let mut opts = TestOpts::new();
349 opts.run_tests = true;
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(),
366 let mut tests = Vec::new();
368 let test = TestDescAndFn {
370 name: DynTestName((*name).clone()),
372 should_panic: ShouldPanic::No,
375 testfn: DynTestFn(Box::new(testfn)),
381 let filtered = filter_tests(&opts, tests);
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(),
397 for (a, b) in expected.iter().zip(filtered) {
398 assert!(*a == b.desc.name.to_string());
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);
409 m1.insert_metric("in-first-noise", 1000.0, 2.0);
410 m2.insert_metric("in-second-noise", 1000.0, 2.0);
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);
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);
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);
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);
426 pub fn test_bench_once_no_iter() {
427 fn f(_: &mut Bencher) {}
432 pub fn test_bench_once_iter() {
433 fn f(b: &mut Bencher) {
440 pub fn test_bench_no_iter() {
441 fn f(_: &mut Bencher) {}
443 let (tx, rx) = channel();
445 let desc = TestDesc {
446 name: StaticTestName("f"),
448 should_panic: ShouldPanic::No,
452 crate::bench::benchmark(desc, tx, true, f);
457 pub fn test_bench_iter() {
458 fn f(b: &mut Bencher) {
462 let (tx, rx) = channel();
464 let desc = TestDesc {
465 name: StaticTestName("f"),
467 should_panic: ShouldPanic::No,
471 crate::bench::benchmark(desc, tx, true, f);
476 fn should_sort_failures_before_printing_them() {
477 let test_a = TestDesc {
478 name: StaticTestName("a"),
480 should_panic: ShouldPanic::No,
484 let test_b = TestDesc {
485 name: StaticTestName("b"),
487 should_panic: ShouldPanic::No,
491 let mut out = PrettyFormatter::new(Raw(Vec::new()), false, 10, false);
493 let st = ConsoleTestState {
502 metrics: MetricMap::new(),
503 failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
504 options: Options::new(),
505 not_failures: Vec::new(),
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!(),
514 let apos = s.find("a").unwrap();
515 let bpos = s.find("b").unwrap();
516 assert!(apos < bpos);