@@ -89,7 +89,7 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu
89
89
// to be used by rustc to compile tests in libtest
90
90
pub mod test {
91
91
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 ,
93
93
StaticBenchFn , StaticTestFn , StaticTestName , TestDesc , TestDescAndFn , TestName ,
94
94
TestOpts , TestResult , TrFailed , TrFailedMsg , TrIgnored , TrOk } ;
95
95
}
@@ -357,12 +357,19 @@ pub enum OutputFormat {
357
357
Json ,
358
358
}
359
359
360
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
361
+ pub enum RunIgnored {
362
+ Yes ,
363
+ No ,
364
+ Only ,
365
+ }
366
+
360
367
#[ derive( Debug ) ]
361
368
pub struct TestOpts {
362
369
pub list : bool ,
363
370
pub filter : Option < String > ,
364
371
pub filter_exact : bool ,
365
- pub run_ignored : bool ,
372
+ pub run_ignored : RunIgnored ,
366
373
pub run_tests : bool ,
367
374
pub bench_benchmarks : bool ,
368
375
pub logfile : Option < PathBuf > ,
@@ -381,7 +388,7 @@ impl TestOpts {
381
388
list : false ,
382
389
filter : None ,
383
390
filter_exact : false ,
384
- run_ignored : false ,
391
+ run_ignored : RunIgnored :: No ,
385
392
run_tests : false ,
386
393
bench_benchmarks : false ,
387
394
logfile : None ,
@@ -400,7 +407,8 @@ pub type OptRes = Result<TestOpts, String>;
400
407
401
408
fn optgroups ( ) -> getopts:: Options {
402
409
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" )
404
412
. optflag ( "" , "test" , "Run tests and not benchmarks" )
405
413
. optflag ( "" , "bench" , "Run benchmarks instead of tests" )
406
414
. optflag ( "" , "list" , "List all tests and benchmarks" )
@@ -499,8 +507,8 @@ Test Attributes:
499
507
contain: #[should_panic(expected = "foo")].
500
508
#[ignore] - When applied to a function which is already attributed as a
501
509
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."# ,
504
512
usage = options. usage( & message)
505
513
) ;
506
514
}
@@ -553,7 +561,21 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
553
561
None
554
562
} ;
555
563
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
+ } ;
557
579
let quiet = matches. opt_present ( "quiet" ) ;
558
580
let exact = matches. opt_present ( "exact" ) ;
559
581
let list = matches. opt_present ( "list" ) ;
@@ -1305,55 +1327,36 @@ fn get_concurrency() -> usize {
1305
1327
1306
1328
pub fn filter_tests ( opts : & TestOpts , tests : Vec < TestDescAndFn > ) -> Vec < TestDescAndFn > {
1307
1329
let mut filtered = tests;
1308
- // Remove tests that don't match the test filter
1309
- filtered = match opts. filter {
1310
- None => filtered,
1311
- Some ( ref filter) => filtered
1312
- . into_iter ( )
1313
- . filter ( |test| {
1314
- if opts. filter_exact {
1315
- test. desc . name . as_slice ( ) == & filter[ ..]
1316
- } else {
1317
- test. desc . name . as_slice ( ) . contains ( & filter[ ..] )
1318
- }
1319
- } )
1320
- . collect ( ) ,
1330
+ let matches_filter = |test : & TestDescAndFn , filter : & str | {
1331
+ let test_name = test. desc . name . as_slice ( ) ;
1332
+
1333
+ match opts. filter_exact {
1334
+ true => test_name == filter,
1335
+ false => test_name. contains ( filter) ,
1336
+ }
1321
1337
} ;
1322
1338
1323
- // Skip tests that match any of the skip filters
1324
- filtered = filtered
1325
- . into_iter ( )
1326
- . filter ( |t| {
1327
- !opts. skip . iter ( ) . any ( |sf| {
1328
- if opts. filter_exact {
1329
- t. desc . name . as_slice ( ) == & sf[ ..]
1330
- } else {
1331
- t. desc . name . as_slice ( ) . contains ( & sf[ ..] )
1332
- }
1333
- } )
1334
- } )
1335
- . collect ( ) ;
1339
+ // Remove tests that don't match the test filter
1340
+ if let Some ( ref filter) = opts. filter {
1341
+ filtered. retain ( |test| matches_filter ( test, filter) ) ;
1342
+ }
1336
1343
1337
- // Maybe pull out the ignored test and unignore them
1338
- filtered = if !opts. run_ignored {
1339
- filtered
1340
- } else {
1341
- fn filter ( test : TestDescAndFn ) -> Option < TestDescAndFn > {
1342
- if test. desc . ignore {
1343
- let TestDescAndFn { desc, testfn } = test;
1344
- Some ( TestDescAndFn {
1345
- desc : TestDesc {
1346
- ignore : false ,
1347
- ..desc
1348
- } ,
1349
- testfn,
1350
- } )
1351
- } else {
1352
- None
1353
- }
1344
+ // Skip tests that match any of the skip filters
1345
+ filtered. retain ( |test| {
1346
+ !opts. skip . iter ( ) . any ( |sf| matches_filter ( test, sf) )
1347
+ } ) ;
1348
+
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 ) ;
1354
1357
}
1355
- filtered . into_iter ( ) . filter_map ( filter ) . collect ( )
1356
- } ;
1358
+ RunIgnored :: No => { }
1359
+ }
1357
1360
1358
1361
// Sort the tests alphabetically
1359
1362
filtered. sort_by ( |t1, t2| t1. desc . name . as_slice ( ) . cmp ( t2. desc . name . as_slice ( ) ) ) ;
@@ -1742,13 +1745,37 @@ pub mod bench {
1742
1745
1743
1746
#[ cfg( test) ]
1744
1747
mod tests {
1745
- use test:: { filter_tests, parse_opts, run_test, DynTestFn , DynTestName , MetricMap , ShouldPanic ,
1746
- StaticTestName , TestDesc , TestDescAndFn , TestOpts , TrFailed , TrFailedMsg ,
1747
- 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 } ;
1748
1751
use std:: sync:: mpsc:: channel;
1749
1752
use bench;
1750
1753
use Bencher ;
1751
1754
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
+
1752
1779
#[ test]
1753
1780
pub fn do_not_run_ignored_tests ( ) {
1754
1781
fn f ( ) {
@@ -1874,11 +1901,20 @@ mod tests {
1874
1901
"filter" . to_string( ) ,
1875
1902
"--ignored" . to_string( ) ,
1876
1903
] ;
1877
- let opts = match parse_opts ( & args) {
1878
- Some ( Ok ( o) ) => o,
1879
- _ => panic ! ( "Malformed arg in parse_ignored_flag" ) ,
1880
- } ;
1881
- 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 ) ;
1882
1918
}
1883
1919
1884
1920
#[ test]
@@ -1888,35 +1924,33 @@ mod tests {
1888
1924
1889
1925
let mut opts = TestOpts :: new ( ) ;
1890
1926
opts. run_tests = true ;
1891
- opts. run_ignored = true ;
1927
+ opts. run_ignored = RunIgnored :: Only ;
1892
1928
1893
- let tests = vec ! [
1894
- TestDescAndFn {
1895
- desc: TestDesc {
1896
- name: StaticTestName ( "1" ) ,
1897
- ignore: true ,
1898
- should_panic: ShouldPanic :: No ,
1899
- allow_fail: false ,
1900
- } ,
1901
- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1902
- } ,
1903
- TestDescAndFn {
1904
- desc: TestDesc {
1905
- name: StaticTestName ( "2" ) ,
1906
- ignore: false ,
1907
- should_panic: ShouldPanic :: No ,
1908
- allow_fail: false ,
1909
- } ,
1910
- testfn: DynTestFn ( Box :: new( move || { } ) ) ,
1911
- } ,
1912
- ] ;
1929
+ let tests = one_ignored_one_unignored_test ( ) ;
1913
1930
let filtered = filter_tests ( & opts, tests) ;
1914
1931
1915
1932
assert_eq ! ( filtered. len( ) , 1 ) ;
1916
1933
assert_eq ! ( filtered[ 0 ] . desc. name. to_string( ) , "1" ) ;
1917
1934
assert ! ( !filtered[ 0 ] . desc. ignore) ;
1918
1935
}
1919
1936
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
+
1920
1954
#[ test]
1921
1955
pub fn exact_filter_match ( ) {
1922
1956
fn tests ( ) -> Vec < TestDescAndFn > {
@@ -2024,7 +2058,9 @@ mod tests {
2024
2058
"test::ignored_tests_result_in_ignored" . to_string( ) ,
2025
2059
"test::first_free_arg_should_be_a_filter" . to_string( ) ,
2026
2060
"test::parse_ignored_flag" . to_string( ) ,
2061
+ "test::parse_include_ignored_flag" . to_string( ) ,
2027
2062
"test::filter_for_ignored_option" . to_string( ) ,
2063
+ "test::run_include_ignored_option" . to_string( ) ,
2028
2064
"test::sort_tests" . to_string( ) ,
2029
2065
] ;
2030
2066
let tests = {
@@ -2055,6 +2091,8 @@ mod tests {
2055
2091
"test::first_free_arg_should_be_a_filter" . to_string( ) ,
2056
2092
"test::ignored_tests_result_in_ignored" . to_string( ) ,
2057
2093
"test::parse_ignored_flag" . to_string( ) ,
2094
+ "test::parse_include_ignored_flag" . to_string( ) ,
2095
+ "test::run_include_ignored_option" . to_string( ) ,
2058
2096
"test::sort_tests" . to_string( ) ,
2059
2097
] ;
2060
2098
0 commit comments