Repository: tauri-apps/tauri
File: core/tauri/src/test/mod.rs (Rust)

Code before:
/// 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")
///     );
///   }
/// }
/// ```
pub fn assert_ipc_response<T: Serialize>(
  window: &Window<MockRuntime>,
  payload: InvokePayload,
  expected: Result<T, T>,
) {
  let callback = payload.callback;
  let error = payload.error;
  window.clone().on_message(payload).unwrap();

  let mut num_tries = 0;
  let evaluated_script = loop {
    std::thread::sleep(std::time::Duration::from_millis(50));
    let evaluated_script = window.dispatcher().last_evaluated_script();
    if let Some(s) = evaluated_script {
      break s;
    }
    num_tries += 1;
    if num_tries == 20 {
      panic!("Response script not evaluated");
    }
  };
  let (expected_response, fn_name) = match expected {
    Ok(payload) => (payload, callback),
    Err(payload) => (payload, error),
  };
  let expected = format!(

Review comment (suggestion):
This one also needs a timeout parameter.. and also it cannot be used with concurrency (only one assert call at a time because we check the last evaluated JS script). Maybe we should use a builder instead (ugly).

Code after:
    } else {
      window_invoke_responder(window, response, callback, error)
    }
  });

  builder
}

/// Creates a new [`App`] for testing using the [`mock_context`] with a [`noop_assets`].
pub fn mock_app() -> App<MockRuntime> {
  mock_builder().build(mock_context(noop_assets())).unwrap()
}

/// Executes the given IPC message and assert the response matches the expected value.
///
/// # Examples
///
/// ```rust
/// #[tauri::command]
/// fn ping() -> &'static str {
///   "pong"
/// }
///
/// fn create_app<R: tauri::Runtime>(mut builder: tauri::Builder<R>) -> tauri::App<R> {
///   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")
/// }
///
/// fn main() {
///   let app = create_app(tauri::Builder::default());
///   // app.run(|_handle, _event| {});}
/// }
///
/// //#[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,