9595: Show test mod runnable in outline modules r=Veykril a=Veykril

This shows a runnable inside outline test modules at the top of its file:
![image](https://user-images.githubusercontent.com/3757771/125494747-169c9238-3faa-4eed-9700-90bd730b4e3c.png)


Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-07-15 00:20:44 +00:00 committed by GitHub
commit 95d85336df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 155 additions and 6 deletions

View file

@ -16,7 +16,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
use stdx::{always, format_to};
use syntax::ast::{self, AstNode, AttrsOwner};
use crate::{display::TryToNav, references, FileId, NavigationTarget};
use crate::{
display::{ToNav, TryToNav},
references, FileId, NavigationTarget,
};
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Runnable {
@ -176,6 +179,10 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
}
});
sema.to_module_defs(file_id)
.map(|it| runnable_mod_outline_definition(&sema, it))
.for_each(|it| add_opt(it, None));
res.extend(in_macro_expansion.into_iter().flat_map(|(_, runnables)| {
let use_name_in_title = runnables.len() != 1;
runnables.into_iter().map(move |mut r| {
@ -351,6 +358,30 @@ pub(crate) fn runnable_impl(sema: &Semantics<RootDatabase>, def: &hir::Impl) ->
Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg })
}
/// Creates a test mod runnable for outline modules at the top of their definition.
fn runnable_mod_outline_definition(
sema: &Semantics<RootDatabase>,
def: hir::Module,
) -> Option<Runnable> {
if !has_test_function_or_multiple_test_submodules(sema, &def) {
return None;
}
let path =
def.path_to_root(sema.db).into_iter().rev().filter_map(|it| it.name(sema.db)).join("::");
let attrs = def.attrs(sema.db);
let cfg = attrs.cfg();
match def.definition_source(sema.db).value {
hir::ModuleSource::SourceFile(_) => Some(Runnable {
use_name_in_title: false,
nav: def.to_nav(sema.db),
kind: RunnableKind::TestMod { path },
cfg,
}),
_ => None,
}
}
fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {
let attrs = match def {
hir::ModuleDef::Module(it) => it.attrs(sema.db),
@ -541,7 +572,7 @@ mod not_a_root {
fn main() {}
}
"#,
&[Bin, Test, Test, Bench],
&[Bin, Test, Test, Bench, TestMod],
expect![[r#"
[
Runnable {
@ -618,6 +649,21 @@ mod not_a_root {
},
cfg: None,
},
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 0..137,
name: "",
kind: Module,
},
kind: TestMod {
path: "",
},
cfg: None,
},
]
"#]],
);
@ -1143,7 +1189,7 @@ $0
#[cfg(feature = "foo")]
fn test_foo1() {}
"#,
&[Test],
&[Test, TestMod],
expect![[r#"
[
Runnable {
@ -1174,6 +1220,21 @@ fn test_foo1() {}
),
),
},
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 0..51,
name: "",
kind: Module,
},
kind: TestMod {
path: "",
},
cfg: None,
},
]
"#]],
);
@ -1189,7 +1250,7 @@ $0
#[cfg(all(feature = "foo", feature = "bar"))]
fn test_foo1() {}
"#,
&[Test],
&[Test, TestMod],
expect![[r#"
[
Runnable {
@ -1230,6 +1291,21 @@ fn test_foo1() {}
),
),
},
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 0..73,
name: "",
kind: Module,
},
kind: TestMod {
path: "",
},
cfg: None,
},
]
"#]],
);
@ -1316,7 +1392,7 @@ mod tests {
}
gen2!();
"#,
&[TestMod, TestMod, Test, Test],
&[TestMod, TestMod, TestMod, Test, Test],
expect![[r#"
[
Runnable {
@ -1336,6 +1412,21 @@ gen2!();
},
cfg: None,
},
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 0..237,
name: "",
kind: Module,
},
kind: TestMod {
path: "",
},
cfg: None,
},
Runnable {
use_name_in_title: true,
nav: NavigationTarget {
@ -1579,7 +1670,7 @@ fn t0() {}
#[test]
fn t1() {}
"#,
&[Test, Test],
&[Test, Test, TestMod],
expect![[r#"
[
Runnable {
@ -1624,6 +1715,21 @@ fn t1() {}
},
cfg: None,
},
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
1,
),
full_range: 0..39,
name: "m",
kind: Module,
},
kind: TestMod {
path: "m",
},
cfg: None,
},
]
"#]],
);

View file

@ -133,6 +133,49 @@ fn main() {}
"targetUri": "file:///[..]/tests/spam.rs"
}
},
{
"args": {
"overrideCargo": null,
"workspaceRoot": server.path().join("foo"),
"cargoArgs": [
"test",
"--package",
"foo",
"--test",
"spam"
],
"cargoExtraArgs": [],
"executableArgs": [
"",
"--nocapture"
]
},
"kind": "cargo",
"label": "test-mod ",
"location": {
"targetUri": "file:///[..]/tests/spam.rs",
"targetRange": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 0
}
},
"targetSelectionRange": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 0
}
}
},
},
{
"args": {
"cargoArgs": ["check", "--package", "foo", "--all-targets"],