Add a better API for updating settings in the SettingsStore in tests

Max Brunsfeld created

Change summary

crates/settings/src/settings_file.rs    | 10 ++---
crates/settings/src/settings_store.rs   | 43 ++++++++++++++++++++------
crates/vim/src/test/vim_test_context.rs | 12 +++---
3 files changed, 42 insertions(+), 23 deletions(-)

Detailed changes

crates/settings/src/settings_file.rs 🔗

@@ -172,12 +172,10 @@ pub fn update_settings_file<T: Setting>(
             })
             .await?;
 
-        let edits = cx.read(|cx| cx.global::<SettingsStore>().update::<T>(&old_text, update));
-
-        let mut new_text = old_text;
-        for (range, replacement) in edits.into_iter().rev() {
-            new_text.replace_range(range, &replacement);
-        }
+        let new_text = cx.read(|cx| {
+            cx.global::<SettingsStore>()
+                .new_text_for_update::<T>(old_text, update)
+        });
 
         cx.background()
             .spawn(async move { fs.atomic_write(paths::SETTINGS.clone(), new_text).await })

crates/settings/src/settings_store.rs 🔗

@@ -184,22 +184,43 @@ impl SettingsStore {
         this
     }
 
-    /// Override the global value for a particular setting.
+    /// Update the value of a setting in the user's global configuration.
     ///
     /// This is only for tests. Normally, settings are only loaded from
     /// JSON files.
     #[cfg(any(test, feature = "test-support"))]
-    pub fn replace_value<T: Setting>(&mut self, value: T) {
-        self.setting_values
-            .get_mut(&TypeId::of::<T>())
-            .unwrap_or_else(|| panic!("unregistered setting type {}", type_name::<T>()))
-            .set_global_value(Box::new(value))
+    pub fn update_user_settings<T: Setting>(
+        &mut self,
+        cx: &AppContext,
+        update: impl FnOnce(&mut T::FileContent),
+    ) {
+        let old_text = if let Some(user_settings) = &self.user_deserialized_settings {
+            serde_json::to_string(&user_settings.untyped).unwrap()
+        } else {
+            String::new()
+        };
+        let new_text = self.new_text_for_update::<T>(old_text, update);
+        self.set_user_settings(&new_text, cx).unwrap();
     }
 
-    /// Update the value of a setting.
-    ///
-    /// Returns a list of edits to apply to the JSON file.
-    pub fn update<T: Setting>(
+    /// Update the value of a setting in a JSON file, returning the new text
+    /// for that JSON file.
+    pub fn new_text_for_update<T: Setting>(
+        &self,
+        old_text: String,
+        update: impl FnOnce(&mut T::FileContent),
+    ) -> String {
+        let edits = self.edits_for_update::<T>(&old_text, update);
+        let mut new_text = old_text;
+        for (range, replacement) in edits.into_iter().rev() {
+            new_text.replace_range(range, &replacement);
+        }
+        new_text
+    }
+
+    /// Update the value of a setting in a JSON file, returning a list
+    /// of edits to apply to the JSON file.
+    pub fn edits_for_update<T: Setting>(
         &self,
         text: &str,
         update: impl FnOnce(&mut T::FileContent),
@@ -1129,7 +1150,7 @@ mod tests {
         cx: &mut AppContext,
     ) {
         store.set_user_settings(&old_json, cx).ok();
-        let edits = store.update::<T>(&old_json, update);
+        let edits = store.edits_for_update::<T>(&old_json, update);
         let mut new_json = old_json;
         for (range, replacement) in edits.into_iter().rev() {
             new_json.replace_range(range, &replacement);

crates/vim/src/test/vim_test_context.rs 🔗

@@ -21,8 +21,8 @@ impl<'a> VimTestContext<'a> {
             search::init(cx);
             crate::init(cx);
 
-            cx.update_global(|store: &mut SettingsStore, _| {
-                store.replace_value(VimModeSetting(enabled));
+            cx.update_global(|store: &mut SettingsStore, cx| {
+                store.update_user_settings::<VimModeSetting>(cx, |s| *s = Some(enabled));
             });
 
             settings::KeymapFileContent::load("keymaps/vim.json", cx).unwrap();
@@ -53,16 +53,16 @@ impl<'a> VimTestContext<'a> {
 
     pub fn enable_vim(&mut self) {
         self.cx.update(|cx| {
-            cx.update_global(|store: &mut SettingsStore, _| {
-                store.replace_value(VimModeSetting(true))
+            cx.update_global(|store: &mut SettingsStore, cx| {
+                store.update_user_settings::<VimModeSetting>(cx, |s| *s = Some(true));
             });
         })
     }
 
     pub fn disable_vim(&mut self) {
         self.cx.update(|cx| {
-            cx.update_global(|store: &mut SettingsStore, _| {
-                store.replace_value(VimModeSetting(false))
+            cx.update_global(|store: &mut SettingsStore, cx| {
+                store.update_user_settings::<VimModeSetting>(cx, |s| *s = Some(false));
             });
         })
     }