239: add test loggin API to db r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2018-11-21 17:44:43 +00:00
commit 4bff9ce59a
2 changed files with 104 additions and 1 deletions

View file

@ -1,5 +1,6 @@
use std::sync::Arc;
use parking_lot::Mutex;
use ra_editor::LineIndex;
use ra_syntax::{SourceFileNode, SyntaxNode};
use salsa::{self, Database};
@ -18,6 +19,11 @@ use crate::{
#[derive(Debug)]
pub(crate) struct RootDatabase {
#[cfg(test)]
events: Mutex<Option<Vec<salsa::Event<RootDatabase>>>>,
#[cfg(not(test))]
events: (),
runtime: salsa::Runtime<RootDatabase>,
id_maps: IdMaps,
}
@ -26,11 +32,22 @@ impl salsa::Database for RootDatabase {
fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
&self.runtime
}
fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
#[cfg(test)]
{
let mut events = self.events.lock();
if let Some(events) = &mut *events {
events.push(event());
}
}
}
}
impl Default for RootDatabase {
fn default() -> RootDatabase {
let mut db = RootDatabase {
events: Default::default(),
runtime: salsa::Runtime::default(),
id_maps: IdMaps::default(),
};
@ -55,6 +72,7 @@ pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> {
impl salsa::ParallelDatabase for RootDatabase {
fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
salsa::Snapshot::new(RootDatabase {
events: Default::default(),
runtime: self.runtime.snapshot(self),
id_maps: self.id_maps.clone(),
})
@ -67,6 +85,29 @@ impl IdDatabase for RootDatabase {
}
}
#[cfg(test)]
impl RootDatabase {
pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<RootDatabase>> {
*self.events.lock() = Some(Vec::new());
f();
let events = self.events.lock().take().unwrap();
events
}
pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
let events = self.log(f);
events
.into_iter()
.filter_map(|e| match e.kind {
// This pretty horrible, but `Debug` is the only way to inspect
// QueryDescriptor at the moment.
salsa::EventKind::WillExecute { descriptor } => Some(format!("{:?}", descriptor)),
_ => None,
})
.collect()
}
}
salsa::database_storage! {
pub(crate) struct RootDatabaseStorage for RootDatabase {
impl crate::input::FilesDatabase {

View file

@ -358,7 +358,8 @@ where
#[cfg(test)]
mod tests {
use crate::{
mock_analysis::analysis_and_position,
AnalysisChange,
mock_analysis::{MockAnalysis, analysis_and_position},
descriptors::{DescriptorDatabase, module::ModuleDescriptor},
input::FilesDatabase,
};
@ -396,4 +397,65 @@ mod tests {
let resolution = &item_map.per_module[&module_id].items[&name];
assert!(resolution.def_id.is_some());
}
#[test]
fn typing_inside_a_function_should_not_invalidate_item_map() {
let mock_analysis = MockAnalysis::with_files(
"
//- /lib.rs
mod foo;
use crate::foo::bar::Baz;
fn foo() -> i32 {
1 + 1
}
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
",
);
let file_id = mock_analysis.id_of("/lib.rs");
let mut host = mock_analysis.analysis_host();
let source_root = host.analysis().imp.db.file_source_root(file_id);
{
let db = host.analysis().imp.db;
let events = db.log_executed(|| {
db._item_map(source_root).unwrap();
});
assert!(format!("{:?}", events).contains("_item_map"))
}
let mut change = AnalysisChange::new();
change.change_file(
file_id,
"
mod foo;
use crate::foo::bar::Baz;
fn foo() -> i32 { 92 }
"
.to_string(),
);
host.apply_change(change);
{
let db = host.analysis().imp.db;
let events = db.log_executed(|| {
db._item_map(source_root).unwrap();
});
// assert!(
// !format!("{:?}", events).contains("_item_map"),
// "{:#?}", events
// )
}
}
}