Add unit test for Project::definition

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2022-01-21 15:05:25 +01:00
parent 64f5a45397
commit 4698d57ddd

View file

@ -1498,7 +1498,8 @@ mod tests {
use futures::StreamExt;
use gpui::{test::subscribe, TestAppContext};
use language::{
tree_sitter_rust, Diagnostic, LanguageConfig, LanguageRegistry, LanguageServerConfig, Point,
tree_sitter_rust, AnchorRangeExt, Diagnostic, LanguageConfig, LanguageRegistry,
LanguageServerConfig, Point,
};
use lsp::Url;
use serde_json::json;
@ -1532,9 +1533,9 @@ mod tests {
let project = build_project(&mut cx);
let tree = project
let (tree, _) = project
.update(&mut cx, |project, cx| {
project.add_local_worktree(&root_link_path, false, cx)
project.find_or_create_worktree_for_abs_path(&root_link_path, false, cx)
})
.await
.unwrap();
@ -1607,9 +1608,9 @@ mod tests {
)
});
let tree = project
let (tree, _) = project
.update(&mut cx, |project, cx| {
project.add_local_worktree(dir.path(), false, cx)
project.find_or_create_worktree_for_abs_path(dir.path(), false, cx)
})
.await
.unwrap();
@ -1713,9 +1714,9 @@ mod tests {
}));
let project = build_project(&mut cx);
let tree = project
let (tree, _) = project
.update(&mut cx, |project, cx| {
project.add_local_worktree(&dir.path(), false, cx)
project.find_or_create_worktree_for_abs_path(&dir.path(), false, cx)
})
.await
.unwrap();
@ -1733,6 +1734,126 @@ mod tests {
assert!(results.is_empty());
}
#[gpui::test]
async fn test_definition(mut cx: gpui::TestAppContext) {
let (language_server_config, mut fake_server) =
LanguageServerConfig::fake(cx.background()).await;
let mut languages = LanguageRegistry::new();
languages.add(Arc::new(Language::new(
LanguageConfig {
name: "Rust".to_string(),
path_suffixes: vec!["rs".to_string()],
language_server: Some(language_server_config),
..Default::default()
},
Some(tree_sitter_rust::language()),
)));
let dir = temp_tree(json!({
"a.rs": "const fn a() { A }",
"b.rs": "const y: i32 = crate::a()",
}));
let http_client = FakeHttpClient::with_404_response();
let client = Client::new(http_client.clone());
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
let project = cx.update(|cx| {
Project::local(
client,
user_store,
Arc::new(languages),
Arc::new(RealFs),
cx,
)
});
let (tree, _) = project
.update(&mut cx, |project, cx| {
project.find_or_create_worktree_for_abs_path(dir.path().join("b.rs"), false, cx)
})
.await
.unwrap();
let worktree_id = tree.read_with(&cx, |tree, _| tree.id());
cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
.await;
// Cause worktree to start the fake language server
let buffer = project
.update(&mut cx, |project, cx| {
project.open_buffer(
ProjectPath {
worktree_id,
path: Path::new("").into(),
},
cx,
)
})
.await
.unwrap();
let definitions =
project.update(&mut cx, |project, cx| project.definition(&buffer, 22, cx));
let (request_id, request) = fake_server
.receive_request::<lsp::request::GotoDefinition>()
.await;
let request_params = request.text_document_position_params;
assert_eq!(
request_params.text_document.uri.to_file_path().unwrap(),
dir.path().join("b.rs")
);
assert_eq!(request_params.position, lsp::Position::new(0, 22));
fake_server
.respond(
request_id,
Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location::new(
lsp::Url::from_file_path(dir.path().join("a.rs")).unwrap(),
lsp::Range::new(lsp::Position::new(0, 9), lsp::Position::new(0, 10)),
))),
)
.await;
let mut definitions = definitions.await.unwrap();
assert_eq!(definitions.len(), 1);
let definition = definitions.pop().unwrap();
cx.update(|cx| {
let target_buffer = definition.target_buffer.read(cx);
assert_eq!(
target_buffer.file().unwrap().abs_path(),
Some(dir.path().join("a.rs"))
);
assert_eq!(definition.target_range.to_offset(target_buffer), 9..10);
assert_eq!(
list_worktrees(&project, cx),
[
(dir.path().join("b.rs"), false),
(dir.path().join("a.rs"), true)
]
);
drop(definition);
});
cx.read(|cx| {
assert_eq!(
list_worktrees(&project, cx),
[(dir.path().join("b.rs"), false)]
);
});
fn list_worktrees(project: &ModelHandle<Project>, cx: &AppContext) -> Vec<(PathBuf, bool)> {
project
.read(cx)
.worktrees(cx)
.map(|worktree| {
let worktree = worktree.read(cx);
(
worktree.as_local().unwrap().abs_path().to_path_buf(),
worktree.is_weak(),
)
})
.collect::<Vec<_>>()
}
}
fn build_project(cx: &mut TestAppContext) -> ModelHandle<Project> {
let languages = Arc::new(LanguageRegistry::new());
let fs = Arc::new(RealFs);