Skip to content

Commit 3c371aa

Browse files
vdang-crabnebulalucasfernoglucasfernog-crabnebula
authored
feat(core): add test::test::get_ipc_response, closes #8199 (#8228)
* feat(core): Add additional functions to the * Add documentation and cleanup the code * Improve and add tests to helper functions * Clean unecessary code and correct tests * Make `Ipc` and `IpcKey` public * Open `Ipc` with public functions * Update core/tauri/src/test/mod.rs Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app> * cleanup, change file --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app> Co-authored-by: Lucas Nogueira <lucas@crabnebula.dev>
1 parent c1bc4d2 commit 3c371aa

File tree

2 files changed

+84
-34
lines changed

2 files changed

+84
-34
lines changed

.changes/get-ipc-response-test.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:enhance
3+
---
4+
5+
Added `test::get_ipc_response`.

core/tauri/src/test/mod.rs

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
//! }
2828
//!
2929
//! fn main() {
30-
//! let app = create_app(tauri::Builder::default());
30+
//! // Use `tauri::Builder::default()` to use the default runtime rather than the `MockRuntime`;
31+
//! // let app = create_app(tauri::Builder::default());
32+
//! let app = create_app(tauri::test::mock_builder());
3133
//! // app.run(|_handle, _event| {});
3234
//! }
3335
//!
@@ -59,6 +61,7 @@
5961

6062
mod mock_runtime;
6163
pub use mock_runtime::*;
64+
use serde::de::DeserializeOwned;
6265
use serde::Serialize;
6366
use serde_json::Value as JsonValue;
6467

@@ -82,9 +85,12 @@ use tauri_utils::{
8285
config::{CliConfig, Config, PatternKind, TauriConfig},
8386
};
8487

88+
/// A key for an [`Ipc`] call.
8589
#[derive(Eq, PartialEq)]
8690
struct IpcKey {
91+
/// callback
8792
callback: CallbackFn,
93+
/// error callback
8894
error: CallbackFn,
8995
}
9096

@@ -95,6 +101,7 @@ impl Hash for IpcKey {
95101
}
96102
}
97103

104+
/// Structure to retrieve result of a Tauri command
98105
struct Ipc(Mutex<HashMap<IpcKey, Sender<std::result::Result<JsonValue, JsonValue>>>>);
99106

100107
/// An empty [`Assets`] implementation.
@@ -227,55 +234,93 @@ pub fn mock_app() -> App<MockRuntime> {
227234
/// .expect("failed to build app")
228235
/// }
229236
///
237+
/// use tauri::Manager;
238+
/// use tauri::test::mock_builder;
230239
/// fn main() {
231-
/// let app = create_app(tauri::Builder::default());
232-
/// // app.run(|_handle, _event| {});}
233-
/// }
234-
///
235-
/// //#[cfg(test)]
236-
/// mod tests {
237-
/// use tauri::Manager;
238-
///
239-
/// //#[cfg(test)]
240-
/// fn something() {
241-
/// let app = super::create_app(tauri::test::mock_builder());
242-
/// let window = app.get_window("main").unwrap();
240+
/// // app createion with a `MockRuntime`
241+
/// let app = create_app(mock_builder());
242+
/// let window = app.get_window("main").unwrap();
243243
///
244-
/// // run the `ping` command and assert it returns `pong`
245-
/// tauri::test::assert_ipc_response(
246-
/// &window,
247-
/// tauri::InvokePayload {
248-
/// cmd: "ping".into(),
249-
/// tauri_module: None,
250-
/// callback: tauri::api::ipc::CallbackFn(0),
251-
/// error: tauri::api::ipc::CallbackFn(1),
252-
/// inner: serde_json::Value::Null,
253-
/// },
254-
/// // the expected response is a success with the "pong" payload
255-
/// // we could also use Err("error message") here to ensure the command failed
256-
/// Ok("pong")
257-
/// );
258-
/// }
244+
/// // run the `ping` command and assert it returns `pong`
245+
/// tauri::test::assert_ipc_response(
246+
/// &window,
247+
/// tauri::InvokePayload {
248+
/// cmd: "ping".into(),
249+
/// tauri_module: None,
250+
/// callback: tauri::api::ipc::CallbackFn(0),
251+
/// error: tauri::api::ipc::CallbackFn(1),
252+
/// inner: serde_json::Value::Null,
253+
/// },
254+
/// // the expected response is a success with the "pong" payload
255+
/// // we could also use Err("error message") here to ensure the command failed
256+
/// Ok("pong")
257+
/// );
259258
/// }
260259
/// ```
261260
pub fn assert_ipc_response<T: Serialize + Debug>(
262261
window: &Window<MockRuntime>,
263262
payload: InvokePayload,
264263
expected: Result<T, T>,
265264
) {
265+
assert_eq!(
266+
get_ipc_response(window, payload),
267+
expected
268+
.map(|e| serde_json::to_value(e).unwrap())
269+
.map_err(|e| serde_json::to_value(e).unwrap())
270+
);
271+
}
272+
273+
/// The application processes the command and stops.
274+
///
275+
/// # Examples
276+
///
277+
/// ```rust
278+
///
279+
/// #[tauri::command]
280+
/// fn ping() -> &'static str {
281+
/// "pong"
282+
/// }
283+
///
284+
/// fn create_app<R: tauri::Runtime>(mut builder: tauri::Builder<R>) -> tauri::App<R> {
285+
/// builder
286+
/// .invoke_handler(tauri::generate_handler![ping])
287+
/// // remove the string argument on your app
288+
/// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))
289+
/// .expect("failed to build app")
290+
/// }
291+
///
292+
/// use tauri::test::*;
293+
/// use tauri::Manager;
294+
/// let app = create_app(mock_builder());
295+
/// let window = app.get_window("main").unwrap();
296+
///
297+
/// // run the `ping` command and assert it returns `pong`
298+
/// let res = tauri::test::get_ipc_response::<String>(
299+
/// &window,
300+
/// tauri::InvokePayload {
301+
/// cmd: "ping".into(),
302+
/// tauri_module: None,
303+
/// callback: tauri::api::ipc::CallbackFn(0),
304+
/// error: tauri::api::ipc::CallbackFn(1),
305+
/// inner: serde_json::Value::Null,
306+
/// });
307+
/// assert_eq!(res, Ok("pong".into()))
308+
/// ```
309+
pub fn get_ipc_response<T: DeserializeOwned + Debug>(
310+
window: &Window<MockRuntime>,
311+
payload: InvokePayload,
312+
) -> Result<T, T> {
266313
let callback = payload.callback;
267314
let error = payload.error;
268315
let ipc = window.state::<Ipc>();
269316
let (tx, rx) = channel();
270317
ipc.0.lock().unwrap().insert(IpcKey { callback, error }, tx);
271318
window.clone().on_message(payload).unwrap();
272319

273-
assert_eq!(
274-
rx.recv().unwrap(),
275-
expected
276-
.map(|e| serde_json::to_value(e).unwrap())
277-
.map_err(|e| serde_json::to_value(e).unwrap())
278-
);
320+
let res: Result<JsonValue, JsonValue> = rx.recv().expect("Failed to receive result from command");
321+
res
322+
.map(|v| serde_json::from_value(v).unwrap())
323+
.map_err(|e| serde_json::from_value(e).unwrap())
279324
}
280325

281326
#[cfg(test)]

0 commit comments

Comments
 (0)