@@ -89,7 +89,7 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu
8989// to be used by rustc to compile tests in libtest
9090pub mod test {
9191 pub use { assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
92- Bencher , DynTestFn , DynTestName , Metric , MetricMap , Options , ShouldPanic ,
92+ Bencher , DynTestFn , DynTestName , Metric , MetricMap , Options , RunIgnored , ShouldPanic ,
9393 StaticBenchFn , StaticTestFn , StaticTestName , TestDesc , TestDescAndFn , TestName ,
9494 TestOpts , TestResult , TrFailed , TrFailedMsg , TrIgnored , TrOk } ;
9595}
@@ -357,12 +357,19 @@ pub enum OutputFormat {
357357 Json ,
358358}
359359
360+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
361+ pub enum RunIgnored {
362+ Yes ,
363+ No ,
364+ Only ,
365+ }
366+
360367#[ derive( Debug ) ]
361368pub struct TestOpts {
362369 pub list : bool ,
363370 pub filter : Option < String > ,
364371 pub filter_exact : bool ,
365- pub run_ignored : bool ,
372+ pub run_ignored : RunIgnored ,
366373 pub run_tests : bool ,
367374 pub bench_benchmarks : bool ,
368375 pub logfile : Option < PathBuf > ,
@@ -381,7 +388,7 @@ impl TestOpts {
381388 list : false ,
382389 filter : None ,
383390 filter_exact : false ,
384- run_ignored : false ,
391+ run_ignored : RunIgnored :: No ,
385392 run_tests : false ,
386393 bench_benchmarks : false ,
387394 logfile : None ,
@@ -400,7 +407,8 @@ pub type OptRes = Result<TestOpts, String>;
400407
401408fn optgroups ( ) -> getopts:: Options {
402409 let mut opts = getopts:: Options :: new ( ) ;
403- opts. optflag ( "" , "ignored" , "Run ignored tests" )
410+ opts. optflag ( "" , "include-ignored" , "Run ignored and not ignored tests" )
411+ . optflag ( "" , "ignored" , "Run only ignored tests" )
404412 . optflag ( "" , "test" , "Run tests and not benchmarks" )
405413 . optflag ( "" , "bench" , "Run benchmarks instead of tests" )
406414 . optflag ( "" , "list" , "List all tests and benchmarks" )
@@ -499,8 +507,8 @@ Test Attributes:
499507 contain: #[should_panic(expected = "foo")].
500508 #[ignore] - When applied to a function which is already attributed as a
501509 test, then the test runner will ignore these tests during
502- normal test runs. Running with --ignored will run these
503- tests."# ,
510+ normal test runs. Running with --ignored or --include-ignored will run
511+ these tests."# ,
504512 usage = options. usage( & message)
505513 ) ;
506514}
@@ -553,7 +561,21 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
553561 None
554562 } ;
555563
556- let run_ignored = matches. opt_present ( "ignored" ) ;
564+ let include_ignored = matches. opt_present ( "include-ignored" ) ;
565+ if !allow_unstable && include_ignored {
566+ return Some ( Err (
567+ "The \" include-ignored\" flag is only accepted on the nightly compiler" . into ( )
568+ ) ) ;
569+ }
570+
571+ let run_ignored = match ( include_ignored, matches. opt_present ( "ignored" ) ) {
572+ ( true , true ) => return Some ( Err (
573+ "the options --include-ignored and --ignored are mutually exclusive" . into ( )
574+ ) ) ,
575+ ( true , false ) => RunIgnored :: Yes ,
576+ ( false , true ) => RunIgnored :: Only ,
577+ ( false , false ) => RunIgnored :: No ,
578+ } ;
557579 let quiet = matches. opt_present ( "quiet" ) ;
558580 let exact = matches. opt_present ( "exact" ) ;
559581 let list = matches. opt_present ( "list" ) ;
@@ -1324,16 +1346,17 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
13241346 !opts. skip . iter ( ) . any ( |sf| matches_filter ( test, sf) )
13251347 } ) ;
13261348
1327- // Maybe pull out the ignored test and unignore them
1328- if opts. run_ignored {
1329- filtered = filtered. into_iter ( )
1330- . filter ( |test| test. desc . ignore )
1331- . map ( |mut test| {
1332- test. desc . ignore = false ;
1333- test
1334- } )
1335- . collect ( ) ;
1336- } ;
1349+ // maybe unignore tests
1350+ match opts. run_ignored {
1351+ RunIgnored :: Yes => {
1352+ filtered. iter_mut ( ) . for_each ( |test| test. desc . ignore = false ) ;
1353+ } ,
1354+ RunIgnored :: Only => {
1355+ filtered. retain ( |test| test. desc . ignore ) ;
1356+ filtered. iter_mut ( ) . for_each ( |test| test. desc . ignore = false ) ;
1357+ }
1358+ RunIgnored :: No => { }
1359+ }
13371360
13381361 // Sort the tests alphabetically
13391362 filtered. sort_by ( |t1, t2| t1. desc . name . as_slice ( ) . cmp ( t2. desc . name . as_slice ( ) ) ) ;
@@ -1722,13 +1745,37 @@ pub mod bench {
17221745
17231746#[ cfg( test) ]
17241747mod tests {
1725- use test:: { filter_tests, parse_opts, run_test, DynTestFn , DynTestName , MetricMap , ShouldPanic ,
1726- StaticTestName , TestDesc , TestDescAndFn , TestOpts , TrFailed , TrFailedMsg ,
1727- TrIgnored , TrOk } ;
1748+ use test:: { filter_tests, parse_opts, run_test, DynTestFn , DynTestName , MetricMap , RunIgnored ,
1749+ ShouldPanic , StaticTestName , TestDesc , TestDescAndFn , TestOpts , TrFailed ,
1750+ TrFailedMsg , TrIgnored , TrOk } ;
17281751 use std:: sync:: mpsc:: channel;
17291752 use bench;
17301753 use Bencher ;
17311754
1755+
1756+ fn one_ignored_one_unignored_test ( ) -> Vec < TestDescAndFn > {
1757+ vec ! [
1758+ TestDescAndFn {
1759+ desc: TestDesc {
1760+ name: StaticTestName ( "1" ) ,
1761+ ignore: true ,
1762+ should_panic: ShouldPanic :: No ,
1763+ allow_fail: false ,
1764+ } ,
1765+ testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1766+ } ,
1767+ TestDescAndFn {
1768+ desc: TestDesc {
1769+ name: StaticTestName ( "2" ) ,
1770+ ignore: false ,
1771+ should_panic: ShouldPanic :: No ,
1772+ allow_fail: false ,
1773+ } ,
1774+ testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1775+ } ,
1776+ ]
1777+ }
1778+
17321779 #[ test]
17331780 pub fn do_not_run_ignored_tests ( ) {
17341781 fn f ( ) {
@@ -1854,11 +1901,20 @@ mod tests {
18541901 "filter" . to_string( ) ,
18551902 "--ignored" . to_string( ) ,
18561903 ] ;
1857- let opts = match parse_opts ( & args) {
1858- Some ( Ok ( o) ) => o,
1859- _ => panic ! ( "Malformed arg in parse_ignored_flag" ) ,
1860- } ;
1861- assert ! ( ( opts. run_ignored) ) ;
1904+ let opts = parse_opts ( & args) . unwrap ( ) . unwrap ( ) ;
1905+ assert_eq ! ( opts. run_ignored, RunIgnored :: Only ) ;
1906+ }
1907+
1908+ #[ test]
1909+ fn parse_include_ignored_flag ( ) {
1910+ let args = vec ! [
1911+ "progname" . to_string( ) ,
1912+ "filter" . to_string( ) ,
1913+ "-Zunstable-options" . to_string( ) ,
1914+ "--include-ignored" . to_string( ) ,
1915+ ] ;
1916+ let opts = parse_opts ( & args) . unwrap ( ) . unwrap ( ) ;
1917+ assert_eq ! ( opts. run_ignored, RunIgnored :: Yes ) ;
18621918 }
18631919
18641920 #[ test]
@@ -1868,35 +1924,33 @@ mod tests {
18681924
18691925 let mut opts = TestOpts :: new ( ) ;
18701926 opts. run_tests = true ;
1871- opts. run_ignored = true ;
1927+ opts. run_ignored = RunIgnored :: Only ;
18721928
1873- let tests = vec ! [
1874- TestDescAndFn {
1875- desc: TestDesc {
1876- name: StaticTestName ( "1" ) ,
1877- ignore: true ,
1878- should_panic: ShouldPanic :: No ,
1879- allow_fail: false ,
1880- } ,
1881- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1882- } ,
1883- TestDescAndFn {
1884- desc: TestDesc {
1885- name: StaticTestName ( "2" ) ,
1886- ignore: false ,
1887- should_panic: ShouldPanic :: No ,
1888- allow_fail: false ,
1889- } ,
1890- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1891- } ,
1892- ] ;
1929+ let tests = one_ignored_one_unignored_test ( ) ;
18931930 let filtered = filter_tests ( & opts, tests) ;
18941931
18951932 assert_eq ! ( filtered. len( ) , 1 ) ;
18961933 assert_eq ! ( filtered[ 0 ] . desc. name. to_string( ) , "1" ) ;
18971934 assert ! ( !filtered[ 0 ] . desc. ignore) ;
18981935 }
18991936
1937+ #[ test]
1938+ pub fn run_include_ignored_option ( ) {
1939+ // When we "--include-ignored" tests, the ignore flag should be set to false on
1940+ // all tests and no test filtered out
1941+
1942+ let mut opts = TestOpts :: new ( ) ;
1943+ opts. run_tests = true ;
1944+ opts. run_ignored = RunIgnored :: Yes ;
1945+
1946+ let tests = one_ignored_one_unignored_test ( ) ;
1947+ let filtered = filter_tests ( & opts, tests) ;
1948+
1949+ assert_eq ! ( filtered. len( ) , 2 ) ;
1950+ assert ! ( !filtered[ 0 ] . desc. ignore) ;
1951+ assert ! ( !filtered[ 1 ] . desc. ignore) ;
1952+ }
1953+
19001954 #[ test]
19011955 pub fn exact_filter_match ( ) {
19021956 fn tests ( ) -> Vec < TestDescAndFn > {
@@ -2004,7 +2058,9 @@ mod tests {
20042058 "test::ignored_tests_result_in_ignored" . to_string( ) ,
20052059 "test::first_free_arg_should_be_a_filter" . to_string( ) ,
20062060 "test::parse_ignored_flag" . to_string( ) ,
2061+ "test::parse_include_ignored_flag" . to_string( ) ,
20072062 "test::filter_for_ignored_option" . to_string( ) ,
2063+ "test::run_include_ignored_option" . to_string( ) ,
20082064 "test::sort_tests" . to_string( ) ,
20092065 ] ;
20102066 let tests = {
@@ -2035,6 +2091,8 @@ mod tests {
20352091 "test::first_free_arg_should_be_a_filter" . to_string( ) ,
20362092 "test::ignored_tests_result_in_ignored" . to_string( ) ,
20372093 "test::parse_ignored_flag" . to_string( ) ,
2094+ "test::parse_include_ignored_flag" . to_string( ) ,
2095+ "test::run_include_ignored_option" . to_string( ) ,
20382096 "test::sort_tests" . to_string( ) ,
20392097 ] ;
20402098
0 commit comments