]>
Commit | Line | Data |
---|---|---|
416331ca XL |
1 | use super::*; |
2 | ||
e74abb32 XL |
3 | use crate::{ |
4 | bench::Bencher, | |
5 | console::OutputLocation, | |
e74abb32 | 6 | formatters::PrettyFormatter, |
dfeec247 | 7 | options::OutputFormat, |
e74abb32 | 8 | test::{ |
dfeec247 XL |
9 | filter_tests, |
10 | parse_opts, | |
11 | run_test, | |
12 | DynTestFn, | |
13 | DynTestName, | |
14 | MetricMap, | |
15 | RunIgnored, | |
16 | RunStrategy, | |
17 | ShouldPanic, | |
18 | StaticTestName, | |
19 | TestDesc, | |
20 | TestDescAndFn, | |
21 | TestOpts, | |
22 | TrIgnored, | |
23 | TrOk, | |
e74abb32 XL |
24 | // FIXME (introduced by #65251) |
25 | // ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TestTimeOptions, | |
26 | // TestType, TrFailedMsg, TrIgnored, TrOk, | |
27 | }, | |
dfeec247 | 28 | time::{TestTimeOptions, TimeThreshold}, |
dc9dc135 | 29 | }; |
dc9dc135 | 30 | use std::sync::mpsc::channel; |
e74abb32 | 31 | use std::time::Duration; |
dc9dc135 | 32 | |
416331ca XL |
33 | impl TestOpts { |
34 | fn new() -> TestOpts { | |
35 | TestOpts { | |
36 | list: false, | |
6a06907d | 37 | filters: vec![], |
416331ca | 38 | filter_exact: false, |
60c5eb7d | 39 | force_run_in_process: false, |
416331ca XL |
40 | exclude_should_panic: false, |
41 | run_ignored: RunIgnored::No, | |
42 | run_tests: false, | |
43 | bench_benchmarks: false, | |
44 | logfile: None, | |
45 | nocapture: false, | |
46 | color: AutoColor, | |
47 | format: OutputFormat::Pretty, | |
48 | test_threads: None, | |
49 | skip: vec![], | |
e74abb32 | 50 | time_options: None, |
416331ca XL |
51 | options: Options::new(), |
52 | } | |
53 | } | |
54 | } | |
55 | ||
dc9dc135 XL |
56 | fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> { |
57 | vec![ | |
58 | TestDescAndFn { | |
59 | desc: TestDesc { | |
60 | name: StaticTestName("1"), | |
61 | ignore: true, | |
62 | should_panic: ShouldPanic::No, | |
63 | allow_fail: false, | |
17df50a5 XL |
64 | #[cfg(not(bootstrap))] |
65 | compile_fail: false, | |
66 | #[cfg(not(bootstrap))] | |
67 | no_run: false, | |
e74abb32 | 68 | test_type: TestType::Unknown, |
dc9dc135 XL |
69 | }, |
70 | testfn: DynTestFn(Box::new(move || {})), | |
71 | }, | |
72 | TestDescAndFn { | |
73 | desc: TestDesc { | |
74 | name: StaticTestName("2"), | |
75 | ignore: false, | |
76 | should_panic: ShouldPanic::No, | |
77 | allow_fail: false, | |
17df50a5 XL |
78 | #[cfg(not(bootstrap))] |
79 | compile_fail: false, | |
80 | #[cfg(not(bootstrap))] | |
81 | no_run: false, | |
e74abb32 | 82 | test_type: TestType::Unknown, |
dc9dc135 XL |
83 | }, |
84 | testfn: DynTestFn(Box::new(move || {})), | |
85 | }, | |
86 | ] | |
87 | } | |
88 | ||
89 | #[test] | |
90 | pub fn do_not_run_ignored_tests() { | |
91 | fn f() { | |
92 | panic!(); | |
93 | } | |
94 | let desc = TestDescAndFn { | |
95 | desc: TestDesc { | |
96 | name: StaticTestName("whatever"), | |
97 | ignore: true, | |
98 | should_panic: ShouldPanic::No, | |
99 | allow_fail: false, | |
17df50a5 XL |
100 | #[cfg(not(bootstrap))] |
101 | compile_fail: false, | |
102 | #[cfg(not(bootstrap))] | |
103 | no_run: false, | |
e74abb32 | 104 | test_type: TestType::Unknown, |
dc9dc135 XL |
105 | }, |
106 | testfn: DynTestFn(Box::new(f)), | |
107 | }; | |
108 | let (tx, rx) = channel(); | |
cdc7bbd5 | 109 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 | 110 | let result = rx.recv().unwrap().result; |
60c5eb7d | 111 | assert_ne!(result, TrOk); |
dc9dc135 XL |
112 | } |
113 | ||
114 | #[test] | |
115 | pub fn ignored_tests_result_in_ignored() { | |
116 | fn f() {} | |
117 | let desc = TestDescAndFn { | |
118 | desc: TestDesc { | |
119 | name: StaticTestName("whatever"), | |
120 | ignore: true, | |
121 | should_panic: ShouldPanic::No, | |
122 | allow_fail: false, | |
17df50a5 XL |
123 | #[cfg(not(bootstrap))] |
124 | compile_fail: false, | |
125 | #[cfg(not(bootstrap))] | |
126 | no_run: false, | |
e74abb32 | 127 | test_type: TestType::Unknown, |
dc9dc135 XL |
128 | }, |
129 | testfn: DynTestFn(Box::new(f)), | |
130 | }; | |
131 | let (tx, rx) = channel(); | |
cdc7bbd5 | 132 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 | 133 | let result = rx.recv().unwrap().result; |
60c5eb7d | 134 | assert_eq!(result, TrIgnored); |
dc9dc135 XL |
135 | } |
136 | ||
e74abb32 | 137 | // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) |
dc9dc135 | 138 | #[test] |
e74abb32 | 139 | #[cfg(not(target_os = "emscripten"))] |
dc9dc135 XL |
140 | fn test_should_panic() { |
141 | fn f() { | |
142 | panic!(); | |
143 | } | |
144 | let desc = TestDescAndFn { | |
145 | desc: TestDesc { | |
146 | name: StaticTestName("whatever"), | |
147 | ignore: false, | |
148 | should_panic: ShouldPanic::Yes, | |
149 | allow_fail: false, | |
17df50a5 XL |
150 | #[cfg(not(bootstrap))] |
151 | compile_fail: false, | |
152 | #[cfg(not(bootstrap))] | |
153 | no_run: false, | |
e74abb32 | 154 | test_type: TestType::Unknown, |
dc9dc135 XL |
155 | }, |
156 | testfn: DynTestFn(Box::new(f)), | |
157 | }; | |
158 | let (tx, rx) = channel(); | |
cdc7bbd5 | 159 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 | 160 | let result = rx.recv().unwrap().result; |
60c5eb7d | 161 | assert_eq!(result, TrOk); |
dc9dc135 XL |
162 | } |
163 | ||
e74abb32 | 164 | // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) |
dc9dc135 | 165 | #[test] |
e74abb32 | 166 | #[cfg(not(target_os = "emscripten"))] |
dc9dc135 XL |
167 | fn test_should_panic_good_message() { |
168 | fn f() { | |
169 | panic!("an error message"); | |
170 | } | |
171 | let desc = TestDescAndFn { | |
172 | desc: TestDesc { | |
173 | name: StaticTestName("whatever"), | |
174 | ignore: false, | |
175 | should_panic: ShouldPanic::YesWithMessage("error message"), | |
176 | allow_fail: false, | |
17df50a5 XL |
177 | #[cfg(not(bootstrap))] |
178 | compile_fail: false, | |
179 | #[cfg(not(bootstrap))] | |
180 | no_run: false, | |
e74abb32 | 181 | test_type: TestType::Unknown, |
dc9dc135 XL |
182 | }, |
183 | testfn: DynTestFn(Box::new(f)), | |
184 | }; | |
185 | let (tx, rx) = channel(); | |
cdc7bbd5 | 186 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 | 187 | let result = rx.recv().unwrap().result; |
60c5eb7d | 188 | assert_eq!(result, TrOk); |
dc9dc135 XL |
189 | } |
190 | ||
e74abb32 | 191 | // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) |
dc9dc135 | 192 | #[test] |
e74abb32 | 193 | #[cfg(not(target_os = "emscripten"))] |
dc9dc135 | 194 | fn test_should_panic_bad_message() { |
e74abb32 | 195 | use crate::tests::TrFailedMsg; |
dc9dc135 XL |
196 | fn f() { |
197 | panic!("an error message"); | |
198 | } | |
199 | let expected = "foobar"; | |
60c5eb7d XL |
200 | let failed_msg = r#"panic did not contain expected string |
201 | panic message: `"an error message"`, | |
202 | expected substring: `"foobar"`"#; | |
dc9dc135 XL |
203 | let desc = TestDescAndFn { |
204 | desc: TestDesc { | |
205 | name: StaticTestName("whatever"), | |
206 | ignore: false, | |
207 | should_panic: ShouldPanic::YesWithMessage(expected), | |
208 | allow_fail: false, | |
17df50a5 XL |
209 | #[cfg(not(bootstrap))] |
210 | compile_fail: false, | |
211 | #[cfg(not(bootstrap))] | |
212 | no_run: false, | |
e74abb32 | 213 | test_type: TestType::Unknown, |
dc9dc135 XL |
214 | }, |
215 | testfn: DynTestFn(Box::new(f)), | |
216 | }; | |
217 | let (tx, rx) = channel(); | |
cdc7bbd5 | 218 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 | 219 | let result = rx.recv().unwrap().result; |
60c5eb7d XL |
220 | assert_eq!(result, TrFailedMsg(failed_msg.to_string())); |
221 | } | |
222 | ||
223 | // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) | |
224 | #[test] | |
225 | #[cfg(not(target_os = "emscripten"))] | |
226 | fn test_should_panic_non_string_message_type() { | |
227 | use crate::tests::TrFailedMsg; | |
6a06907d | 228 | use std::any::TypeId; |
60c5eb7d | 229 | fn f() { |
5869c6ff | 230 | std::panic::panic_any(1i32); |
60c5eb7d XL |
231 | } |
232 | let expected = "foobar"; | |
dfeec247 XL |
233 | let failed_msg = format!( |
234 | r#"expected panic with string value, | |
60c5eb7d | 235 | found non-string value: `{:?}` |
dfeec247 XL |
236 | expected substring: `"foobar"`"#, |
237 | TypeId::of::<i32>() | |
238 | ); | |
60c5eb7d XL |
239 | let desc = TestDescAndFn { |
240 | desc: TestDesc { | |
241 | name: StaticTestName("whatever"), | |
242 | ignore: false, | |
243 | should_panic: ShouldPanic::YesWithMessage(expected), | |
244 | allow_fail: false, | |
17df50a5 XL |
245 | #[cfg(not(bootstrap))] |
246 | compile_fail: false, | |
247 | #[cfg(not(bootstrap))] | |
248 | no_run: false, | |
60c5eb7d XL |
249 | test_type: TestType::Unknown, |
250 | }, | |
251 | testfn: DynTestFn(Box::new(f)), | |
252 | }; | |
253 | let (tx, rx) = channel(); | |
cdc7bbd5 | 254 | run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
60c5eb7d XL |
255 | let result = rx.recv().unwrap().result; |
256 | assert_eq!(result, TrFailedMsg(failed_msg)); | |
dc9dc135 XL |
257 | } |
258 | ||
e74abb32 | 259 | // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) |
dc9dc135 | 260 | #[test] |
e74abb32 | 261 | #[cfg(not(target_os = "emscripten"))] |
dc9dc135 | 262 | fn test_should_panic_but_succeeds() { |
5869c6ff XL |
263 | let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")]; |
264 | ||
265 | for &should_panic in should_panic_variants.iter() { | |
266 | fn f() {} | |
267 | let desc = TestDescAndFn { | |
268 | desc: TestDesc { | |
269 | name: StaticTestName("whatever"), | |
270 | ignore: false, | |
271 | should_panic, | |
272 | allow_fail: false, | |
17df50a5 XL |
273 | #[cfg(not(bootstrap))] |
274 | compile_fail: false, | |
275 | #[cfg(not(bootstrap))] | |
276 | no_run: false, | |
5869c6ff XL |
277 | test_type: TestType::Unknown, |
278 | }, | |
279 | testfn: DynTestFn(Box::new(f)), | |
280 | }; | |
281 | let (tx, rx) = channel(); | |
cdc7bbd5 XL |
282 | run_test( |
283 | &TestOpts::new(), | |
284 | false, | |
285 | TestId(0), | |
286 | desc, | |
287 | RunStrategy::InProcess, | |
288 | tx, | |
289 | Concurrent::No, | |
290 | ); | |
5869c6ff XL |
291 | let result = rx.recv().unwrap().result; |
292 | assert_eq!( | |
293 | result, | |
294 | TrFailedMsg("test did not panic as expected".to_string()), | |
295 | "should_panic == {:?}", | |
296 | should_panic | |
297 | ); | |
298 | } | |
e74abb32 XL |
299 | } |
300 | ||
301 | fn report_time_test_template(report_time: bool) -> Option<TestExecTime> { | |
302 | fn f() {} | |
303 | let desc = TestDescAndFn { | |
304 | desc: TestDesc { | |
305 | name: StaticTestName("whatever"), | |
306 | ignore: false, | |
307 | should_panic: ShouldPanic::No, | |
308 | allow_fail: false, | |
17df50a5 XL |
309 | #[cfg(not(bootstrap))] |
310 | compile_fail: false, | |
311 | #[cfg(not(bootstrap))] | |
312 | no_run: false, | |
e74abb32 XL |
313 | test_type: TestType::Unknown, |
314 | }, | |
315 | testfn: DynTestFn(Box::new(f)), | |
316 | }; | |
dfeec247 | 317 | let time_options = if report_time { Some(TestTimeOptions::default()) } else { None }; |
e74abb32 | 318 | |
dfeec247 | 319 | let test_opts = TestOpts { time_options, ..TestOpts::new() }; |
e74abb32 | 320 | let (tx, rx) = channel(); |
cdc7bbd5 | 321 | run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 XL |
322 | let exec_time = rx.recv().unwrap().exec_time; |
323 | exec_time | |
324 | } | |
325 | ||
326 | #[test] | |
327 | fn test_should_not_report_time() { | |
328 | let exec_time = report_time_test_template(false); | |
329 | assert!(exec_time.is_none()); | |
330 | } | |
331 | ||
332 | #[test] | |
333 | fn test_should_report_time() { | |
334 | let exec_time = report_time_test_template(true); | |
335 | assert!(exec_time.is_some()); | |
336 | } | |
337 | ||
338 | fn time_test_failure_template(test_type: TestType) -> TestResult { | |
339 | fn f() {} | |
340 | let desc = TestDescAndFn { | |
341 | desc: TestDesc { | |
342 | name: StaticTestName("whatever"), | |
343 | ignore: false, | |
344 | should_panic: ShouldPanic::No, | |
345 | allow_fail: false, | |
17df50a5 XL |
346 | #[cfg(not(bootstrap))] |
347 | compile_fail: false, | |
348 | #[cfg(not(bootstrap))] | |
349 | no_run: false, | |
dfeec247 | 350 | test_type, |
e74abb32 XL |
351 | }, |
352 | testfn: DynTestFn(Box::new(f)), | |
353 | }; | |
354 | // `Default` will initialize all the thresholds to 0 milliseconds. | |
355 | let mut time_options = TestTimeOptions::default(); | |
356 | time_options.error_on_excess = true; | |
357 | ||
dfeec247 | 358 | let test_opts = TestOpts { time_options: Some(time_options), ..TestOpts::new() }; |
e74abb32 | 359 | let (tx, rx) = channel(); |
cdc7bbd5 | 360 | run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No); |
e74abb32 XL |
361 | let result = rx.recv().unwrap().result; |
362 | ||
363 | result | |
364 | } | |
365 | ||
366 | #[test] | |
367 | fn test_error_on_exceed() { | |
368 | let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest]; | |
369 | ||
60c5eb7d | 370 | for test_type in types.iter() { |
e74abb32 XL |
371 | let result = time_test_failure_template(*test_type); |
372 | ||
373 | assert_eq!(result, TestResult::TrTimedFail); | |
374 | } | |
375 | ||
376 | // Check that for unknown tests thresholds aren't applied. | |
377 | let result = time_test_failure_template(TestType::Unknown); | |
378 | assert_eq!(result, TestResult::TrOk); | |
379 | } | |
380 | ||
381 | fn typed_test_desc(test_type: TestType) -> TestDesc { | |
382 | TestDesc { | |
383 | name: StaticTestName("whatever"), | |
384 | ignore: false, | |
385 | should_panic: ShouldPanic::No, | |
386 | allow_fail: false, | |
17df50a5 XL |
387 | #[cfg(not(bootstrap))] |
388 | compile_fail: false, | |
389 | #[cfg(not(bootstrap))] | |
390 | no_run: false, | |
dfeec247 | 391 | test_type, |
e74abb32 XL |
392 | } |
393 | } | |
394 | ||
395 | fn test_exec_time(millis: u64) -> TestExecTime { | |
396 | TestExecTime(Duration::from_millis(millis)) | |
397 | } | |
398 | ||
399 | #[test] | |
400 | fn test_time_options_threshold() { | |
401 | let unit = TimeThreshold::new(Duration::from_millis(50), Duration::from_millis(100)); | |
402 | let integration = TimeThreshold::new(Duration::from_millis(500), Duration::from_millis(1000)); | |
403 | let doc = TimeThreshold::new(Duration::from_millis(5000), Duration::from_millis(10000)); | |
404 | ||
405 | let options = TestTimeOptions { | |
406 | error_on_excess: false, | |
407 | colored: false, | |
408 | unit_threshold: unit.clone(), | |
409 | integration_threshold: integration.clone(), | |
410 | doctest_threshold: doc.clone(), | |
411 | }; | |
412 | ||
413 | let test_vector = [ | |
414 | (TestType::UnitTest, unit.warn.as_millis() - 1, false, false), | |
415 | (TestType::UnitTest, unit.warn.as_millis(), true, false), | |
416 | (TestType::UnitTest, unit.critical.as_millis(), true, true), | |
417 | (TestType::IntegrationTest, integration.warn.as_millis() - 1, false, false), | |
418 | (TestType::IntegrationTest, integration.warn.as_millis(), true, false), | |
419 | (TestType::IntegrationTest, integration.critical.as_millis(), true, true), | |
420 | (TestType::DocTest, doc.warn.as_millis() - 1, false, false), | |
421 | (TestType::DocTest, doc.warn.as_millis(), true, false), | |
422 | (TestType::DocTest, doc.critical.as_millis(), true, true), | |
423 | ]; | |
424 | ||
60c5eb7d | 425 | for (test_type, time, expected_warn, expected_critical) in test_vector.iter() { |
e74abb32 XL |
426 | let test_desc = typed_test_desc(*test_type); |
427 | let exec_time = test_exec_time(*time as u64); | |
428 | ||
429 | assert_eq!(options.is_warn(&test_desc, &exec_time), *expected_warn); | |
430 | assert_eq!(options.is_critical(&test_desc, &exec_time), *expected_critical); | |
431 | } | |
dc9dc135 XL |
432 | } |
433 | ||
434 | #[test] | |
435 | fn parse_ignored_flag() { | |
dfeec247 | 436 | let args = vec!["progname".to_string(), "filter".to_string(), "--ignored".to_string()]; |
dc9dc135 XL |
437 | let opts = parse_opts(&args).unwrap().unwrap(); |
438 | assert_eq!(opts.run_ignored, RunIgnored::Only); | |
439 | } | |
440 | ||
e1599b0c XL |
441 | #[test] |
442 | fn parse_show_output_flag() { | |
dfeec247 | 443 | let args = vec!["progname".to_string(), "filter".to_string(), "--show-output".to_string()]; |
e1599b0c XL |
444 | let opts = parse_opts(&args).unwrap().unwrap(); |
445 | assert!(opts.options.display_output); | |
446 | } | |
447 | ||
dc9dc135 XL |
448 | #[test] |
449 | fn parse_include_ignored_flag() { | |
5869c6ff | 450 | let args = vec!["progname".to_string(), "filter".to_string(), "--include-ignored".to_string()]; |
dc9dc135 XL |
451 | let opts = parse_opts(&args).unwrap().unwrap(); |
452 | assert_eq!(opts.run_ignored, RunIgnored::Yes); | |
453 | } | |
454 | ||
455 | #[test] | |
456 | pub fn filter_for_ignored_option() { | |
457 | // When we run ignored tests the test filter should filter out all the | |
458 | // unignored tests and flip the ignore flag on the rest to false | |
459 | ||
460 | let mut opts = TestOpts::new(); | |
461 | opts.run_tests = true; | |
462 | opts.run_ignored = RunIgnored::Only; | |
463 | ||
464 | let tests = one_ignored_one_unignored_test(); | |
465 | let filtered = filter_tests(&opts, tests); | |
466 | ||
467 | assert_eq!(filtered.len(), 1); | |
468 | assert_eq!(filtered[0].desc.name.to_string(), "1"); | |
469 | assert!(!filtered[0].desc.ignore); | |
470 | } | |
471 | ||
472 | #[test] | |
473 | pub fn run_include_ignored_option() { | |
474 | // When we "--include-ignored" tests, the ignore flag should be set to false on | |
475 | // all tests and no test filtered out | |
476 | ||
477 | let mut opts = TestOpts::new(); | |
478 | opts.run_tests = true; | |
479 | opts.run_ignored = RunIgnored::Yes; | |
480 | ||
481 | let tests = one_ignored_one_unignored_test(); | |
482 | let filtered = filter_tests(&opts, tests); | |
483 | ||
484 | assert_eq!(filtered.len(), 2); | |
485 | assert!(!filtered[0].desc.ignore); | |
486 | assert!(!filtered[1].desc.ignore); | |
487 | } | |
488 | ||
489 | #[test] | |
490 | pub fn exclude_should_panic_option() { | |
491 | let mut opts = TestOpts::new(); | |
492 | opts.run_tests = true; | |
493 | opts.exclude_should_panic = true; | |
494 | ||
495 | let mut tests = one_ignored_one_unignored_test(); | |
496 | tests.push(TestDescAndFn { | |
497 | desc: TestDesc { | |
498 | name: StaticTestName("3"), | |
499 | ignore: false, | |
500 | should_panic: ShouldPanic::Yes, | |
501 | allow_fail: false, | |
17df50a5 XL |
502 | #[cfg(not(bootstrap))] |
503 | compile_fail: false, | |
504 | #[cfg(not(bootstrap))] | |
505 | no_run: false, | |
e74abb32 | 506 | test_type: TestType::Unknown, |
dc9dc135 XL |
507 | }, |
508 | testfn: DynTestFn(Box::new(move || {})), | |
509 | }); | |
510 | ||
511 | let filtered = filter_tests(&opts, tests); | |
512 | ||
513 | assert_eq!(filtered.len(), 2); | |
514 | assert!(filtered.iter().all(|test| test.desc.should_panic == ShouldPanic::No)); | |
515 | } | |
516 | ||
517 | #[test] | |
518 | pub fn exact_filter_match() { | |
519 | fn tests() -> Vec<TestDescAndFn> { | |
520 | vec!["base", "base::test", "base::test1", "base::test2"] | |
521 | .into_iter() | |
522 | .map(|name| TestDescAndFn { | |
523 | desc: TestDesc { | |
524 | name: StaticTestName(name), | |
525 | ignore: false, | |
526 | should_panic: ShouldPanic::No, | |
527 | allow_fail: false, | |
17df50a5 XL |
528 | #[cfg(not(bootstrap))] |
529 | compile_fail: false, | |
530 | #[cfg(not(bootstrap))] | |
531 | no_run: false, | |
e74abb32 | 532 | test_type: TestType::Unknown, |
dc9dc135 XL |
533 | }, |
534 | testfn: DynTestFn(Box::new(move || {})), | |
535 | }) | |
536 | .collect() | |
537 | } | |
538 | ||
dfeec247 | 539 | let substr = |
6a06907d | 540 | filter_tests(&TestOpts { filters: vec!["base".into()], ..TestOpts::new() }, tests()); |
dc9dc135 XL |
541 | assert_eq!(substr.len(), 4); |
542 | ||
6a06907d XL |
543 | let substr = |
544 | filter_tests(&TestOpts { filters: vec!["bas".into()], ..TestOpts::new() }, tests()); | |
dc9dc135 XL |
545 | assert_eq!(substr.len(), 4); |
546 | ||
dfeec247 | 547 | let substr = |
6a06907d | 548 | filter_tests(&TestOpts { filters: vec!["::test".into()], ..TestOpts::new() }, tests()); |
dc9dc135 XL |
549 | assert_eq!(substr.len(), 3); |
550 | ||
dfeec247 | 551 | let substr = |
6a06907d | 552 | filter_tests(&TestOpts { filters: vec!["base::test".into()], ..TestOpts::new() }, tests()); |
dc9dc135 XL |
553 | assert_eq!(substr.len(), 3); |
554 | ||
6a06907d XL |
555 | let substr = filter_tests( |
556 | &TestOpts { filters: vec!["test1".into(), "test2".into()], ..TestOpts::new() }, | |
557 | tests(), | |
558 | ); | |
559 | assert_eq!(substr.len(), 2); | |
560 | ||
dc9dc135 | 561 | let exact = filter_tests( |
6a06907d | 562 | &TestOpts { filters: vec!["base".into()], filter_exact: true, ..TestOpts::new() }, |
dc9dc135 XL |
563 | tests(), |
564 | ); | |
565 | assert_eq!(exact.len(), 1); | |
566 | ||
567 | let exact = filter_tests( | |
6a06907d | 568 | &TestOpts { filters: vec!["bas".into()], filter_exact: true, ..TestOpts::new() }, |
dc9dc135 XL |
569 | tests(), |
570 | ); | |
571 | assert_eq!(exact.len(), 0); | |
572 | ||
573 | let exact = filter_tests( | |
6a06907d | 574 | &TestOpts { filters: vec!["::test".into()], filter_exact: true, ..TestOpts::new() }, |
dc9dc135 XL |
575 | tests(), |
576 | ); | |
577 | assert_eq!(exact.len(), 0); | |
578 | ||
579 | let exact = filter_tests( | |
6a06907d | 580 | &TestOpts { filters: vec!["base::test".into()], filter_exact: true, ..TestOpts::new() }, |
dc9dc135 XL |
581 | tests(), |
582 | ); | |
583 | assert_eq!(exact.len(), 1); | |
6a06907d XL |
584 | |
585 | let exact = filter_tests( | |
586 | &TestOpts { | |
587 | filters: vec!["base".into(), "base::test".into()], | |
588 | filter_exact: true, | |
589 | ..TestOpts::new() | |
590 | }, | |
591 | tests(), | |
592 | ); | |
593 | assert_eq!(exact.len(), 2); | |
dc9dc135 XL |
594 | } |
595 | ||
596 | #[test] | |
597 | pub fn sort_tests() { | |
598 | let mut opts = TestOpts::new(); | |
599 | opts.run_tests = true; | |
600 | ||
601 | let names = vec![ | |
602 | "sha1::test".to_string(), | |
603 | "isize::test_to_str".to_string(), | |
604 | "isize::test_pow".to_string(), | |
605 | "test::do_not_run_ignored_tests".to_string(), | |
606 | "test::ignored_tests_result_in_ignored".to_string(), | |
607 | "test::first_free_arg_should_be_a_filter".to_string(), | |
608 | "test::parse_ignored_flag".to_string(), | |
609 | "test::parse_include_ignored_flag".to_string(), | |
610 | "test::filter_for_ignored_option".to_string(), | |
611 | "test::run_include_ignored_option".to_string(), | |
612 | "test::sort_tests".to_string(), | |
613 | ]; | |
614 | let tests = { | |
615 | fn testfn() {} | |
616 | let mut tests = Vec::new(); | |
617 | for name in &names { | |
618 | let test = TestDescAndFn { | |
619 | desc: TestDesc { | |
620 | name: DynTestName((*name).clone()), | |
621 | ignore: false, | |
622 | should_panic: ShouldPanic::No, | |
623 | allow_fail: false, | |
17df50a5 XL |
624 | #[cfg(not(bootstrap))] |
625 | compile_fail: false, | |
626 | #[cfg(not(bootstrap))] | |
627 | no_run: false, | |
e74abb32 | 628 | test_type: TestType::Unknown, |
dc9dc135 XL |
629 | }, |
630 | testfn: DynTestFn(Box::new(testfn)), | |
631 | }; | |
632 | tests.push(test); | |
633 | } | |
634 | tests | |
635 | }; | |
636 | let filtered = filter_tests(&opts, tests); | |
637 | ||
638 | let expected = vec![ | |
639 | "isize::test_pow".to_string(), | |
640 | "isize::test_to_str".to_string(), | |
641 | "sha1::test".to_string(), | |
642 | "test::do_not_run_ignored_tests".to_string(), | |
643 | "test::filter_for_ignored_option".to_string(), | |
644 | "test::first_free_arg_should_be_a_filter".to_string(), | |
645 | "test::ignored_tests_result_in_ignored".to_string(), | |
646 | "test::parse_ignored_flag".to_string(), | |
647 | "test::parse_include_ignored_flag".to_string(), | |
648 | "test::run_include_ignored_option".to_string(), | |
649 | "test::sort_tests".to_string(), | |
650 | ]; | |
651 | ||
652 | for (a, b) in expected.iter().zip(filtered) { | |
60c5eb7d | 653 | assert_eq!(*a, b.desc.name.to_string()); |
dc9dc135 XL |
654 | } |
655 | } | |
656 | ||
657 | #[test] | |
658 | pub fn test_metricmap_compare() { | |
659 | let mut m1 = MetricMap::new(); | |
660 | let mut m2 = MetricMap::new(); | |
661 | m1.insert_metric("in-both-noise", 1000.0, 200.0); | |
662 | m2.insert_metric("in-both-noise", 1100.0, 200.0); | |
663 | ||
664 | m1.insert_metric("in-first-noise", 1000.0, 2.0); | |
665 | m2.insert_metric("in-second-noise", 1000.0, 2.0); | |
666 | ||
667 | m1.insert_metric("in-both-want-downwards-but-regressed", 1000.0, 10.0); | |
668 | m2.insert_metric("in-both-want-downwards-but-regressed", 2000.0, 10.0); | |
669 | ||
670 | m1.insert_metric("in-both-want-downwards-and-improved", 2000.0, 10.0); | |
671 | m2.insert_metric("in-both-want-downwards-and-improved", 1000.0, 10.0); | |
672 | ||
673 | m1.insert_metric("in-both-want-upwards-but-regressed", 2000.0, -10.0); | |
674 | m2.insert_metric("in-both-want-upwards-but-regressed", 1000.0, -10.0); | |
675 | ||
676 | m1.insert_metric("in-both-want-upwards-and-improved", 1000.0, -10.0); | |
677 | m2.insert_metric("in-both-want-upwards-and-improved", 2000.0, -10.0); | |
678 | } | |
679 | ||
680 | #[test] | |
681 | pub fn test_bench_once_no_iter() { | |
682 | fn f(_: &mut Bencher) {} | |
683 | bench::run_once(f); | |
684 | } | |
685 | ||
686 | #[test] | |
687 | pub fn test_bench_once_iter() { | |
688 | fn f(b: &mut Bencher) { | |
689 | b.iter(|| {}) | |
690 | } | |
691 | bench::run_once(f); | |
692 | } | |
693 | ||
694 | #[test] | |
695 | pub fn test_bench_no_iter() { | |
696 | fn f(_: &mut Bencher) {} | |
697 | ||
698 | let (tx, rx) = channel(); | |
699 | ||
700 | let desc = TestDesc { | |
701 | name: StaticTestName("f"), | |
702 | ignore: false, | |
703 | should_panic: ShouldPanic::No, | |
704 | allow_fail: false, | |
17df50a5 XL |
705 | #[cfg(not(bootstrap))] |
706 | compile_fail: false, | |
707 | #[cfg(not(bootstrap))] | |
708 | no_run: false, | |
e74abb32 | 709 | test_type: TestType::Unknown, |
dc9dc135 XL |
710 | }; |
711 | ||
cdc7bbd5 | 712 | crate::bench::benchmark(TestId(0), desc, tx, true, f); |
dc9dc135 XL |
713 | rx.recv().unwrap(); |
714 | } | |
715 | ||
716 | #[test] | |
717 | pub fn test_bench_iter() { | |
718 | fn f(b: &mut Bencher) { | |
719 | b.iter(|| {}) | |
720 | } | |
721 | ||
722 | let (tx, rx) = channel(); | |
723 | ||
724 | let desc = TestDesc { | |
725 | name: StaticTestName("f"), | |
726 | ignore: false, | |
727 | should_panic: ShouldPanic::No, | |
728 | allow_fail: false, | |
17df50a5 XL |
729 | #[cfg(not(bootstrap))] |
730 | compile_fail: false, | |
731 | #[cfg(not(bootstrap))] | |
732 | no_run: false, | |
e74abb32 | 733 | test_type: TestType::Unknown, |
dc9dc135 XL |
734 | }; |
735 | ||
cdc7bbd5 | 736 | crate::bench::benchmark(TestId(0), desc, tx, true, f); |
dc9dc135 XL |
737 | rx.recv().unwrap(); |
738 | } | |
416331ca XL |
739 | |
740 | #[test] | |
741 | fn should_sort_failures_before_printing_them() { | |
742 | let test_a = TestDesc { | |
743 | name: StaticTestName("a"), | |
744 | ignore: false, | |
745 | should_panic: ShouldPanic::No, | |
746 | allow_fail: false, | |
17df50a5 XL |
747 | #[cfg(not(bootstrap))] |
748 | compile_fail: false, | |
749 | #[cfg(not(bootstrap))] | |
750 | no_run: false, | |
e74abb32 | 751 | test_type: TestType::Unknown, |
416331ca XL |
752 | }; |
753 | ||
754 | let test_b = TestDesc { | |
755 | name: StaticTestName("b"), | |
756 | ignore: false, | |
757 | should_panic: ShouldPanic::No, | |
758 | allow_fail: false, | |
17df50a5 XL |
759 | #[cfg(not(bootstrap))] |
760 | compile_fail: false, | |
761 | #[cfg(not(bootstrap))] | |
762 | no_run: false, | |
e74abb32 | 763 | test_type: TestType::Unknown, |
416331ca XL |
764 | }; |
765 | ||
e74abb32 | 766 | let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None); |
416331ca | 767 | |
e74abb32 | 768 | let st = console::ConsoleTestState { |
416331ca XL |
769 | log_out: None, |
770 | total: 0, | |
771 | passed: 0, | |
772 | failed: 0, | |
773 | ignored: 0, | |
774 | allowed_fail: 0, | |
775 | filtered_out: 0, | |
776 | measured: 0, | |
fc512014 | 777 | exec_time: None, |
416331ca XL |
778 | metrics: MetricMap::new(), |
779 | failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], | |
780 | options: Options::new(), | |
781 | not_failures: Vec::new(), | |
e74abb32 | 782 | time_failures: Vec::new(), |
416331ca XL |
783 | }; |
784 | ||
785 | out.write_failures(&st).unwrap(); | |
786 | let s = match out.output_location() { | |
e74abb32 XL |
787 | &OutputLocation::Raw(ref m) => String::from_utf8_lossy(&m[..]), |
788 | &OutputLocation::Pretty(_) => unreachable!(), | |
416331ca XL |
789 | }; |
790 | ||
791 | let apos = s.find("a").unwrap(); | |
792 | let bpos = s.find("b").unwrap(); | |
793 | assert!(apos < bpos); | |
794 | } |