Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #19571 from duncanawoods/19464-Regression-vs-code-test-explorer-skips-unit-tests-since-v0.3.2353
Fix missing test update notifications when there are hyphens in the target name and exclude dependencies from `Run All`
| -rw-r--r-- | crates/rust-analyzer/src/handlers/request.rs | 48 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 4 |
2 files changed, 22 insertions, 30 deletions
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 7427a3bbaa..27114fef87 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -195,6 +195,8 @@ pub(crate) fn handle_view_item_tree( } // cargo test requires: +// - the package is a member of the workspace +// - the target in the package is not a build script (custom-build) // - the package name - the root of the test identifier supplied to this handler can be // a package or a target inside a package. // - the target name - if the test identifier is a target, it's needed in addition to the @@ -202,38 +204,26 @@ pub(crate) fn handle_view_item_tree( // - real names - the test identifier uses the namespace form where hyphens are replaced with // underscores. cargo test requires the real name. // - the target kind e.g. bin or lib -fn find_test_target(namespace_root: &str, cargo: &CargoWorkspace) -> Option<TestTarget> { - cargo.packages().find_map(|p| { - let package_name = &cargo[p].name; - for target in cargo[p].targets.iter() { - let target_name = &cargo[*target].name; - if target_name.replace('-', "_") == namespace_root { - return Some(TestTarget { - package: package_name.clone(), - target: target_name.clone(), - kind: cargo[*target].kind, - }); +fn all_test_targets(cargo: &CargoWorkspace) -> impl Iterator<Item = TestTarget> { + cargo.packages().filter(|p| cargo[*p].is_member).flat_map(|p| { + let package = &cargo[p]; + package.targets.iter().filter_map(|t| { + let target = &cargo[*t]; + if target.kind == TargetKind::BuildScript { + None + } else { + Some(TestTarget { + package: package.name.clone(), + target: target.name.clone(), + kind: target.kind, + }) } - } - None + }) }) } -fn get_all_targets(cargo: &CargoWorkspace) -> Vec<TestTarget> { - cargo - .packages() - .flat_map(|p| { - let package_name = &cargo[p].name; - cargo[p].targets.iter().map(|target| { - let target_name = &cargo[*target].name; - TestTarget { - package: package_name.clone(), - target: target_name.clone(), - kind: cargo[*target].kind, - } - }) - }) - .collect() +fn find_test_target(namespace_root: &str, cargo: &CargoWorkspace) -> Option<TestTarget> { + all_test_targets(cargo).find(|t| namespace_root == t.target.replace('-', "_")) } pub(crate) fn handle_run_test( @@ -265,7 +255,7 @@ pub(crate) fn handle_run_test( } }) .collect_vec(), - None => get_all_targets(cargo).into_iter().map(|target| (target, None)).collect(), + None => all_test_targets(cargo).map(|target| (target, None)).collect(), }; for (target, path) in tests { diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 930c499c5f..bd213ffa57 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -969,7 +969,9 @@ impl GlobalState { TestState::Ok => lsp_ext::TestState::Passed, TestState::Failed { stdout } => lsp_ext::TestState::Failed { message: stdout }, }; - let test_id = format!("{}::{name}", message.target.target); + + // The notification requires the namespace form (with underscores) of the target + let test_id = format!("{}::{name}", message.target.target.replace('-', "_")); self.send_notification::<lsp_ext::ChangeTestState>( lsp_ext::ChangeTestStateParams { test_id, state }, |