// 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};
}
Json,
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum RunIgnored {
+ Yes,
+ No,
+ Only,
+}
+
#[derive(Debug)]
pub struct TestOpts {
pub list: bool,
pub filter: Option<String>,
pub filter_exact: bool,
- pub run_ignored: bool,
+ pub run_ignored: RunIgnored,
pub run_tests: bool,
pub bench_benchmarks: bool,
pub logfile: Option<PathBuf>,
list: false,
filter: None,
filter_exact: false,
- run_ignored: false,
+ run_ignored: RunIgnored::No,
run_tests: false,
bench_benchmarks: false,
logfile: None,
fn optgroups() -> getopts::Options {
let mut opts = getopts::Options::new();
- opts.optflag("", "ignored", "Run ignored tests")
+ opts.optflag("", "include-ignored", "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")
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 --include-ignored will run
+ these tests."#,
usage = options.usage(&message)
);
}
None
};
- let run_ignored = matches.opt_present("ignored");
+ let include_ignored = matches.opt_present("include-ignored");
+ if !allow_unstable && include_ignored {
+ return Some(Err(
+ "The \"include-ignored\" flag is only accepted on the nightly compiler".into()
+ ));
+ }
+
+ let run_ignored = match (include_ignored, matches.opt_present("ignored")) {
+ (true, true) => return Some(Err(
+ "the options --include-ignored 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");
}
}
-#[cfg(any(target_os = "cloudabi", target_os = "redox",
- all(target_arch = "wasm32", not(target_os = "emscripten"))))]
+#[cfg(any(target_os = "cloudabi",
+ target_os = "redox",
+ all(target_arch = "wasm32", not(target_os = "emscripten")),
+ target_env = "sgx"))]
fn stdout_isatty() -> bool {
- // FIXME: Implement isatty on Redox
+ // FIXME: Implement isatty on Redox and SGX
false
}
#[cfg(unix)]
1
}
- #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
+ #[cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), target_env = "sgx"))]
fn num_cpus() -> usize {
1
}
pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
let mut filtered = tests;
- // Remove tests that don't match the test filter
- filtered = match opts.filter {
- None => filtered,
- Some(ref filter) => filtered
- .into_iter()
- .filter(|test| {
- if opts.filter_exact {
- test.desc.name.as_slice() == &filter[..]
- } else {
- test.desc.name.as_slice().contains(&filter[..])
- }
- })
- .collect(),
+ let matches_filter = |test: &TestDescAndFn, filter: &str| {
+ let test_name = test.desc.name.as_slice();
+
+ match opts.filter_exact {
+ true => test_name == filter,
+ false => test_name.contains(filter),
+ }
};
- // Skip tests that match any of the skip filters
- filtered = filtered
- .into_iter()
- .filter(|t| {
- !opts.skip.iter().any(|sf| {
- if opts.filter_exact {
- t.desc.name.as_slice() == &sf[..]
- } else {
- t.desc.name.as_slice().contains(&sf[..])
- }
- })
- })
- .collect();
+ // Remove tests that don't match the test filter
+ if let Some(ref filter) = opts.filter {
+ filtered.retain(|test| matches_filter(test, filter));
+ }
- // Maybe pull out the ignored test and unignore them
- filtered = if !opts.run_ignored {
- filtered
- } else {
- fn filter(test: TestDescAndFn) -> Option<TestDescAndFn> {
- if test.desc.ignore {
- let TestDescAndFn { desc, testfn } = test;
- Some(TestDescAndFn {
- desc: TestDesc {
- ignore: false,
- ..desc
- },
- testfn,
- })
- } else {
- None
- }
+ // Skip tests that match any of the skip filters
+ filtered.retain(|test| {
+ !opts.skip.iter().any(|sf| matches_filter(test, sf))
+ });
+
+ // maybe unignore tests
+ match opts.run_ignored {
+ RunIgnored::Yes => {
+ 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);
}
- filtered.into_iter().filter_map(filter).collect()
- };
+ RunIgnored::No => {}
+ }
// Sort the tests alphabetically
filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice()));
#[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<TestDescAndFn> {
+ 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() {
"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_include_ignored_flag() {
+ let args = vec![
+ "progname".to_string(),
+ "filter".to_string(),
+ "-Zunstable-options".to_string(),
+ "--include-ignored".to_string(),
+ ];
+ let opts = parse_opts(&args).unwrap().unwrap();
+ assert_eq!(opts.run_ignored, RunIgnored::Yes);
}
#[test]
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);
assert!(!filtered[0].desc.ignore);
}
+ #[test]
+ pub fn run_include_ignored_option() {
+ // When we "--include-ignored" 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<TestDescAndFn> {
"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_include_ignored_flag".to_string(),
"test::filter_for_ignored_option".to_string(),
+ "test::run_include_ignored_option".to_string(),
"test::sort_tests".to_string(),
];
let tests = {
"test::first_free_arg_should_be_a_filter".to_string(),
"test::ignored_tests_result_in_ignored".to_string(),
"test::parse_ignored_flag".to_string(),
+ "test::parse_include_ignored_flag".to_string(),
+ "test::run_include_ignored_option".to_string(),
"test::sort_tests".to_string(),
];