From 9138c35d8cbd035fddd3a231424f390a83cfaa8a Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 20 Jan 2022 11:30:55 +0800 Subject: [PATCH] Extract logic of all test target filter to `all_test_targets` --- src/bin/cargo/commands/test.rs | 16 ++++++---------- src/cargo/ops/cargo_compile.rs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index c03bc915f6f..cb35ab5aeeb 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -105,16 +105,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { FilterRule::none(), FilterRule::none(), ); - } else if test_name.is_some() { - if let CompileFilter::Default { .. } = compile_opts.filter { - compile_opts.filter = ops::CompileFilter::new( - LibRule::Default, // compile the library, so the unit tests can be run filtered - FilterRule::none(), // binaries without `test = false` are included by default - FilterRule::All, // compile the tests, so the integration tests can be run filtered - FilterRule::none(), // specify --examples to unit test binaries filtered - FilterRule::none(), // specify --benches to unit test benchmarks filtered - ); // also, specify --doc to run doc tests filtered - } + } else if test_name.is_some() && !compile_opts.filter.is_specific() { + // If arg `TESTNAME` is provided, assumed that the user knows what + // exactly they wants to test, so we use `all_test_targets` to + // avoid compiling unnecessary targets such as examples, which are + // included by the logic of default target filter. + compile_opts.filter = ops::CompileFilter::all_test_targets(); } let ops = ops::TestOptions { diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index a21cf4f429b..11ff38b6a1b 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -828,6 +828,25 @@ impl CompileFilter { } } + /// Constructs a filter that includes all test targets. + /// + /// Being different from the behavior of [`CompileFilter::Default`], this + /// function only recongnizes test targets, which means cargo might compile + /// all targets with `tested` flag on, whereas [`CompileFilter::Default`] + /// may include additional example targets to ensure they can be compiled. + /// + /// Note that the actual behavior is subject to `filter_default_targets` + /// and `generate_targets` though. + pub fn all_test_targets() -> Self { + Self::Only { + all_targets: false, + lib: LibRule::Default, + bins: FilterRule::none(), + examples: FilterRule::none(), + tests: FilterRule::All, + benches: FilterRule::none(), + } + } pub fn need_dev_deps(&self, mode: CompileMode) -> bool { match mode { CompileMode::Test | CompileMode::Doctest | CompileMode::Bench => true,