From 709682e8bcb7e1f9f71d63b450d0455f162e1e85 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 5 Jan 2024 16:28:40 -0700 Subject: [PATCH] Tidy up TestContext lifecycle Co-Authored-By: Max --- crates/collab/src/tests/following_tests.rs | 18 ++++++++---- crates/editor/src/editor_tests.rs | 8 ++--- .../src/test/editor_lsp_test_context.rs | 24 +++++++-------- crates/editor/src/test/editor_test_context.rs | 12 ++++---- crates/file_finder/src/file_finder.rs | 2 +- crates/gpui/src/app/test_context.rs | 29 ++++++++++--------- crates/search/src/buffer_search.rs | 7 ++--- .../neovim_backed_binding_test_context.rs | 21 ++++++-------- .../src/test/neovim_backed_test_context.rs | 21 +++++++------- crates/vim/src/test/vim_test_context.rs | 18 ++++++------ 10 files changed, 82 insertions(+), 78 deletions(-) diff --git a/crates/collab/src/tests/following_tests.rs b/crates/collab/src/tests/following_tests.rs index 01c3302e4d3b1e6d5cf02d65b03ad095acf1b893..c9be683ee6e5a1cae53ed8933b69a7da39dcbe4f 100644 --- a/crates/collab/src/tests/following_tests.rs +++ b/crates/collab/src/tests/following_tests.rs @@ -4,7 +4,7 @@ use collab_ui::notifications::project_shared_notification::ProjectSharedNotifica use editor::{Editor, ExcerptRange, MultiBuffer}; use gpui::{ point, BackgroundExecutor, Context, SharedString, TestAppContext, View, VisualContext, - VisualTestContext, WindowContext, + VisualTestContext, }; use language::Capability; use live_kit_client::MacOSDisplay; @@ -12,7 +12,6 @@ use project::project_settings::ProjectSettings; use rpc::proto::PeerId; use serde_json::json; use settings::SettingsStore; -use std::borrow::Cow; use workspace::{ dock::{test::TestPanel, DockPosition}, item::{test::TestItem, ItemHandle as _}, @@ -1433,6 +1432,15 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut }); executor.run_until_parked(); + let window_b_project_a = cx_b + .windows() + .iter() + .max_by_key(|window| window.window_id()) + .unwrap() + .clone(); + + let mut cx_b_project_a = VisualTestContext::from_window(window_b_project_a, cx_b); + let workspace_b_project_a = cx_b .windows() .iter() @@ -1444,7 +1452,7 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut .unwrap(); // assert that b is following a in project a in w.rs - workspace_b_project_a.update(cx_b, |workspace, cx| { + workspace_b_project_a.update(&mut cx_b_project_a, |workspace, cx| { assert!(workspace.is_being_followed(client_a.peer_id().unwrap())); assert_eq!( client_a.peer_id(), @@ -1459,7 +1467,7 @@ async fn test_following_across_workspaces(cx_a: &mut TestAppContext, cx_b: &mut // TODO: in app code, this would be done by the collab_ui. active_call_b - .update(cx_b, |call, cx| { + .update(&mut cx_b_project_a, |call, cx| { let project = workspace_b_project_a.read(cx).project().clone(); call.set_location(Some(&project), cx) }) @@ -1738,7 +1746,7 @@ fn followers_by_leader(project_id: u64, cx: &TestAppContext) -> Vec<(PeerId, Vec }) } -fn pane_summaries(workspace: &View, cx: &mut VisualTestContext<'_>) -> Vec { +fn pane_summaries(workspace: &View, cx: &mut VisualTestContext) -> Vec { workspace.update(cx, |workspace, cx| { let active_pane = workspace.active_pane(); workspace diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index a84b866e1f8139a8ca558ccd54ac57c1d6e08bdd..b64e3cccc3e6330429eefb54a410024cbc5e1ce6 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -8131,8 +8131,8 @@ fn assert_selection_ranges(marked_text: &str, view: &mut Editor, cx: &mut ViewCo /// Handle completion request passing a marked string specifying where the completion /// should be triggered from using '|' character, what range should be replaced, and what completions /// should be returned using '<' and '>' to delimit the range -pub fn handle_completion_request<'a>( - cx: &mut EditorLspTestContext<'a>, +pub fn handle_completion_request( + cx: &mut EditorLspTestContext, marked_string: &str, completions: Vec<&'static str>, ) -> impl Future { @@ -8177,8 +8177,8 @@ pub fn handle_completion_request<'a>( } } -fn handle_resolve_completion_request<'a>( - cx: &mut EditorLspTestContext<'a>, +fn handle_resolve_completion_request( + cx: &mut EditorLspTestContext, edits: Option>, ) -> impl Future { let edits = edits.map(|edits| { diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index 7ee55cddba1edba9356be2c6773c3f097f57c1c8..70c1699b83d090ef24c74f393cd8530502b7ce02 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -21,19 +21,19 @@ use workspace::{AppState, Workspace, WorkspaceHandle}; use super::editor_test_context::{AssertionContextManager, EditorTestContext}; -pub struct EditorLspTestContext<'a> { - pub cx: EditorTestContext<'a>, +pub struct EditorLspTestContext { + pub cx: EditorTestContext, pub lsp: lsp::FakeLanguageServer, pub workspace: View, pub buffer_lsp_url: lsp::Url, } -impl<'a> EditorLspTestContext<'a> { +impl EditorLspTestContext { pub async fn new( mut language: Language, capabilities: lsp::ServerCapabilities, - cx: &'a mut gpui::TestAppContext, - ) -> EditorLspTestContext<'a> { + cx: &mut gpui::TestAppContext, + ) -> EditorLspTestContext { let app_state = cx.update(AppState::test); cx.update(|cx| { @@ -110,8 +110,8 @@ impl<'a> EditorLspTestContext<'a> { pub async fn new_rust( capabilities: lsp::ServerCapabilities, - cx: &'a mut gpui::TestAppContext, - ) -> EditorLspTestContext<'a> { + cx: &mut gpui::TestAppContext, + ) -> EditorLspTestContext { let language = Language::new( LanguageConfig { name: "Rust".into(), @@ -152,8 +152,8 @@ impl<'a> EditorLspTestContext<'a> { pub async fn new_typescript( capabilities: lsp::ServerCapabilities, - cx: &'a mut gpui::TestAppContext, - ) -> EditorLspTestContext<'a> { + cx: &mut gpui::TestAppContext, + ) -> EditorLspTestContext { let mut word_characters: HashSet = Default::default(); word_characters.insert('$'); word_characters.insert('#'); @@ -283,15 +283,15 @@ impl<'a> EditorLspTestContext<'a> { } } -impl<'a> Deref for EditorLspTestContext<'a> { - type Target = EditorTestContext<'a>; +impl Deref for EditorLspTestContext { + type Target = EditorTestContext; fn deref(&self) -> &Self::Target { &self.cx } } -impl<'a> DerefMut for EditorLspTestContext<'a> { +impl DerefMut for EditorLspTestContext { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx } diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index bd5acb99459c131d316a5376688f3d4bcb81da93..18916f844cec8dc379de5f56259940e183aad447 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -26,15 +26,15 @@ use util::{ use super::build_editor_with_project; -pub struct EditorTestContext<'a> { - pub cx: gpui::VisualTestContext<'a>, +pub struct EditorTestContext { + pub cx: gpui::VisualTestContext, pub window: AnyWindowHandle, pub editor: View, pub assertion_cx: AssertionContextManager, } -impl<'a> EditorTestContext<'a> { - pub async fn new(cx: &'a mut gpui::TestAppContext) -> EditorTestContext<'a> { +impl EditorTestContext { + pub async fn new(cx: &mut gpui::TestAppContext) -> EditorTestContext { let fs = FakeFs::new(cx.executor()); // fs.insert_file("/file", "".to_owned()).await; fs.insert_tree( @@ -342,7 +342,7 @@ impl<'a> EditorTestContext<'a> { } } -impl<'a> Deref for EditorTestContext<'a> { +impl Deref for EditorTestContext { type Target = gpui::TestAppContext; fn deref(&self) -> &Self::Target { @@ -350,7 +350,7 @@ impl<'a> Deref for EditorTestContext<'a> { } } -impl<'a> DerefMut for EditorTestContext<'a> { +impl DerefMut for EditorTestContext { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 589f634d01b7db8c5889f134e9707eabad4943bc..323d4555671f1020b970eff091d28dd694977293 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -1843,7 +1843,7 @@ mod tests { expected_matches: usize, expected_editor_title: &str, workspace: &View, - cx: &mut gpui::VisualTestContext<'_>, + cx: &mut gpui::VisualTestContext, ) -> Vec { let picker = open_file_picker(&workspace, cx); cx.simulate_input(input); diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index cf6ecb62b6f8adb023c8ceb9a1b9ace5277b4a40..470315f887c6fd5e4c6d3523498dbe496ff041a8 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -483,21 +483,24 @@ impl View { } use derive_more::{Deref, DerefMut}; -#[derive(Deref, DerefMut)] -pub struct VisualTestContext<'a> { +#[derive(Deref, DerefMut, Clone)] +pub struct VisualTestContext { #[deref] #[deref_mut] - cx: &'a mut TestAppContext, + cx: TestAppContext, window: AnyWindowHandle, } -impl<'a> VisualTestContext<'a> { +impl<'a> VisualTestContext { pub fn update(&mut self, f: impl FnOnce(&mut WindowContext) -> R) -> R { self.cx.update_window(self.window, |_, cx| f(cx)).unwrap() } - pub fn from_window(window: AnyWindowHandle, cx: &'a mut TestAppContext) -> Self { - Self { cx, window } + pub fn from_window(window: AnyWindowHandle, cx: &TestAppContext) -> Self { + Self { + cx: cx.clone(), + window, + } } pub fn run_until_parked(&self) { @@ -531,7 +534,7 @@ impl<'a> VisualTestContext<'a> { } } -impl<'a> Context for VisualTestContext<'a> { +impl Context for VisualTestContext { type Result = ::Result; fn new_model( @@ -582,7 +585,7 @@ impl<'a> Context for VisualTestContext<'a> { } } -impl<'a> VisualContext for VisualTestContext<'a> { +impl VisualContext for VisualTestContext { fn new_view( &mut self, build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V, @@ -591,7 +594,7 @@ impl<'a> VisualContext for VisualTestContext<'a> { V: 'static + Render, { self.window - .update(self.cx, |_, cx| cx.new_view(build_view)) + .update(&mut self.cx, |_, cx| cx.new_view(build_view)) .unwrap() } @@ -601,7 +604,7 @@ impl<'a> VisualContext for VisualTestContext<'a> { update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R, ) -> Self::Result { self.window - .update(self.cx, |_, cx| cx.update_view(view, update)) + .update(&mut self.cx, |_, cx| cx.update_view(view, update)) .unwrap() } @@ -613,13 +616,13 @@ impl<'a> VisualContext for VisualTestContext<'a> { V: 'static + Render, { self.window - .update(self.cx, |_, cx| cx.replace_root_view(build_view)) + .update(&mut self.cx, |_, cx| cx.replace_root_view(build_view)) .unwrap() } fn focus_view(&mut self, view: &View) -> Self::Result<()> { self.window - .update(self.cx, |_, cx| { + .update(&mut self.cx, |_, cx| { view.read(cx).focus_handle(cx).clone().focus(cx) }) .unwrap() @@ -630,7 +633,7 @@ impl<'a> VisualContext for VisualTestContext<'a> { V: crate::ManagedView, { self.window - .update(self.cx, |_, cx| { + .update(&mut self.cx, |_, cx| { view.update(cx, |_, cx| cx.emit(crate::DismissEvent)) }) .unwrap() diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 3f1cbce1bded6c7b7517597606f176062c34e06b..c889f0a4a4c11d3f104e130e34e5b87c092565d6 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1091,13 +1091,10 @@ mod tests { theme::init(theme::LoadThemes::JustBase, cx); }); } + fn init_test( cx: &mut TestAppContext, - ) -> ( - View, - View, - &mut VisualTestContext<'_>, - ) { + ) -> (View, View, &mut VisualTestContext) { init_globals(cx); let buffer = cx.new_model(|cx| { Buffer::new( diff --git a/crates/vim/src/test/neovim_backed_binding_test_context.rs b/crates/vim/src/test/neovim_backed_binding_test_context.rs index 15fce99aad3f4ea0e03129342a4bca48fba4166f..0f64a6c849a32b6764cd5d605b5568c64759d89d 100644 --- a/crates/vim/src/test/neovim_backed_binding_test_context.rs +++ b/crates/vim/src/test/neovim_backed_binding_test_context.rs @@ -4,30 +4,27 @@ use crate::state::Mode; use super::{ExemptionFeatures, NeovimBackedTestContext, SUPPORTED_FEATURES}; -pub struct NeovimBackedBindingTestContext<'a, const COUNT: usize> { - cx: NeovimBackedTestContext<'a>, +pub struct NeovimBackedBindingTestContext { + cx: NeovimBackedTestContext, keystrokes_under_test: [&'static str; COUNT], } -impl<'a, const COUNT: usize> NeovimBackedBindingTestContext<'a, COUNT> { - pub fn new( - keystrokes_under_test: [&'static str; COUNT], - cx: NeovimBackedTestContext<'a>, - ) -> Self { +impl NeovimBackedBindingTestContext { + pub fn new(keystrokes_under_test: [&'static str; COUNT], cx: NeovimBackedTestContext) -> Self { Self { cx, keystrokes_under_test, } } - pub fn consume(self) -> NeovimBackedTestContext<'a> { + pub fn consume(self) -> NeovimBackedTestContext { self.cx } pub fn binding( self, keystrokes: [&'static str; NEW_COUNT], - ) -> NeovimBackedBindingTestContext<'a, NEW_COUNT> { + ) -> NeovimBackedBindingTestContext { self.consume().binding(keystrokes) } @@ -80,15 +77,15 @@ impl<'a, const COUNT: usize> NeovimBackedBindingTestContext<'a, COUNT> { } } -impl<'a, const COUNT: usize> Deref for NeovimBackedBindingTestContext<'a, COUNT> { - type Target = NeovimBackedTestContext<'a>; +impl Deref for NeovimBackedBindingTestContext { + type Target = NeovimBackedTestContext; fn deref(&self) -> &Self::Target { &self.cx } } -impl<'a, const COUNT: usize> DerefMut for NeovimBackedBindingTestContext<'a, COUNT> { +impl DerefMut for NeovimBackedBindingTestContext { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx } diff --git a/crates/vim/src/test/neovim_backed_test_context.rs b/crates/vim/src/test/neovim_backed_test_context.rs index 7380537655b1e2765003aeaec37d7918c2607bfb..fe5c5db62f831a3725e753ef4df3d448c28c4e68 100644 --- a/crates/vim/src/test/neovim_backed_test_context.rs +++ b/crates/vim/src/test/neovim_backed_test_context.rs @@ -47,8 +47,8 @@ impl ExemptionFeatures { } } -pub struct NeovimBackedTestContext<'a> { - cx: VimTestContext<'a>, +pub struct NeovimBackedTestContext { + cx: VimTestContext, // Lookup for exempted assertions. Keyed by the insertion text, and with a value indicating which // bindings are exempted. If None, all bindings are ignored for that insertion text. exemptions: HashMap>>, @@ -60,8 +60,8 @@ pub struct NeovimBackedTestContext<'a> { is_dirty: bool, } -impl<'a> NeovimBackedTestContext<'a> { - pub async fn new(cx: &'a mut gpui::TestAppContext) -> NeovimBackedTestContext<'a> { +impl NeovimBackedTestContext { + pub async fn new(cx: &mut gpui::TestAppContext) -> NeovimBackedTestContext { // rust stores the name of the test on the current thread. // We use this to automatically name a file that will store // the neovim connection's requests/responses so that we can @@ -393,20 +393,20 @@ impl<'a> NeovimBackedTestContext<'a> { pub fn binding( self, keystrokes: [&'static str; COUNT], - ) -> NeovimBackedBindingTestContext<'a, COUNT> { + ) -> NeovimBackedBindingTestContext { NeovimBackedBindingTestContext::new(keystrokes, self) } } -impl<'a> Deref for NeovimBackedTestContext<'a> { - type Target = VimTestContext<'a>; +impl Deref for NeovimBackedTestContext { + type Target = VimTestContext; fn deref(&self) -> &Self::Target { &self.cx } } -impl<'a> DerefMut for NeovimBackedTestContext<'a> { +impl DerefMut for NeovimBackedTestContext { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx } @@ -415,7 +415,7 @@ impl<'a> DerefMut for NeovimBackedTestContext<'a> { // a common mistake in tests is to call set_shared_state when // you mean asswert_shared_state. This notices that and lets // you know. -impl<'a> Drop for NeovimBackedTestContext<'a> { +impl Drop for NeovimBackedTestContext { fn drop(&mut self) { if self.is_dirty { panic!("Test context was dropped after set_shared_state before assert_shared_state") @@ -425,9 +425,8 @@ impl<'a> Drop for NeovimBackedTestContext<'a> { #[cfg(test)] mod test { - use gpui::TestAppContext; - use crate::test::NeovimBackedTestContext; + use gpui::TestAppContext; #[gpui::test] async fn neovim_backed_test_context_works(cx: &mut TestAppContext) { diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 21b041b2451f5dce4d930ebbc9c66705ed5a22a2..5ed5296bff44d3e76c32f2a4b768afd760d1d121 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -10,11 +10,11 @@ use search::BufferSearchBar; use crate::{state::Operator, *}; -pub struct VimTestContext<'a> { - cx: EditorLspTestContext<'a>, +pub struct VimTestContext { + cx: EditorLspTestContext, } -impl<'a> VimTestContext<'a> { +impl VimTestContext { pub fn init(cx: &mut gpui::TestAppContext) { if cx.has_global::() { dbg!("OOPS"); @@ -29,13 +29,13 @@ impl<'a> VimTestContext<'a> { }); } - pub async fn new(cx: &'a mut gpui::TestAppContext, enabled: bool) -> VimTestContext<'a> { + pub async fn new(cx: &mut gpui::TestAppContext, enabled: bool) -> VimTestContext { Self::init(cx); let lsp = EditorLspTestContext::new_rust(Default::default(), cx).await; Self::new_with_lsp(lsp, enabled) } - pub async fn new_typescript(cx: &'a mut gpui::TestAppContext) -> VimTestContext<'a> { + pub async fn new_typescript(cx: &mut gpui::TestAppContext) -> VimTestContext { Self::init(cx); Self::new_with_lsp( EditorLspTestContext::new_typescript(Default::default(), cx).await, @@ -43,7 +43,7 @@ impl<'a> VimTestContext<'a> { ) } - pub fn new_with_lsp(mut cx: EditorLspTestContext<'a>, enabled: bool) -> VimTestContext<'a> { + pub fn new_with_lsp(mut cx: EditorLspTestContext, enabled: bool) -> VimTestContext { cx.update(|cx| { cx.update_global(|store: &mut SettingsStore, cx| { store.update_user_settings::(cx, |s| *s = Some(enabled)); @@ -162,15 +162,15 @@ impl<'a> VimTestContext<'a> { } } -impl<'a> Deref for VimTestContext<'a> { - type Target = EditorTestContext<'a>; +impl Deref for VimTestContext { + type Target = EditorTestContext; fn deref(&self) -> &Self::Target { &self.cx } } -impl<'a> DerefMut for VimTestContext<'a> { +impl DerefMut for VimTestContext { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.cx }