Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/test_explorer.rs')
-rw-r--r--crates/ide/src/test_explorer.rs68
1 files changed, 62 insertions, 6 deletions
diff --git a/crates/ide/src/test_explorer.rs b/crates/ide/src/test_explorer.rs
index ca47139970..99e2430860 100644
--- a/crates/ide/src/test_explorer.rs
+++ b/crates/ide/src/test_explorer.rs
@@ -7,7 +7,7 @@ use ide_db::{
};
use syntax::TextRange;
-use crate::{navigation_target::ToNav, runnables::runnable_fn, Runnable, TryToNav};
+use crate::{runnables::runnable_fn, NavigationTarget, Runnable, TryToNav};
#[derive(Debug)]
pub enum TestItemKind {
@@ -56,7 +56,12 @@ fn find_crate_by_id(crate_graph: &CrateGraph, crate_id: &str) -> Option<CrateId>
})
}
-fn discover_tests_in_module(db: &RootDatabase, module: Module, prefix_id: String) -> Vec<TestItem> {
+fn discover_tests_in_module(
+ db: &RootDatabase,
+ module: Module,
+ prefix_id: String,
+ only_in_this_file: bool,
+) -> Vec<TestItem> {
let sema = Semantics::new(db);
let mut r = vec![];
@@ -64,9 +69,9 @@ fn discover_tests_in_module(db: &RootDatabase, module: Module, prefix_id: String
let module_name =
c.name(db).as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]").to_owned();
let module_id = format!("{prefix_id}::{module_name}");
- let module_children = discover_tests_in_module(db, c, module_id.clone());
+ let module_children = discover_tests_in_module(db, c, module_id.clone(), only_in_this_file);
if !module_children.is_empty() {
- let nav = c.to_nav(db).call_site;
+ let nav = NavigationTarget::from_module_to_decl(sema.db, c).call_site;
r.push(TestItem {
id: module_id,
kind: TestItemKind::Module,
@@ -76,7 +81,9 @@ fn discover_tests_in_module(db: &RootDatabase, module: Module, prefix_id: String
text_range: Some(nav.focus_or_full_range()),
runnable: None,
});
- r.extend(module_children);
+ if !only_in_this_file || c.is_inline(db) {
+ r.extend(module_children);
+ }
}
}
for def in module.declarations(db) {
@@ -112,6 +119,55 @@ pub(crate) fn discover_tests_in_crate_by_test_id(
discover_tests_in_crate(db, crate_id)
}
+pub(crate) fn discover_tests_in_file(db: &RootDatabase, file_id: FileId) -> Vec<TestItem> {
+ let sema = Semantics::new(db);
+
+ let Some(module) = sema.file_to_module_def(file_id) else { return vec![] };
+ let Some((mut tests, id)) = find_module_id_and_test_parents(&sema, module) else {
+ return vec![];
+ };
+ tests.extend(discover_tests_in_module(db, module, id, true));
+ tests
+}
+
+fn find_module_id_and_test_parents(
+ sema: &Semantics<'_, RootDatabase>,
+ module: Module,
+) -> Option<(Vec<TestItem>, String)> {
+ let Some(parent) = module.parent(sema.db) else {
+ let name = module.krate().display_name(sema.db)?.to_string();
+ return Some((
+ vec![TestItem {
+ id: name.clone(),
+ kind: TestItemKind::Crate(module.krate().into()),
+ label: name.clone(),
+ parent: None,
+ file: None,
+ text_range: None,
+ runnable: None,
+ }],
+ name,
+ ));
+ };
+ let (mut r, mut id) = find_module_id_and_test_parents(sema, parent)?;
+ let parent = Some(id.clone());
+ id += "::";
+ let module_name = &module.name(sema.db);
+ let module_name = module_name.as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]");
+ id += module_name;
+ let nav = NavigationTarget::from_module_to_decl(sema.db, module).call_site;
+ r.push(TestItem {
+ id: id.clone(),
+ kind: TestItemKind::Module,
+ label: module_name.to_owned(),
+ parent,
+ file: Some(nav.file_id),
+ text_range: Some(nav.focus_or_full_range()),
+ runnable: None,
+ });
+ Some((r, id))
+}
+
pub(crate) fn discover_tests_in_crate(db: &RootDatabase, crate_id: CrateId) -> Vec<TestItem> {
let crate_graph = db.crate_graph();
if !crate_graph[crate_id].origin.is_local() {
@@ -133,6 +189,6 @@ pub(crate) fn discover_tests_in_crate(db: &RootDatabase, crate_id: CrateId) -> V
text_range: None,
runnable: None,
}];
- r.extend(discover_tests_in_module(db, module, crate_test_id));
+ r.extend(discover_tests_in_module(db, module, crate_test_id, false));
r
}