Merge pull request #20639 from ChayimFriedman2/update-test-abs

fix: Resolve paths to snapshot test libraries absolutely
This commit is contained in:
David Barsky 2025-09-09 17:16:50 +00:00 committed by GitHub
commit bc6e592fb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 85 additions and 23 deletions

View File

@ -10569,6 +10569,77 @@ macro_rules! str {
); );
} }
#[test]
fn test_runnables_with_snapshot_tests_indirect_dep() {
check_actions(
r#"
//- /lib.rs crate:foo deps:utils
use utils::expect_test::expect;
#[test]
fn test$0() {
let actual = "new25";
expect!["new25"].assert_eq(&actual);
}
//- /expect-test/lib.rs crate:expect_test
struct Expect;
impl Expect {
fn assert_eq(&self, actual: &str) {}
}
#[macro_export]
macro_rules! expect {
($e:expr) => Expect; // dummy
}
//- /utils/lib.rs crate:utils deps:expect_test
pub use expect_test;
"#,
expect![[r#"
[
Reference(
FilePositionWrapper {
file_id: FileId(
0,
),
offset: 44,
},
),
Runnable(
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 33..121,
focus_range: 44..48,
name: "test",
kind: Function,
},
kind: Test {
test_id: Path(
"test",
),
attr: TestAttr {
ignore: false,
},
},
cfg: None,
update_test: UpdateTest {
expect_test: true,
insta: false,
snapbox: false,
},
},
),
]
"#]],
);
}
#[test] #[test]
fn drop_glue() { fn drop_glue() {
check( check(

View File

@ -4,8 +4,8 @@ use arrayvec::ArrayVec;
use ast::HasName; use ast::HasName;
use cfg::{CfgAtom, CfgExpr}; use cfg::{CfgAtom, CfgExpr};
use hir::{ use hir::{
AsAssocItem, AttrsWithOwner, HasAttrs, HasCrate, HasSource, ModPath, Name, PathKind, Semantics, AsAssocItem, AttrsWithOwner, HasAttrs, HasCrate, HasSource, Semantics, Symbol, db::HirDatabase,
Symbol, db::HirDatabase, sym, sym,
}; };
use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn};
use ide_db::{ use ide_db::{
@ -352,8 +352,7 @@ pub(crate) fn runnable_fn(
.call_site(); .call_site();
let file_range = fn_source.syntax().original_file_range_with_macro_call_input(sema.db); let file_range = fn_source.syntax().original_file_range_with_macro_call_input(sema.db);
let update_test = let update_test = UpdateTest::find_snapshot_macro(sema, file_range);
UpdateTest::find_snapshot_macro(sema, &fn_source.file_syntax(sema.db), file_range);
let cfg = def.attrs(sema.db).cfg(); let cfg = def.attrs(sema.db).cfg();
Some(Runnable { use_name_in_title: false, nav, kind, cfg, update_test }) Some(Runnable { use_name_in_title: false, nav, kind, cfg, update_test })
@ -388,7 +387,7 @@ pub(crate) fn runnable_mod(
file_id: module_source.file_id.original_file(sema.db), file_id: module_source.file_id.original_file(sema.db),
range: module_syntax.text_range(), range: module_syntax.text_range(),
}; };
let update_test = UpdateTest::find_snapshot_macro(sema, &module_syntax, file_range); let update_test = UpdateTest::find_snapshot_macro(sema, file_range);
Some(Runnable { Some(Runnable {
use_name_in_title: false, use_name_in_title: false,
@ -428,8 +427,7 @@ pub(crate) fn runnable_impl(
let impl_source = sema.source(*def)?; let impl_source = sema.source(*def)?;
let impl_syntax = impl_source.syntax(); let impl_syntax = impl_source.syntax();
let file_range = impl_syntax.original_file_range_with_macro_call_input(sema.db); let file_range = impl_syntax.original_file_range_with_macro_call_input(sema.db);
let update_test = let update_test = UpdateTest::find_snapshot_macro(sema, file_range);
UpdateTest::find_snapshot_macro(sema, &impl_syntax.file_syntax(sema.db), file_range);
Some(Runnable { Some(Runnable {
use_name_in_title: false, use_name_in_title: false,
@ -475,7 +473,7 @@ fn runnable_mod_outline_definition(
file_id: mod_source.file_id.original_file(sema.db), file_id: mod_source.file_id.original_file(sema.db),
range: mod_syntax.text_range(), range: mod_syntax.text_range(),
}; };
let update_test = UpdateTest::find_snapshot_macro(sema, &mod_syntax, file_range); let update_test = UpdateTest::find_snapshot_macro(sema, file_range);
Some(Runnable { Some(Runnable {
use_name_in_title: false, use_name_in_title: false,
@ -641,7 +639,7 @@ pub struct UpdateTest {
pub snapbox: bool, pub snapbox: bool,
} }
static SNAPSHOT_TEST_MACROS: OnceLock<FxHashMap<&str, Vec<ModPath>>> = OnceLock::new(); static SNAPSHOT_TEST_MACROS: OnceLock<FxHashMap<&str, Vec<[Symbol; 2]>>> = OnceLock::new();
impl UpdateTest { impl UpdateTest {
const EXPECT_CRATE: &str = "expect_test"; const EXPECT_CRATE: &str = "expect_test";
@ -665,22 +663,17 @@ impl UpdateTest {
const SNAPBOX_CRATE: &str = "snapbox"; const SNAPBOX_CRATE: &str = "snapbox";
const SNAPBOX_MACROS: &[&str] = &["assert_data_eq", "file", "str"]; const SNAPBOX_MACROS: &[&str] = &["assert_data_eq", "file", "str"];
fn find_snapshot_macro( fn find_snapshot_macro(sema: &Semantics<'_, RootDatabase>, file_range: hir::FileRange) -> Self {
sema: &Semantics<'_, RootDatabase>,
scope: &SyntaxNode,
file_range: hir::FileRange,
) -> Self {
fn init<'a>( fn init<'a>(
krate_name: &'a str, krate_name: &'a str,
paths: &[&str], paths: &[&str],
map: &mut FxHashMap<&'a str, Vec<ModPath>>, map: &mut FxHashMap<&'a str, Vec<[Symbol; 2]>>,
) { ) {
let mut res = Vec::with_capacity(paths.len()); let mut res = Vec::with_capacity(paths.len());
let krate = Name::new_symbol_root(Symbol::intern(krate_name)); let krate = Symbol::intern(krate_name);
for path in paths { for path in paths {
let segments = [krate.clone(), Name::new_symbol_root(Symbol::intern(path))]; let segments = [krate.clone(), Symbol::intern(path)];
let mod_path = ModPath::from_segments(PathKind::Abs, segments); res.push(segments);
res.push(mod_path);
} }
map.insert(krate_name, res); map.insert(krate_name, res);
} }
@ -694,11 +687,9 @@ impl UpdateTest {
}); });
let search_scope = SearchScope::file_range(file_range); let search_scope = SearchScope::file_range(file_range);
let find_macro = |paths: &[ModPath]| { let find_macro = |paths: &[[Symbol; 2]]| {
for path in paths { for path in paths {
let Some(items) = sema.resolve_mod_path(scope, path) else { let items = hir::resolve_absolute_path(sema.db, path.iter().cloned());
continue;
};
for item in items { for item in items {
if let hir::ItemInNs::Macros(makro) = item if let hir::ItemInNs::Macros(makro) = item
&& Definition::Macro(makro) && Definition::Macro(makro)