From 7ddfa62d4f01d15783e4bd85d1b2f4f0b5d3ba93 Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Tue, 16 Sep 2025 12:33:41 -0300 Subject: [PATCH] Test buffer shadow --- Cargo.lock | 1 + crates/edit_prediction_context/Cargo.toml | 1 + .../src/tree_sitter_index.rs | 178 +++++++++++++----- 3 files changed, 134 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f95b1f1059f73b9ae5093ffe5b9aa532a4e785ab..c5743802deec4367d4dff833d6920232155245c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5046,6 +5046,7 @@ dependencies = [ "anyhow", "arrayvec", "collections", + "futures 0.3.31", "gpui", "indoc", "language", diff --git a/crates/edit_prediction_context/Cargo.toml b/crates/edit_prediction_context/Cargo.toml index 70688ff6fdf424e7f8b1b94a1d00fc02801be05c..64e765d7d2cfb1db86bc828d77d290027461bebc 100644 --- a/crates/edit_prediction_context/Cargo.toml +++ b/crates/edit_prediction_context/Cargo.toml @@ -26,6 +26,7 @@ workspace-hack.workspace = true worktree.workspace = true [dev-dependencies] +futures.workspace = true gpui = { workspace = true, features = ["test-support"] } indoc.workspace = true language = { workspace = true, features = ["test-support"] } diff --git a/crates/edit_prediction_context/src/tree_sitter_index.rs b/crates/edit_prediction_context/src/tree_sitter_index.rs index 1b1992f750fd20d9c71ba1afec0668c319ffe554..b3917c3f561556e78eaee2c36b0fb3f86ef03dd7 100644 --- a/crates/edit_prediction_context/src/tree_sitter_index.rs +++ b/crates/edit_prediction_context/src/tree_sitter_index.rs @@ -385,10 +385,11 @@ mod tests { use super::*; use std::{path::Path, sync::Arc}; + use futures::channel::oneshot; use gpui::TestAppContext; use indoc::indoc; use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_rust}; - use project::{FakeFs, Project}; + use project::{FakeFs, Project, ProjectItem}; use serde_json::json; use settings::SettingsStore; use util::path; @@ -397,7 +398,135 @@ mod tests { #[gpui::test] async fn test_unopen_indexed_files(cx: &mut TestAppContext) { - init_test(cx); + let (project, index) = init_test(cx).await; + + index.read_with(cx, |index, cx| { + let decls = index.declarations_for_identifier::<8>("main", cx); + assert_eq!(decls.len(), 2); + + let decl = expect_file_decl("c.rs", &decls[0], &project, cx); + assert_eq!(decl.identifier, "main".into()); + assert_eq!(decl.item_range, 32..279); + + let decl = expect_file_decl("a.rs", &decls[1], &project, cx); + assert_eq!(decl.identifier, "main".into()); + assert_eq!(decl.item_range, 0..97); + }); + } + + #[gpui::test] + async fn test_declarations_limt(cx: &mut TestAppContext) { + let (_, index) = init_test(cx).await; + + // todo! test with buffers + index.read_with(cx, |index, cx| { + let decls = index.declarations_for_identifier::<1>("main", cx); + assert_eq!(decls.len(), 1); + }); + } + + #[gpui::test] + async fn test_buffer_shadow(cx: &mut TestAppContext) { + let (project, index) = init_test(cx).await; + + let buffer = project + .update(cx, |project, cx| { + let project_path = project.find_project_path("c.rs", cx).unwrap(); + project.open_buffer(project_path, cx) + }) + .await + .unwrap(); + + cx.run_until_parked(); + + index.read_with(cx, |index, cx| { + let decls = index.declarations_for_identifier::<8>("main", cx); + assert_eq!(decls.len(), 2); + + let decl = expect_buffer_decl("c.rs", &decls[0], cx); + assert_eq!(decl.identifier, "main".into()); + assert_eq!(decl.item_range.to_offset(&buffer.read(cx)), 32..279); + + expect_file_decl("a.rs", &decls[1], &project, cx); + }); + + // Drop the buffer and wait for release + let (release_tx, release_rx) = oneshot::channel(); + cx.update(|cx| { + cx.observe_release(&buffer, |_, _| { + release_tx.send(()).ok(); + }) + .detach(); + }); + drop(buffer); + cx.run_until_parked(); + release_rx.await.ok(); + cx.run_until_parked(); + + index.read_with(cx, |index, cx| { + let decls = index.declarations_for_identifier::<8>("main", cx); + assert_eq!(decls.len(), 2); + expect_file_decl("c.rs", &decls[0], &project, cx); + expect_file_decl("a.rs", &decls[1], &project, cx); + }); + } + + fn expect_buffer_decl<'a>( + path: &str, + declaration: &'a Declaration, + cx: &App, + ) -> &'a BufferDeclaration { + if let Declaration::Buffer { + declaration, + buffer, + } = declaration + { + assert_eq!( + buffer + .upgrade() + .unwrap() + .read(cx) + .project_path(cx) + .unwrap() + .path + .as_ref(), + Path::new(path), + ); + declaration + } else { + panic!("Expected a buffer declaration, found {:?}", declaration); + } + } + + fn expect_file_decl<'a>( + path: &str, + declaration: &'a Declaration, + project: &Entity, + cx: &App, + ) -> &'a FileDeclaration { + if let Declaration::File { declaration, file } = declaration { + assert_eq!( + project + .read(cx) + .path_for_entry(*file, cx) + .unwrap() + .path + .as_ref(), + Path::new(path), + ); + declaration + } else { + panic!("Expected a file declaration, found {:?}", declaration); + } + } + + async fn init_test(cx: &mut TestAppContext) -> (Entity, Entity) { + cx.update(|cx| { + let settings_store = SettingsStore::test(cx); + cx.set_global(settings_store); + language::init(cx); + Project::init_settings(cx); + }); let fs = FakeFs::new(cx.executor()); fs.insert_tree( @@ -469,42 +598,8 @@ mod tests { let index = cx.new(|cx| TreeSitterIndex::new(&project, cx)); cx.run_until_parked(); - index.read_with(cx, |index, cx| { - let decls = index.declarations_for_identifier::<8>("main", cx); - assert_eq!(decls.len(), 2); - if let Declaration::File { declaration, file } = &decls[0] { - assert_eq!( - project - .read(cx) - .path_for_entry(*file, cx) - .unwrap() - .path - .as_ref(), - Path::new("c.rs"), - ); - assert_eq!(declaration.identifier, "main".into()); - assert_eq!(declaration.item_range, 32..279); - } else { - panic!(); - } - - if let Declaration::File { declaration, file } = &decls[1] { - assert_eq!( - project - .read(cx) - .path_for_entry(*file, cx) - .unwrap() - .path - .as_ref(), - Path::new("a.rs"), - ); - assert_eq!(declaration.identifier, "main".into()); - assert_eq!(declaration.item_range, 0..97); - } else { - panic!(); - } - }); + (project, index) } fn rust_lang() -> Language { @@ -522,15 +617,6 @@ mod tests { .with_outline_query(include_str!("../../languages/src/rust/outline.scm")) .unwrap() } - - fn init_test(cx: &mut TestAppContext) { - cx.update(|cx| { - let settings_store = SettingsStore::test(cx); - cx.set_global(settings_store); - language::init(cx); - Project::init_settings(cx); - }); - } } /*