optimize snapshot-testing macro detection and add tests

This commit is contained in:
roife 2024-12-26 15:55:03 +08:00
parent c54bfcb181
commit 1dcce45f48
2 changed files with 136 additions and 44 deletions

View file

@ -9926,3 +9926,99 @@ fn bar() {
"#]],
);
}
#[test]
fn test_runnables_with_snapshot_tests() {
check_actions(
r#"
//- /lib.rs crate:foo deps:expect_test,insta,snapbox
use expect_test::expect;
use insta::assert_debug_snapshot;
use snapbox::Assert;
#[test]
fn test$0() {
let actual = "new25";
expect!["new25"].assert_eq(&actual);
Assert::new()
.action_env("SNAPSHOTS")
.eq(actual, snapbox::str!["new25"]);
assert_debug_snapshot!(actual);
}
//- /lib.rs crate:expect_test
struct Expect;
impl Expect {
fn assert_eq(&self, actual: &str) {}
}
#[macro_export]
macro_rules! expect {
($e:expr) => Expect; // dummy
}
//- /lib.rs crate:insta
#[macro_export]
macro_rules! assert_debug_snapshot {
($e:expr) => {}; // dummy
}
//- /lib.rs crate:snapbox
pub struct Assert;
impl Assert {
pub fn new() -> Self { Assert }
pub fn action_env(&self, env: &str) -> &Self { self }
pub fn eq(&self, actual: &str, expected: &str) {}
}
#[macro_export]
macro_rules! str {
($e:expr) => ""; // dummy
}
"#,
expect![[r#"
[
Reference(
FilePositionWrapper {
file_id: FileId(
0,
),
offset: 92,
},
),
Runnable(
Runnable {
use_name_in_title: false,
nav: NavigationTarget {
file_id: FileId(
0,
),
full_range: 81..301,
focus_range: 92..96,
name: "test",
kind: Function,
},
kind: Test {
test_id: Path(
"test",
),
attr: TestAttr {
ignore: false,
},
},
cfg: None,
update_test: UpdateTest {
expect_test: true,
insta: true,
snapbox: true,
},
},
),
]
"#]],
);
}

View file

@ -657,62 +657,58 @@ impl<'a, 'b> TestDefs<'a, 'b> {
}
fn expect_test(&self) -> bool {
self.find_macro("expect_test:expect") || self.find_macro("expect_test::expect_file")
self.find_macro("expect_test", &["expect", "expect_file"])
}
fn insta(&self) -> bool {
self.find_macro("insta:assert_snapshot")
|| self.find_macro("insta:assert_debug_snapshot")
|| self.find_macro("insta:assert_display_snapshot")
|| self.find_macro("insta:assert_json_snapshot")
|| self.find_macro("insta:assert_yaml_snapshot")
|| self.find_macro("insta:assert_ron_snapshot")
|| self.find_macro("insta:assert_toml_snapshot")
|| self.find_macro("insta:assert_csv_snapshot")
|| self.find_macro("insta:assert_compact_json_snapshot")
|| self.find_macro("insta:assert_compact_debug_snapshot")
|| self.find_macro("insta:assert_binary_snapshot")
self.find_macro(
"insta",
&[
"assert_snapshot",
"assert_debug_snapshot",
"assert_display_snapshot",
"assert_json_snapshot",
"assert_yaml_snapshot",
"assert_ron_snapshot",
"assert_toml_snapshot",
"assert_csv_snapshot",
"assert_compact_json_snapshot",
"assert_compact_debug_snapshot",
"assert_binary_snapshot",
],
)
}
fn snapbox(&self) -> bool {
self.find_macro("snapbox:assert_data_eq")
|| self.find_macro("snapbox:file")
|| self.find_macro("snapbox:str")
self.find_macro("snapbox", &["assert_data_eq", "file", "str"])
}
fn find_macro(&self, path: &str) -> bool {
let Some(hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(it))) = self.find_def(path) else {
return false;
};
Definition::Macro(it)
.usages(self.0)
.in_scope(&SearchScope::file_range(self.2))
.at_least_one()
}
fn find_def(&self, path: &str) -> Option<hir::ScopeDef> {
fn find_macro(&self, crate_name: &str, paths: &[&str]) -> bool {
let db = self.0.db;
let mut path = path.split(':');
let item = path.next_back()?;
let krate = path.next()?;
let dep = self.1.dependencies(db).into_iter().find(|dep| dep.name.eq_ident(krate))?;
let Some(dep) =
self.1.dependencies(db).into_iter().find(|dep| dep.name.eq_ident(crate_name))
else {
return false;
};
let module = dep.krate.root_module();
let scope = module.scope(db, None);
let mut module = dep.krate.root_module();
for segment in path {
module = module.children(db).find_map(|child| {
let name = child.name(db)?;
if name.eq_ident(segment) {
Some(child)
} else {
None
paths
.iter()
.filter_map(|path| {
let (_, def) = scope.iter().find(|(name, _)| name.eq_ident(path))?;
match def {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(it)) => Some(it),
_ => None,
}
})?;
}
let (_, def) = module.scope(db, None).into_iter().find(|(name, _)| name.eq_ident(item))?;
Some(def)
})
.any(|makro| {
Definition::Macro(*makro)
.usages(self.0)
.in_scope(&SearchScope::file_range(self.2))
.at_least_one()
})
}
}