Attempt to write test

Mikayla created

Change summary

crates/gpui/src/action.rs       | 22 ++++++-
crates/gpui/src/key_dispatch.rs | 88 ++++++++++++++++++++++++++++++++++
2 files changed, 103 insertions(+), 7 deletions(-)

Detailed changes

crates/gpui/src/action.rs 🔗

@@ -114,14 +114,26 @@ impl ActionRegistry {
     pub(crate) fn load_actions(&mut self) {
         for builder in __GPUI_ACTIONS {
             let action = builder();
-            //todo(remove)
-            let name: SharedString = action.name.into();
-            self.builders_by_name.insert(name.clone(), action.build);
-            self.names_by_type_id.insert(action.type_id, name.clone());
-            self.all_names.push(name);
+            self.insert_action(action);
         }
     }
 
+    #[cfg(test)]
+    pub(crate) fn load_action<A: Action>(&mut self) {
+        self.insert_action(ActionData {
+            name: A::debug_name(),
+            type_id: TypeId::of::<A>(),
+            build: A::build,
+        });
+    }
+
+    fn insert_action(&mut self, action: ActionData) {
+        let name: SharedString = action.name.into();
+        self.builders_by_name.insert(name.clone(), action.build);
+        self.names_by_type_id.insert(action.type_id, name.clone());
+        self.all_names.push(name);
+    }
+
     /// Construct an action based on its name and optional JSON parameters sourced from the keymap.
     pub fn build_action_type(&self, type_id: &TypeId) -> Result<Box<dyn Action>> {
         let name = self

crates/gpui/src/key_dispatch.rs 🔗

@@ -192,8 +192,9 @@ impl DispatchTree {
         keymap
             .bindings_for_action(action)
             .filter(|binding| {
-                for i in 0..context_stack.len() {
-                    let context = &context_stack[0..=i];
+                for i in 1..context_stack.len() {
+                    dbg!(i);
+                    let context = &context_stack[0..i];
                     if keymap.binding_enabled(binding, context) {
                         return true;
                     }
@@ -283,3 +284,86 @@ impl DispatchTree {
         *self.node_stack.last().unwrap()
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use std::{rc::Rc, sync::Arc};
+
+    use parking_lot::Mutex;
+
+    use crate::{Action, ActionRegistry, DispatchTree, KeyBinding, KeyContext, Keymap};
+
+    #[derive(PartialEq, Eq)]
+    struct TestAction;
+
+    impl Action for TestAction {
+        fn name(&self) -> &'static str {
+            "test::TestAction"
+        }
+
+        fn debug_name() -> &'static str
+        where
+            Self: ::std::marker::Sized,
+        {
+            "test::TestAction"
+        }
+
+        fn partial_eq(&self, action: &dyn Action) -> bool {
+            action
+                .as_any()
+                .downcast_ref::<Self>()
+                .map_or(false, |a| self == a)
+        }
+
+        fn boxed_clone(&self) -> std::boxed::Box<dyn Action> {
+            Box::new(TestAction)
+        }
+
+        fn as_any(&self) -> &dyn ::std::any::Any {
+            self
+        }
+
+        fn build(_value: serde_json::Value) -> anyhow::Result<Box<dyn Action>>
+        where
+            Self: Sized,
+        {
+            Ok(Box::new(TestAction))
+        }
+    }
+
+    #[test]
+    fn test_keybinding_for_action_bounds() {
+        dbg!("got here");
+
+        let keymap = Keymap::new(vec![KeyBinding::new(
+            "cmd-n",
+            TestAction,
+            Some("ProjectPanel"),
+        )]);
+        dbg!("got here");
+
+        let mut registry = ActionRegistry::default();
+        dbg!("got here");
+
+        registry.load_action::<TestAction>();
+
+        dbg!("got here");
+
+        let keymap = Arc::new(Mutex::new(keymap));
+        dbg!("got here");
+
+        let tree = DispatchTree::new(keymap, Rc::new(registry));
+
+        dbg!("got here");
+        let keybinding = tree.bindings_for_action(
+            &TestAction,
+            &vec![
+                KeyContext::parse(",").unwrap(),
+                KeyContext::parse("Workspace").unwrap(),
+                KeyContext::parse("ProjectPanel").unwrap(),
+            ],
+        );
+
+        assert!(keybinding[0].action.partial_eq(&TestAction))
+    }
+}