Pārlūkot izejas kodu

add async command tests, command with arg

Lucas Nogueira 2 gadi atpakaļ
vecāks
revīzija
b0485d0187
1 mainītis faili ar 164 papildinājumiem un 51 dzēšanām
  1. 164 51
      core/tauri/src/window.rs

+ 164 - 51
core/tauri/src/window.rs

@@ -1519,6 +1519,7 @@ mod tests {
 
   use super::{Window, WindowBuilder};
   use crate::{api::ipc::CallbackFn, test, InvokePayload, State};
+  use serde_json::Value as JsonValue;
 
   #[test]
   fn window_is_send_sync() {
@@ -1526,60 +1527,172 @@ mod tests {
     crate::test_utils::assert_sync::<Window>();
   }
 
-  #[test]
-  fn regular_commands() {
-    #[derive(Debug, Eq, PartialEq)]
-    enum Response {
-      Cmd,
-    }
+  macro_rules! commands {
+    (fn) => {
+      #[crate::command(root = "crate")]
+      fn cmd_state(channel: State<'_, Channel>) {
+        println!("cmd state");
+        channel.tx.send(Response::Cmd).unwrap();
+      }
 
-    #[crate::command(root = "crate")]
-    fn cmd() {
-      println!("cmd");
-    }
+      #[crate::command(root = "crate")]
+      fn cmd_state_return_val(channel: State<'_, Channel>) -> &'static str {
+        println!("cmd state return val");
+        channel.tx.send(Response::CmdReturnVal).unwrap();
+        STATE_RETURN_VAL_RESPONSE
+      }
 
-    #[crate::command(root = "crate")]
-    fn cmd_state(channel: State<'_, Channel>) {
-      println!("cmd state");
-      channel.tx.send(Response::Cmd).unwrap();
-    }
+      #[crate::command(root = "crate")]
+      fn cmd_state_arg(channel: State<'_, Channel>, arg: usize) {
+        println!("cmd state arg");
+        channel.tx.send(Response::CmdArg(arg)).unwrap();
+      }
 
-    struct Channel {
-      tx: SyncSender<Response>,
-    }
+      #[crate::command(root = "crate")]
+      fn cmd_state_arg_return_val(channel: State<'_, Channel>, arg: usize) -> &'static str {
+        println!("cmd state arg return val");
+        channel.tx.send(Response::CmdArgReturnVal(arg)).unwrap();
+        STATE_ARG_RETURN_VAL_RESPONSE
+      }
+    };
+
+    (async fn) => {
+      #[crate::command(root = "crate")]
+      async fn cmd_state(channel: State<'_, Channel>) -> crate::Result<()> {
+        println!("cmd state");
+        channel.tx.send(Response::Cmd).unwrap();
+        Ok(())
+      }
 
-    let (tx, rx) = sync_channel(1);
-    let channel = Channel { tx };
-
-    let app = test::mock_builder()
-      .manage(channel)
-      .invoke_handler(crate::generate_handler![cmd, cmd_state])
-      .build(test::mock_context(test::noop_assets()))
-      .unwrap();
-    let window = WindowBuilder::new(&app, "test", Default::default())
-      .build()
-      .unwrap();
-    window
-      .clone()
-      .on_message(InvokePayload {
-        cmd: "cmd".into(),
-        tauri_module: None,
-        callback: CallbackFn(0),
-        error: CallbackFn(0),
-        inner: Default::default(),
-      })
-      .unwrap();
-
-    window
-      .clone()
-      .on_message(InvokePayload {
-        cmd: "cmd_state".into(),
-        tauri_module: None,
-        callback: CallbackFn(0),
-        error: CallbackFn(0),
-        inner: Default::default(),
-      })
-      .unwrap();
-    assert_eq!(rx.try_recv().unwrap(), Response::Cmd);
+      #[crate::command(root = "crate")]
+      async fn cmd_state_return_val(channel: State<'_, Channel>) -> crate::Result<&'static str> {
+        println!("cmd state return val");
+        channel.tx.send(Response::CmdReturnVal).unwrap();
+        Ok(STATE_RETURN_VAL_RESPONSE)
+      }
+
+      #[crate::command(root = "crate")]
+      async fn cmd_state_arg(channel: State<'_, Channel>, arg: usize) -> crate::Result<()> {
+        println!("cmd state arg");
+        channel.tx.send(Response::CmdArg(arg)).unwrap();
+        Ok(())
+      }
+
+      #[crate::command(root = "crate")]
+      async fn cmd_state_arg_return_val(
+        channel: State<'_, Channel>,
+        arg: usize,
+      ) -> crate::Result<&'static str> {
+        println!("cmd state arg return val");
+        channel.tx.send(Response::CmdArgReturnVal(arg)).unwrap();
+        Ok(STATE_ARG_RETURN_VAL_RESPONSE)
+      }
+    };
+  }
+
+  macro_rules! command_test {
+    ($test_name: ident, $($fn_kind: ident) +) => {
+      #[test]
+      fn $test_name() {
+        const STATE_RETURN_VAL_RESPONSE: &str = "return-val";
+        const STATE_ARG_RETURN_VAL_RESPONSE: &str = "arg-return-val";
+
+        #[derive(Debug, Eq, PartialEq)]
+        enum Response {
+          Cmd,
+          CmdReturnVal,
+          CmdArg(usize),
+          CmdArgReturnVal(usize),
+        }
+
+        struct Channel {
+          tx: SyncSender<Response>,
+        }
+
+        #[crate::command(root = "crate")]
+        $($fn_kind)* cmd() {
+          println!("cmd");
+        }
+
+        commands!($($fn_kind)*);
+
+        let (tx, rx) = sync_channel(1);
+        let channel = Channel { tx };
+
+        let app = test::mock_builder()
+          .manage(channel)
+          .invoke_handler(crate::generate_handler![
+            cmd,
+            cmd_state,
+            cmd_state_return_val,
+            cmd_state_arg,
+            cmd_state_arg_return_val
+          ])
+          .build(test::mock_context(test::noop_assets()))
+          .unwrap();
+        let window = WindowBuilder::new(&app, "test", Default::default())
+          .build()
+          .unwrap();
+
+        fn json_obj(key: &str, value: impl Into<JsonValue>) -> JsonValue {
+          let mut map = serde_json::Map::new();
+          map.insert(key.into(), value.into());
+          map.into()
+        }
+
+        struct UnitTest {
+          cmd: &'static str,
+          response: Option<Response>,
+          arg: Option<JsonValue>,
+        }
+
+        let tests = vec![
+          UnitTest {
+            cmd: "cmd",
+            response: None,
+            arg: None,
+          },
+          UnitTest {
+            cmd: "cmd_state",
+            response: Some(Response::Cmd),
+            arg: None,
+          },
+          UnitTest {
+            cmd: "cmd_state_return_val",
+            response: Some(Response::CmdReturnVal),
+            arg: None,
+          },
+          UnitTest {
+            cmd: "cmd_state_arg",
+            response: Some(Response::CmdArg(1)),
+            arg: Some(json_obj("arg", 1)),
+          },
+          UnitTest {
+            cmd: "cmd_state_arg_return_val",
+            response: Some(Response::CmdArgReturnVal(2)),
+            arg: Some(json_obj("arg", 2)),
+          },
+        ];
+
+        for test in tests {
+          window
+            .clone()
+            .on_message(InvokePayload {
+              cmd: test.cmd.into(),
+              tauri_module: None,
+              callback: CallbackFn(0),
+              error: CallbackFn(0),
+              inner: test.arg.unwrap_or_default(),
+            })
+            .unwrap();
+          if let Some(response) = test.response {
+            assert_eq!(rx.recv_timeout(std::time::Duration::from_secs(3)).unwrap(), response);
+          }
+        }
+      }
+    };
   }
+
+  command_test!(regular_commands, fn);
+  command_test!(async_commands, async fn);
 }