mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-12-09 02:55:12 +00:00
17470 - run test explorer tests at the package level and add missing extra_test_bin_args settings
This commit is contained in:
parent
a46788318c
commit
20d3237dfa
3 changed files with 54 additions and 10 deletions
|
|
@ -24,7 +24,7 @@ pub mod project_json;
|
||||||
mod test_runner;
|
mod test_runner;
|
||||||
|
|
||||||
use command::{CommandHandle, ParseFromLine};
|
use command::{CommandHandle, ParseFromLine};
|
||||||
pub use test_runner::{CargoTestHandle, CargoTestMessage, TestState};
|
pub use test_runner::{CargoTestHandle, CargoTestMessage, TestState, TestTarget};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub enum InvocationStrategy {
|
pub enum InvocationStrategy {
|
||||||
|
|
|
||||||
|
|
@ -59,19 +59,38 @@ pub struct CargoTestHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example of a cargo test command:
|
// Example of a cargo test command:
|
||||||
// cargo test --workspace --no-fail-fast -- module::func -Z unstable-options --format=json
|
// cargo test --workspace --no-fail-fast -- -Z unstable-options --format=json
|
||||||
|
// or
|
||||||
|
// cargo test --package my-package --no-fail-fast -- module::func -Z unstable-options --format=json
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TestTarget {
|
||||||
|
Workspace,
|
||||||
|
Package(String),
|
||||||
|
}
|
||||||
|
|
||||||
impl CargoTestHandle {
|
impl CargoTestHandle {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
path: Option<&str>,
|
path: Option<&str>,
|
||||||
options: CargoOptions,
|
options: CargoOptions,
|
||||||
root: &AbsPath,
|
root: &AbsPath,
|
||||||
|
test_target: TestTarget,
|
||||||
sender: Sender<CargoTestMessage>,
|
sender: Sender<CargoTestMessage>,
|
||||||
) -> std::io::Result<Self> {
|
) -> std::io::Result<Self> {
|
||||||
let mut cmd = Command::new(Tool::Cargo.path());
|
let mut cmd = Command::new(Tool::Cargo.path());
|
||||||
cmd.env("RUSTC_BOOTSTRAP", "1");
|
cmd.env("RUSTC_BOOTSTRAP", "1");
|
||||||
cmd.arg("test");
|
cmd.arg("test");
|
||||||
cmd.arg("--workspace");
|
|
||||||
|
match &test_target {
|
||||||
|
TestTarget::Package(package) => {
|
||||||
|
cmd.arg("--package");
|
||||||
|
cmd.arg(package);
|
||||||
|
}
|
||||||
|
TestTarget::Workspace => {
|
||||||
|
cmd.arg("--workspace");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// --no-fail-fast is needed to ensure that all requested tests will run
|
// --no-fail-fast is needed to ensure that all requested tests will run
|
||||||
cmd.arg("--no-fail-fast");
|
cmd.arg("--no-fail-fast");
|
||||||
cmd.arg("--manifest-path");
|
cmd.arg("--manifest-path");
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use lsp_types::{
|
||||||
SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
|
SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
|
||||||
};
|
};
|
||||||
use paths::Utf8PathBuf;
|
use paths::Utf8PathBuf;
|
||||||
use project_model::{ManifestPath, ProjectWorkspaceKind, TargetKind};
|
use project_model::{CargoWorkspace, ManifestPath, ProjectWorkspaceKind, TargetKind};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use stdx::{format_to, never};
|
use stdx::{format_to, never};
|
||||||
use syntax::{algo, ast, AstNode, TextRange, TextSize};
|
use syntax::{algo, ast, AstNode, TextRange, TextSize};
|
||||||
|
|
@ -199,6 +199,20 @@ pub(crate) fn handle_view_item_tree(
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cargo test requires the real package name which might contain hyphens but
|
||||||
|
// the test identifier passed to this function is the namespace form where hyphens
|
||||||
|
// are replaced with underscores so we have to reverse this and find the real package name
|
||||||
|
fn find_package_name(namespace_root: &str, cargo: &CargoWorkspace) -> Option<String> {
|
||||||
|
cargo.packages().find_map(|p| {
|
||||||
|
let package_name = &cargo[p].name;
|
||||||
|
if package_name.replace('-', "_") == namespace_root {
|
||||||
|
Some(package_name.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_run_test(
|
pub(crate) fn handle_run_test(
|
||||||
state: &mut GlobalState,
|
state: &mut GlobalState,
|
||||||
params: lsp_ext::RunTestParams,
|
params: lsp_ext::RunTestParams,
|
||||||
|
|
@ -206,7 +220,7 @@ pub(crate) fn handle_run_test(
|
||||||
if let Some(_session) = state.test_run_session.take() {
|
if let Some(_session) = state.test_run_session.take() {
|
||||||
state.send_notification::<lsp_ext::EndRunTest>(());
|
state.send_notification::<lsp_ext::EndRunTest>(());
|
||||||
}
|
}
|
||||||
// We detect the lowest common ansector of all included tests, and
|
// We detect the lowest common ancestor of all included tests, and
|
||||||
// run it. We ignore excluded tests for now, the client will handle
|
// run it. We ignore excluded tests for now, the client will handle
|
||||||
// it for us.
|
// it for us.
|
||||||
let lca = match params.include {
|
let lca = match params.include {
|
||||||
|
|
@ -225,20 +239,31 @@ pub(crate) fn handle_run_test(
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
None => "".to_owned(),
|
None => "".to_owned(),
|
||||||
};
|
};
|
||||||
let test_path = if lca.is_empty() {
|
let (namespace_root, test_path) = if lca.is_empty() {
|
||||||
None
|
(None, None)
|
||||||
} else if let Some((_, path)) = lca.split_once("::") {
|
} else if let Some((namespace_root, path)) = lca.split_once("::") {
|
||||||
Some(path)
|
(Some(namespace_root), Some(path))
|
||||||
} else {
|
} else {
|
||||||
None
|
(Some(lca.as_str()), None)
|
||||||
};
|
};
|
||||||
let mut handles = vec![];
|
let mut handles = vec![];
|
||||||
for ws in &*state.workspaces {
|
for ws in &*state.workspaces {
|
||||||
if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind {
|
if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind {
|
||||||
|
let test_target = if let Some(namespace_root) = namespace_root {
|
||||||
|
if let Some(package_name) = find_package_name(namespace_root, cargo) {
|
||||||
|
flycheck::TestTarget::Package(package_name)
|
||||||
|
} else {
|
||||||
|
flycheck::TestTarget::Workspace
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
flycheck::TestTarget::Workspace
|
||||||
|
};
|
||||||
|
|
||||||
let handle = flycheck::CargoTestHandle::new(
|
let handle = flycheck::CargoTestHandle::new(
|
||||||
test_path,
|
test_path,
|
||||||
state.config.cargo_test_options(),
|
state.config.cargo_test_options(),
|
||||||
cargo.workspace_root(),
|
cargo.workspace_root(),
|
||||||
|
test_target,
|
||||||
state.test_run_sender.clone(),
|
state.test_run_sender.clone(),
|
||||||
)?;
|
)?;
|
||||||
handles.push(handle);
|
handles.push(handle);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue