From cee7edabf94dc3cf0ffa55e9895613224eb2a6aa Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 10 May 2023 16:39:59 -0700 Subject: [PATCH] Ensure the SettingsStore global is added in tests --- crates/client/src/client.rs | 25 +++++++++++-------- crates/collab/src/tests.rs | 5 +++- .../src/tests/randomized_integration_tests.rs | 7 ++++-- .../src/test/editor_lsp_test_context.rs | 4 +-- crates/gpui/src/app.rs | 11 +++++++- crates/settings/src/settings_store.rs | 23 +++++++++++------ crates/vim/src/test/vim_test_context.rs | 5 ++-- crates/workspace/src/workspace.rs | 7 ++++-- crates/zed/src/main.rs | 2 +- crates/zed/src/zed.rs | 4 +-- 10 files changed, 61 insertions(+), 32 deletions(-) diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 9d24254b40..bcf9152051 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -70,27 +70,30 @@ pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5); actions!(client, [SignIn, SignOut]); -pub fn init(client: Arc, cx: &mut AppContext) { +pub fn init(client: &Arc, cx: &mut AppContext) { + let client = Arc::downgrade(client); settings::register_setting::(cx); cx.add_global_action({ let client = client.clone(); move |_: &SignIn, cx| { - let client = client.clone(); - cx.spawn( - |cx| async move { client.authenticate_and_connect(true, &cx).log_err().await }, - ) - .detach(); + if let Some(client) = client.upgrade() { + cx.spawn( + |cx| async move { client.authenticate_and_connect(true, &cx).log_err().await }, + ) + .detach(); + } } }); cx.add_global_action({ let client = client.clone(); move |_: &SignOut, cx| { - let client = client.clone(); - cx.spawn(|cx| async move { - client.disconnect(&cx); - }) - .detach(); + if let Some(client) = client.upgrade() { + cx.spawn(|cx| async move { + client.disconnect(&cx); + }) + .detach(); + } } }); } diff --git a/crates/collab/src/tests.rs b/crates/collab/src/tests.rs index 64768d1a47..50fb9658fe 100644 --- a/crates/collab/src/tests.rs +++ b/crates/collab/src/tests.rs @@ -19,7 +19,7 @@ use gpui::{ use language::LanguageRegistry; use parking_lot::Mutex; use project::{Project, WorktreeId}; -use settings::Settings; +use settings::{Settings, SettingsStore}; use std::{ cell::{Ref, RefCell, RefMut}, env, @@ -102,6 +102,7 @@ impl TestServer { async fn create_client(&mut self, cx: &mut TestAppContext, name: &str) -> TestClient { cx.update(|cx| { + cx.set_global(SettingsStore::test(cx)); cx.set_global(Settings::test(cx)); }); @@ -185,6 +186,8 @@ impl TestServer { }) }); + cx.update(|cx| client::init(&client, cx)); + let fs = FakeFs::new(cx.background()); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx)); let app_state = Arc::new(workspace::AppState { diff --git a/crates/collab/src/tests/randomized_integration_tests.rs b/crates/collab/src/tests/randomized_integration_tests.rs index c4326be101..3a87ced2e1 100644 --- a/crates/collab/src/tests/randomized_integration_tests.rs +++ b/crates/collab/src/tests/randomized_integration_tests.rs @@ -20,7 +20,7 @@ use rand::{ prelude::*, }; use serde::{Deserialize, Serialize}; -use settings::Settings; +use settings::{Settings, SettingsStore}; use std::{ env, ops::Range, @@ -148,8 +148,11 @@ async fn test_random_collaboration( for (client, mut cx) in clients { cx.update(|cx| { + let store = cx.remove_global::(); + let settings = cx.remove_global::(); cx.clear_globals(); - cx.set_global(Settings::test(cx)); + cx.set_global(store); + cx.set_global(settings); drop(client); }); } diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index fe9a7909b8..e268e2a0ce 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -34,13 +34,13 @@ impl<'a> EditorLspTestContext<'a> { ) -> EditorLspTestContext<'a> { use json::json; + let app_state = cx.update(AppState::test); + cx.update(|cx| { crate::init(cx); pane::init(cx); }); - let app_state = cx.update(AppState::test); - let file_name = format!( "file.{}", language diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index d5a7a2f3ab..5def0bed9d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1174,7 +1174,7 @@ impl AppContext { this.notify_global(type_id); result } else { - panic!("No global added for {}", std::any::type_name::()); + panic!("no global added for {}", std::any::type_name::()); } } @@ -1182,6 +1182,15 @@ impl AppContext { self.globals.clear(); } + pub fn remove_global(&mut self) -> T { + *self + .globals + .remove(&TypeId::of::()) + .unwrap_or_else(|| panic!("no global added for {}", std::any::type_name::())) + .downcast() + .unwrap() + } + pub fn add_model(&mut self, build_model: F) -> ModelHandle where T: Entity, diff --git a/crates/settings/src/settings_store.rs b/crates/settings/src/settings_store.rs index d986ea0683..59f7bee10f 100644 --- a/crates/settings/src/settings_store.rs +++ b/crates/settings/src/settings_store.rs @@ -122,11 +122,11 @@ impl SettingsStore { /// Add a new type of setting to the store. pub fn register_setting(&mut self, cx: &AppContext) { let setting_type_id = TypeId::of::(); - let entry = self.setting_values.entry(setting_type_id); if matches!(entry, hash_map::Entry::Occupied(_)) { - panic!("duplicate setting type: {}", type_name::()); + return; } + let setting_value = entry.or_insert(Box::new(SettingValue:: { global_value: None, local_values: Vec::new(), @@ -142,6 +142,7 @@ impl SettingsStore { user_values_stack = vec![user_value]; } } + if let Some(default_deserialized_value) = default_settings.typed.get(&setting_type_id) { setting_value.set_global_value(setting_value.load_setting( default_deserialized_value, @@ -159,7 +160,7 @@ impl SettingsStore { pub fn get(&self, path: Option<&Path>) -> &T { self.setting_values .get(&TypeId::of::()) - .expect("unregistered setting type") + .unwrap_or_else(|| panic!("unregistered setting type {}", type_name::())) .value_for_path(path) .downcast_ref::() .expect("no default value for setting type") @@ -175,6 +176,14 @@ impl SettingsStore { .map_or(&serde_json::Value::Null, |s| &s.untyped) } + #[cfg(any(test, feature = "test-support"))] + pub fn test(cx: &AppContext) -> Self { + let mut this = Self::default(); + this.set_default_settings(&crate::test_settings(), cx) + .unwrap(); + this + } + /// Override the global value for a particular setting. /// /// This is only for tests. Normally, settings are only loaded from @@ -183,7 +192,7 @@ impl SettingsStore { pub fn replace_value(&mut self, value: T) { self.setting_values .get_mut(&TypeId::of::()) - .expect("unregistered setting type") + .unwrap_or_else(|| panic!("unregistered setting type {}", type_name::())) .set_global_value(Box::new(value)) } @@ -268,7 +277,7 @@ impl SettingsStore { pub fn set_default_settings( &mut self, default_settings_content: &str, - cx: &mut AppContext, + cx: &AppContext, ) -> Result<()> { let deserialized_setting_map = self.load_setting_map(default_settings_content)?; if deserialized_setting_map.typed.len() != self.setting_values.len() { @@ -290,7 +299,7 @@ impl SettingsStore { pub fn set_user_settings( &mut self, user_settings_content: &str, - cx: &mut AppContext, + cx: &AppContext, ) -> Result<()> { let user_settings = self.load_setting_map(user_settings_content)?; let old_user_settings = @@ -304,7 +313,7 @@ impl SettingsStore { &mut self, path: Arc, settings_content: Option<&str>, - cx: &mut AppContext, + cx: &AppContext, ) -> Result<()> { let removed_map = if let Some(settings_content) = settings_content { self.local_deserialized_settings diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 69e432079a..b426cea717 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -18,11 +18,12 @@ impl<'a> VimTestContext<'a> { pub async fn new(cx: &'a mut gpui::TestAppContext, enabled: bool) -> VimTestContext<'a> { let mut cx = EditorLspTestContext::new_rust(Default::default(), cx).await; cx.update(|cx| { + search::init(cx); + crate::init(cx); + cx.update_global(|store: &mut SettingsStore, _| { store.replace_value(VimModeSetting(enabled)); }); - search::init(cx); - crate::init(cx); settings::KeymapFileContent::load("keymaps/vim.json", cx).unwrap(); }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 8a62a28c11..0e3ce2a724 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -369,8 +369,8 @@ pub struct AppState { impl AppState { #[cfg(any(test, feature = "test-support"))] pub fn test(cx: &mut AppContext) -> Arc { - let settings = Settings::test(cx); - cx.set_global(settings); + cx.set_global(settings::SettingsStore::test(cx)); + cx.set_global(Settings::test(cx)); let fs = fs::FakeFs::new(cx.background().clone()); let languages = Arc::new(LanguageRegistry::test()); @@ -378,6 +378,9 @@ impl AppState { let client = Client::new(http_client.clone(), cx); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx)); let themes = ThemeRegistry::new((), cx.font_cache().clone()); + + client::init(&client, cx); + Arc::new(Self { client, themes, diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 58c68c56d3..465219b8a6 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -158,7 +158,7 @@ fn main() { context_menu::init(cx); project::Project::init(&client); - client::init(client.clone(), cx); + client::init(&client, cx); command_palette::init(cx); editor::init(cx); go_to_line::init(cx); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 26d2b50e0d..e6322ad843 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1283,9 +1283,7 @@ mod tests { #[gpui::test] async fn test_pane_actions(cx: &mut TestAppContext) { - init(cx); - - let app_state = cx.update(AppState::test); + let app_state = init(cx); app_state .fs .as_fake()