@@ -81,7 +81,7 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu
81
81
// to be used by rustc to compile tests in libtest
82
82
pub mod test {
83
83
pub use { assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
84
- Bencher , DynTestFn , DynTestName , Metric , MetricMap , Options , ShouldPanic ,
84
+ Bencher , DynTestFn , DynTestName , Metric , MetricMap , Options , RunIgnored , ShouldPanic ,
85
85
StaticBenchFn , StaticTestFn , StaticTestName , TestDesc , TestDescAndFn , TestName ,
86
86
TestOpts , TestResult , TrFailed , TrFailedMsg , TrIgnored , TrOk } ;
87
87
}
@@ -349,12 +349,19 @@ pub enum OutputFormat {
349
349
Json ,
350
350
}
351
351
352
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
353
+ pub enum RunIgnored {
354
+ Yes ,
355
+ No ,
356
+ Only ,
357
+ }
358
+
352
359
#[ derive( Debug ) ]
353
360
pub struct TestOpts {
354
361
pub list : bool ,
355
362
pub filter : Option < String > ,
356
363
pub filter_exact : bool ,
357
- pub run_ignored : bool ,
364
+ pub run_ignored : RunIgnored ,
358
365
pub run_tests : bool ,
359
366
pub bench_benchmarks : bool ,
360
367
pub logfile : Option < PathBuf > ,
@@ -373,7 +380,7 @@ impl TestOpts {
373
380
list : false ,
374
381
filter : None ,
375
382
filter_exact : false ,
376
- run_ignored : false ,
383
+ run_ignored : RunIgnored :: No ,
377
384
run_tests : false ,
378
385
bench_benchmarks : false ,
379
386
logfile : None ,
@@ -392,7 +399,8 @@ pub type OptRes = Result<TestOpts, String>;
392
399
393
400
fn optgroups ( ) -> getopts:: Options {
394
401
let mut opts = getopts:: Options :: new ( ) ;
395
- opts. optflag ( "" , "ignored" , "Run ignored tests" )
402
+ opts. optflag ( "" , "include-ignored" , "Run ignored and not ignored tests" )
403
+ . optflag ( "" , "ignored" , "Run only ignored tests" )
396
404
. optflag ( "" , "test" , "Run tests and not benchmarks" )
397
405
. optflag ( "" , "bench" , "Run benchmarks instead of tests" )
398
406
. optflag ( "" , "list" , "List all tests and benchmarks" )
@@ -491,8 +499,8 @@ Test Attributes:
491
499
contain: #[should_panic(expected = "foo")].
492
500
#[ignore] - When applied to a function which is already attributed as a
493
501
test, then the test runner will ignore these tests during
494
- normal test runs. Running with --ignored will run these
495
- tests."# ,
502
+ normal test runs. Running with --ignored or --include-ignored will run
503
+ these tests."# ,
496
504
usage = options. usage( & message)
497
505
) ;
498
506
}
@@ -545,7 +553,21 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
545
553
None
546
554
} ;
547
555
548
- let run_ignored = matches. opt_present ( "ignored" ) ;
556
+ let include_ignored = matches. opt_present ( "include-ignored" ) ;
557
+ if !allow_unstable && include_ignored {
558
+ return Some ( Err (
559
+ "The \" include-ignored\" flag is only accepted on the nightly compiler" . into ( )
560
+ ) ) ;
561
+ }
562
+
563
+ let run_ignored = match ( include_ignored, matches. opt_present ( "ignored" ) ) {
564
+ ( true , true ) => return Some ( Err (
565
+ "the options --include-ignored and --ignored are mutually exclusive" . into ( )
566
+ ) ) ,
567
+ ( true , false ) => RunIgnored :: Yes ,
568
+ ( false , true ) => RunIgnored :: Only ,
569
+ ( false , false ) => RunIgnored :: No ,
570
+ } ;
549
571
let quiet = matches. opt_present ( "quiet" ) ;
550
572
let exact = matches. opt_present ( "exact" ) ;
551
573
let list = matches. opt_present ( "list" ) ;
@@ -1297,55 +1319,36 @@ fn get_concurrency() -> usize {
1297
1319
1298
1320
pub fn filter_tests ( opts : & TestOpts , tests : Vec < TestDescAndFn > ) -> Vec < TestDescAndFn > {
1299
1321
let mut filtered = tests;
1300
- // Remove tests that don't match the test filter
1301
- filtered = match opts. filter {
1302
- None => filtered,
1303
- Some ( ref filter) => filtered
1304
- . into_iter ( )
1305
- . filter ( |test| {
1306
- if opts. filter_exact {
1307
- test. desc . name . as_slice ( ) == & filter[ ..]
1308
- } else {
1309
- test. desc . name . as_slice ( ) . contains ( & filter[ ..] )
1310
- }
1311
- } )
1312
- . collect ( ) ,
1322
+ let matches_filter = |test : & TestDescAndFn , filter : & str | {
1323
+ let test_name = test. desc . name . as_slice ( ) ;
1324
+
1325
+ match opts. filter_exact {
1326
+ true => test_name == filter,
1327
+ false => test_name. contains ( filter) ,
1328
+ }
1313
1329
} ;
1314
1330
1315
- // Skip tests that match any of the skip filters
1316
- filtered = filtered
1317
- . into_iter ( )
1318
- . filter ( |t| {
1319
- !opts. skip . iter ( ) . any ( |sf| {
1320
- if opts. filter_exact {
1321
- t. desc . name . as_slice ( ) == & sf[ ..]
1322
- } else {
1323
- t. desc . name . as_slice ( ) . contains ( & sf[ ..] )
1324
- }
1325
- } )
1326
- } )
1327
- . collect ( ) ;
1331
+ // Remove tests that don't match the test filter
1332
+ if let Some ( ref filter) = opts. filter {
1333
+ filtered. retain ( |test| matches_filter ( test, filter) ) ;
1334
+ }
1328
1335
1329
- // Maybe pull out the ignored test and unignore them
1330
- filtered = if !opts. run_ignored {
1331
- filtered
1332
- } else {
1333
- fn filter ( test : TestDescAndFn ) -> Option < TestDescAndFn > {
1334
- if test. desc . ignore {
1335
- let TestDescAndFn { desc, testfn } = test;
1336
- Some ( TestDescAndFn {
1337
- desc : TestDesc {
1338
- ignore : false ,
1339
- ..desc
1340
- } ,
1341
- testfn,
1342
- } )
1343
- } else {
1344
- None
1345
- }
1336
+ // Skip tests that match any of the skip filters
1337
+ filtered. retain ( |test| {
1338
+ !opts. skip . iter ( ) . any ( |sf| matches_filter ( test, sf) )
1339
+ } ) ;
1340
+
1341
+ // maybe unignore tests
1342
+ match opts. run_ignored {
1343
+ RunIgnored :: Yes => {
1344
+ filtered. iter_mut ( ) . for_each ( |test| test. desc . ignore = false ) ;
1345
+ } ,
1346
+ RunIgnored :: Only => {
1347
+ filtered. retain ( |test| test. desc . ignore ) ;
1348
+ filtered. iter_mut ( ) . for_each ( |test| test. desc . ignore = false ) ;
1346
1349
}
1347
- filtered . into_iter ( ) . filter_map ( filter ) . collect ( )
1348
- } ;
1350
+ RunIgnored :: No => { }
1351
+ }
1349
1352
1350
1353
// Sort the tests alphabetically
1351
1354
filtered. sort_by ( |t1, t2| t1. desc . name . as_slice ( ) . cmp ( t2. desc . name . as_slice ( ) ) ) ;
@@ -1734,13 +1737,37 @@ pub mod bench {
1734
1737
1735
1738
#[ cfg( test) ]
1736
1739
mod tests {
1737
- use test:: { filter_tests, parse_opts, run_test, DynTestFn , DynTestName , MetricMap , ShouldPanic ,
1738
- StaticTestName , TestDesc , TestDescAndFn , TestOpts , TrFailed , TrFailedMsg ,
1739
- TrIgnored , TrOk } ;
1740
+ use test:: { filter_tests, parse_opts, run_test, DynTestFn , DynTestName , MetricMap , RunIgnored ,
1741
+ ShouldPanic , StaticTestName , TestDesc , TestDescAndFn , TestOpts , TrFailed ,
1742
+ TrFailedMsg , TrIgnored , TrOk } ;
1740
1743
use std:: sync:: mpsc:: channel;
1741
1744
use bench;
1742
1745
use Bencher ;
1743
1746
1747
+
1748
+ fn one_ignored_one_unignored_test ( ) -> Vec < TestDescAndFn > {
1749
+ vec ! [
1750
+ TestDescAndFn {
1751
+ desc: TestDesc {
1752
+ name: StaticTestName ( "1" ) ,
1753
+ ignore: true ,
1754
+ should_panic: ShouldPanic :: No ,
1755
+ allow_fail: false ,
1756
+ } ,
1757
+ testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1758
+ } ,
1759
+ TestDescAndFn {
1760
+ desc: TestDesc {
1761
+ name: StaticTestName ( "2" ) ,
1762
+ ignore: false ,
1763
+ should_panic: ShouldPanic :: No ,
1764
+ allow_fail: false ,
1765
+ } ,
1766
+ testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1767
+ } ,
1768
+ ]
1769
+ }
1770
+
1744
1771
#[ test]
1745
1772
pub fn do_not_run_ignored_tests ( ) {
1746
1773
fn f ( ) {
@@ -1866,11 +1893,20 @@ mod tests {
1866
1893
"filter" . to_string( ) ,
1867
1894
"--ignored" . to_string( ) ,
1868
1895
] ;
1869
- let opts = match parse_opts ( & args) {
1870
- Some ( Ok ( o) ) => o,
1871
- _ => panic ! ( "Malformed arg in parse_ignored_flag" ) ,
1872
- } ;
1873
- assert ! ( ( opts. run_ignored) ) ;
1896
+ let opts = parse_opts ( & args) . unwrap ( ) . unwrap ( ) ;
1897
+ assert_eq ! ( opts. run_ignored, RunIgnored :: Only ) ;
1898
+ }
1899
+
1900
+ #[ test]
1901
+ fn parse_include_ignored_flag ( ) {
1902
+ let args = vec ! [
1903
+ "progname" . to_string( ) ,
1904
+ "filter" . to_string( ) ,
1905
+ "-Zunstable-options" . to_string( ) ,
1906
+ "--include-ignored" . to_string( ) ,
1907
+ ] ;
1908
+ let opts = parse_opts ( & args) . unwrap ( ) . unwrap ( ) ;
1909
+ assert_eq ! ( opts. run_ignored, RunIgnored :: Yes ) ;
1874
1910
}
1875
1911
1876
1912
#[ test]
@@ -1880,35 +1916,33 @@ mod tests {
1880
1916
1881
1917
let mut opts = TestOpts :: new ( ) ;
1882
1918
opts. run_tests = true ;
1883
- opts. run_ignored = true ;
1919
+ opts. run_ignored = RunIgnored :: Only ;
1884
1920
1885
- let tests = vec ! [
1886
- TestDescAndFn {
1887
- desc: TestDesc {
1888
- name: StaticTestName ( "1" ) ,
1889
- ignore: true ,
1890
- should_panic: ShouldPanic :: No ,
1891
- allow_fail: false ,
1892
- } ,
1893
- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1894
- } ,
1895
- TestDescAndFn {
1896
- desc: TestDesc {
1897
- name: StaticTestName ( "2" ) ,
1898
- ignore: false ,
1899
- should_panic: ShouldPanic :: No ,
1900
- allow_fail: false ,
1901
- } ,
1902
- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1903
- } ,
1904
- ] ;
1921
+ let tests = one_ignored_one_unignored_test ( ) ;
1905
1922
let filtered = filter_tests ( & opts, tests) ;
1906
1923
1907
1924
assert_eq ! ( filtered. len( ) , 1 ) ;
1908
1925
assert_eq ! ( filtered[ 0 ] . desc. name. to_string( ) , "1" ) ;
1909
1926
assert ! ( !filtered[ 0 ] . desc. ignore) ;
1910
1927
}
1911
1928
1929
+ #[ test]
1930
+ pub fn run_include_ignored_option ( ) {
1931
+ // When we "--include-ignored" tests, the ignore flag should be set to false on
1932
+ // all tests and no test filtered out
1933
+
1934
+ let mut opts = TestOpts :: new ( ) ;
1935
+ opts. run_tests = true ;
1936
+ opts. run_ignored = RunIgnored :: Yes ;
1937
+
1938
+ let tests = one_ignored_one_unignored_test ( ) ;
1939
+ let filtered = filter_tests ( & opts, tests) ;
1940
+
1941
+ assert_eq ! ( filtered. len( ) , 2 ) ;
1942
+ assert ! ( !filtered[ 0 ] . desc. ignore) ;
1943
+ assert ! ( !filtered[ 1 ] . desc. ignore) ;
1944
+ }
1945
+
1912
1946
#[ test]
1913
1947
pub fn exact_filter_match ( ) {
1914
1948
fn tests ( ) -> Vec < TestDescAndFn > {
@@ -2016,7 +2050,9 @@ mod tests {
2016
2050
"test::ignored_tests_result_in_ignored" . to_string( ) ,
2017
2051
"test::first_free_arg_should_be_a_filter" . to_string( ) ,
2018
2052
"test::parse_ignored_flag" . to_string( ) ,
2053
+ "test::parse_include_ignored_flag" . to_string( ) ,
2019
2054
"test::filter_for_ignored_option" . to_string( ) ,
2055
+ "test::run_include_ignored_option" . to_string( ) ,
2020
2056
"test::sort_tests" . to_string( ) ,
2021
2057
] ;
2022
2058
let tests = {
@@ -2047,6 +2083,8 @@ mod tests {
2047
2083
"test::first_free_arg_should_be_a_filter" . to_string( ) ,
2048
2084
"test::ignored_tests_result_in_ignored" . to_string( ) ,
2049
2085
"test::parse_ignored_flag" . to_string( ) ,
2086
+ "test::parse_include_ignored_flag" . to_string( ) ,
2087
+ "test::run_include_ignored_option" . to_string( ) ,
2050
2088
"test::sort_tests" . to_string( ) ,
2051
2089
] ;
2052
2090
0 commit comments