From 9adf26a5d09fcdbc423c2134fc0ef20dc3375f2e Mon Sep 17 00:00:00 2001 From: Emerentius Date: Mon, 20 Aug 2018 13:57:10 +0200 Subject: [PATCH] add option to run all tests add --all flag to libtest that runs ignored and not ignored tests --- src/libtest/lib.rs | 142 ++++++++++++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 46 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 5a0663f776b78..71207e8e408d1 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -80,7 +80,7 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu // to be used by rustc to compile tests in libtest pub mod test { pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, - Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, ShouldPanic, + Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic, StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}; } @@ -348,12 +348,19 @@ pub enum OutputFormat { Json, } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum RunIgnored { + Yes, + No, + Only, +} + #[derive(Debug)] pub struct TestOpts { pub list: bool, pub filter: Option, pub filter_exact: bool, - pub run_ignored: bool, + pub run_ignored: RunIgnored, pub run_tests: bool, pub bench_benchmarks: bool, pub logfile: Option, @@ -372,7 +379,7 @@ impl TestOpts { list: false, filter: None, filter_exact: false, - run_ignored: false, + run_ignored: RunIgnored::No, run_tests: false, bench_benchmarks: false, logfile: None, @@ -391,7 +398,8 @@ pub type OptRes = Result; fn optgroups() -> getopts::Options { let mut opts = getopts::Options::new(); - opts.optflag("", "ignored", "Run ignored tests") + opts.optflag("", "all", "Run ignored and not ignored tests") + .optflag("", "ignored", "Run only ignored tests") .optflag("", "test", "Run tests and not benchmarks") .optflag("", "bench", "Run benchmarks instead of tests") .optflag("", "list", "List all tests and benchmarks") @@ -490,8 +498,8 @@ Test Attributes: contain: #[should_panic(expected = "foo")]. #[ignore] - When applied to a function which is already attributed as a test, then the test runner will ignore these tests during - normal test runs. Running with --ignored will run these - tests."#, + normal test runs. Running with --ignored or --all will run + these tests."#, usage = options.usage(&message) ); } @@ -544,7 +552,14 @@ pub fn parse_opts(args: &[String]) -> Option { None }; - let run_ignored = matches.opt_present("ignored"); + let run_ignored = match (matches.opt_present("all"), matches.opt_present("ignored")) { + (true, true) => return Some(Err( + "the options --all and --ignored are mutually exclusive".into() + )), + (true, false) => RunIgnored::Yes, + (false, true) => RunIgnored::Only, + (false, false) => RunIgnored::No, + }; let quiet = matches.opt_present("quiet"); let exact = matches.opt_present("exact"); let list = matches.opt_present("list"); @@ -1315,16 +1330,17 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec { + filtered.iter_mut().for_each(|test| test.desc.ignore = false); + }, + RunIgnored::Only => { + filtered.retain(|test| test.desc.ignore); + filtered.iter_mut().for_each(|test| test.desc.ignore = false); + } + RunIgnored::No => {} + } // Sort the tests alphabetically filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice())); @@ -1713,13 +1729,37 @@ pub mod bench { #[cfg(test)] mod tests { - use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, ShouldPanic, - StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, - TrIgnored, TrOk}; + use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, + ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, + TrFailedMsg, TrIgnored, TrOk}; use std::sync::mpsc::channel; use bench; use Bencher; + + fn one_ignored_one_unignored_test() -> Vec { + vec![ + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("1"), + ignore: true, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("2"), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + ] + } + #[test] pub fn do_not_run_ignored_tests() { fn f() { @@ -1845,11 +1885,19 @@ mod tests { "filter".to_string(), "--ignored".to_string(), ]; - let opts = match parse_opts(&args) { - Some(Ok(o)) => o, - _ => panic!("Malformed arg in parse_ignored_flag"), - }; - assert!((opts.run_ignored)); + let opts = parse_opts(&args).unwrap().unwrap(); + assert_eq!(opts.run_ignored, RunIgnored::Only); + } + + #[test] + fn parse_all_flag() { + let args = vec![ + "progname".to_string(), + "filter".to_string(), + "--all".to_string(), + ]; + let opts = parse_opts(&args).unwrap().unwrap(); + assert_eq!(opts.run_ignored, RunIgnored::Yes); } #[test] @@ -1859,28 +1907,9 @@ mod tests { let mut opts = TestOpts::new(); opts.run_tests = true; - opts.run_ignored = true; + opts.run_ignored = RunIgnored::Only; - let tests = vec![ - TestDescAndFn { - desc: TestDesc { - name: StaticTestName("1"), - ignore: true, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }, - TestDescAndFn { - desc: TestDesc { - name: StaticTestName("2"), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }, - ]; + let tests = one_ignored_one_unignored_test(); let filtered = filter_tests(&opts, tests); assert_eq!(filtered.len(), 1); @@ -1888,6 +1917,23 @@ mod tests { assert!(!filtered[0].desc.ignore); } + #[test] + pub fn run_all_option() { + // When we run "--all" tests, the ignore flag should be set to false on + // all tests and no test filtered out + + let mut opts = TestOpts::new(); + opts.run_tests = true; + opts.run_ignored = RunIgnored::Yes; + + let tests = one_ignored_one_unignored_test(); + let filtered = filter_tests(&opts, tests); + + assert_eq!(filtered.len(), 2); + assert!(!filtered[0].desc.ignore); + assert!(!filtered[1].desc.ignore); + } + #[test] pub fn exact_filter_match() { fn tests() -> Vec { @@ -1995,7 +2041,9 @@ mod tests { "test::ignored_tests_result_in_ignored".to_string(), "test::first_free_arg_should_be_a_filter".to_string(), "test::parse_ignored_flag".to_string(), + "test::parse_all_flag".to_string(), "test::filter_for_ignored_option".to_string(), + "test::run_all_option".to_string(), "test::sort_tests".to_string(), ]; let tests = { @@ -2025,7 +2073,9 @@ mod tests { "test::filter_for_ignored_option".to_string(), "test::first_free_arg_should_be_a_filter".to_string(), "test::ignored_tests_result_in_ignored".to_string(), + "test::parse_all_flag".to_string(), "test::parse_ignored_flag".to_string(), + "test::run_all_option".to_string(), "test::sort_tests".to_string(), ];