diff --git a/.changes/get-ipc-response-test.md b/.changes/get-ipc-response-test.md new file mode 100644 index 000000000..9cd3ce1d2 --- /dev/null +++ b/.changes/get-ipc-response-test.md @@ -0,0 +1,5 @@ +--- +"tauri": patch:enhance +--- + +Added `test::get_ipc_response`. diff --git a/core/tauri/src/test/mod.rs b/core/tauri/src/test/mod.rs index 3138d56fb..38c651231 100644 --- a/core/tauri/src/test/mod.rs +++ b/core/tauri/src/test/mod.rs @@ -27,7 +27,9 @@ //! } //! //! fn main() { -//! let app = create_app(tauri::Builder::default()); +//! // Use `tauri::Builder::default()` to use the default runtime rather than the `MockRuntime`; +//! // let app = create_app(tauri::Builder::default()); +//! let app = create_app(tauri::test::mock_builder()); //! // app.run(|_handle, _event| {}); //! } //! @@ -59,6 +61,7 @@ mod mock_runtime; pub use mock_runtime::*; +use serde::de::DeserializeOwned; use serde::Serialize; use serde_json::Value as JsonValue; @@ -82,9 +85,12 @@ use tauri_utils::{ config::{CliConfig, Config, PatternKind, TauriConfig}, }; +/// A key for an [`Ipc`] call. #[derive(Eq, PartialEq)] struct IpcKey { + /// callback callback: CallbackFn, + /// error callback error: CallbackFn, } @@ -95,6 +101,7 @@ impl Hash for IpcKey { } } +/// Structure to retrieve result of a Tauri command struct Ipc(Mutex>>>); /// An empty [`Assets`] implementation. @@ -227,35 +234,27 @@ pub fn mock_app() -> App { /// .expect("failed to build app") /// } /// +/// use tauri::Manager; +/// use tauri::test::mock_builder; /// fn main() { -/// let app = create_app(tauri::Builder::default()); -/// // app.run(|_handle, _event| {});} -/// } +/// // app createion with a `MockRuntime` +/// let app = create_app(mock_builder()); +/// let window = app.get_window("main").unwrap(); /// -/// //#[cfg(test)] -/// mod tests { -/// use tauri::Manager; -/// -/// //#[cfg(test)] -/// fn something() { -/// let app = super::create_app(tauri::test::mock_builder()); -/// let window = app.get_window("main").unwrap(); -/// -/// // run the `ping` command and assert it returns `pong` -/// tauri::test::assert_ipc_response( -/// &window, -/// tauri::InvokePayload { -/// cmd: "ping".into(), -/// tauri_module: None, -/// callback: tauri::api::ipc::CallbackFn(0), -/// error: tauri::api::ipc::CallbackFn(1), -/// inner: serde_json::Value::Null, -/// }, -/// // the expected response is a success with the "pong" payload -/// // we could also use Err("error message") here to ensure the command failed -/// Ok("pong") -/// ); -/// } +/// // run the `ping` command and assert it returns `pong` +/// tauri::test::assert_ipc_response( +/// &window, +/// tauri::InvokePayload { +/// cmd: "ping".into(), +/// tauri_module: None, +/// callback: tauri::api::ipc::CallbackFn(0), +/// error: tauri::api::ipc::CallbackFn(1), +/// inner: serde_json::Value::Null, +/// }, +/// // the expected response is a success with the "pong" payload +/// // we could also use Err("error message") here to ensure the command failed +/// Ok("pong") +/// ); /// } /// ``` pub fn assert_ipc_response( @@ -263,6 +262,54 @@ pub fn assert_ipc_response( payload: InvokePayload, expected: Result, ) { + assert_eq!( + get_ipc_response(window, payload), + expected + .map(|e| serde_json::to_value(e).unwrap()) + .map_err(|e| serde_json::to_value(e).unwrap()) + ); +} + +/// The application processes the command and stops. +/// +/// # Examples +/// +/// ```rust +/// +/// #[tauri::command] +/// fn ping() -> &'static str { +/// "pong" +/// } +/// +/// fn create_app(mut builder: tauri::Builder) -> tauri::App { +/// builder +/// .invoke_handler(tauri::generate_handler![ping]) +/// // remove the string argument on your app +/// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) +/// .expect("failed to build app") +/// } +/// +/// use tauri::test::*; +/// use tauri::Manager; +/// let app = create_app(mock_builder()); +/// let window = app.get_window("main").unwrap(); +/// +/// // run the `ping` command and assert it returns `pong` +/// let res = tauri::test::get_ipc_response::( +/// &window, +/// tauri::InvokePayload { +/// cmd: "ping".into(), +/// tauri_module: None, +/// callback: tauri::api::ipc::CallbackFn(0), +/// error: tauri::api::ipc::CallbackFn(1), +/// inner: serde_json::Value::Null, +/// }); +/// assert_eq!(res, Ok("pong".into())) +/// ``` +pub fn get_ipc_response( + window: &Window, + payload: InvokePayload, +) -> Result { let callback = payload.callback; let error = payload.error; let ipc = window.state::(); @@ -270,12 +317,10 @@ pub fn assert_ipc_response( ipc.0.lock().unwrap().insert(IpcKey { callback, error }, tx); window.clone().on_message(payload).unwrap(); - assert_eq!( - rx.recv().unwrap(), - expected - .map(|e| serde_json::to_value(e).unwrap()) - .map_err(|e| serde_json::to_value(e).unwrap()) - ); + let res: Result = rx.recv().expect("Failed to receive result from command"); + res + .map(|v| serde_json::from_value(v).unwrap()) + .map_err(|e| serde_json::from_value(e).unwrap()) } #[cfg(test)]