diff --git a/.gitignore b/.gitignore index 6f057fe0e..e698101a4 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ debug.log package-lock.json .vscode/settings.json */.vscode/ +proptest-regressions/ # Tauri output /bundle.json diff --git a/examples/vue/quasar-app/src-tauri/src/main.rs b/examples/vue/quasar-app/src-tauri/src/main.rs index 89f6b0252..41c854f71 100644 --- a/examples/vue/quasar-app/src-tauri/src/main.rs +++ b/examples/vue/quasar-app/src-tauri/src/main.rs @@ -13,19 +13,23 @@ fn main() { tauri::AppBuilder::new() .setup(|_webview| { let handle = _webview.handle(); - tauri::event::listen("hello", move |msg| { + tauri::event::listen(String::from("hello"), move |msg| { #[derive(Serialize)] pub struct Reply { pub msg: String, - pub rep: String + pub rep: String, } let reply = Reply { msg: format!("{}", msg).to_string(), - rep: "something else".to_string() + rep: "something else".to_string(), }; - tauri::event::emit(&handle, "reply", serde_json::to_string(&reply).unwrap()); + tauri::event::emit( + &handle, + String::from("reply"), + serde_json::to_string(&reply).unwrap(), + ); println!("Message from emit:hello => {}", msg); }); diff --git a/tauri-updater/src/updater.rs b/tauri-updater/src/updater.rs index bfbfa34f5..dd6397a09 100644 --- a/tauri-updater/src/updater.rs +++ b/tauri-updater/src/updater.rs @@ -128,7 +128,7 @@ impl UpdateBuilder { /// The path provided should be: /// /// ``` - /// # use tauri::updater::Update; + /// # use tauri_updater::updater::Update; /// # fn run() -> Result<(), Box> { /// Update::configure()? /// .bin_path_in_archive("bin/myapp") diff --git a/tauri/Cargo.toml b/tauri/Cargo.toml index 21a0148d5..906e26bbe 100644 --- a/tauri/Cargo.toml +++ b/tauri/Cargo.toml @@ -28,6 +28,8 @@ tauri-api = { version = "0.2", path = "../tauri-api" } [build-dependencies] tauri_includedir_codegen = "0.5.1" +[dev-dependencies] +proptest = "0.9.4" [features] edge = ["web-view/edge"] diff --git a/tauri/src/event.rs b/tauri/src/event.rs index c636da993..6ba9b7120 100644 --- a/tauri/src/event.rs +++ b/tauri/src/event.rs @@ -1,6 +1,7 @@ use std::boxed::Box; use std::collections::HashMap; use std::sync::{Arc, Mutex}; + use web_view::Handle; struct EventHandler { @@ -27,13 +28,13 @@ pub fn event_queue_object_name() -> String { EVENT_QUEUE_OBJECT_NAME.to_string() } -pub fn listen(id: &'static str, handler: F) { +pub fn listen(id: String, handler: F) { LISTENERS.with(|listeners| { let mut l = listeners .lock() .expect("Failed to lock listeners: listen()"); l.insert( - id.to_string(), + id, EventHandler { on_event: Box::new(handler), }, @@ -41,7 +42,7 @@ pub fn listen(id: &'static str, handler: F) { }); } -pub fn emit(webview_handle: &Handle, event: &'static str, mut payload: String) { +pub fn emit(webview_handle: &Handle, event: String, mut payload: String) { let salt = crate::salt::generate(); if payload == "" { payload = "void 0".to_string(); @@ -52,7 +53,7 @@ pub fn emit(webview_handle: &Handle, event: &'static str, mut pay _webview.eval(&format!( "window['{}']({{type: '{}', payload: {}}}, '{}')", emit_function_name(), - event, + event.as_str(), payload, salt )) @@ -74,3 +75,83 @@ pub fn on_event(event: String, data: String) { } }); } + +#[cfg(test)] +mod test { + use crate::event::*; + use proptest::prelude::*; + + // dummy event handler function + fn event_fn(s: String) { + println!("{}", s) + } + + proptest! { + #![proptest_config(ProptestConfig::with_cases(10000))] + #[test] + // check to see if listen() is properly passing keys into the LISTENERS map + fn listeners_check_key(e in "[a-z]+") { + // clone e as the key + let key = e.clone(); + // pass e and an dummy func into listen + listen(e, event_fn); + + // open listeners + LISTENERS.with(|lis| { + // lock mutex + let l = lis.lock().unwrap(); + + // check if the generated key is in the map + assert_eq!(l.contains_key(&key), true); + }); + } + + #[test] + // check to see if listen inputs a handler function properly into the LISTENERS map. + fn listeners_check_fn(e in "[a-z]+") { + // clone e as the key + let key = e.clone(); + // pass e and an dummy func into listen + listen(e, event_fn); + + // open listeners + LISTENERS.with(|lis| { + // lock mutex + let mut l = lis.lock().unwrap(); + + // check if l contains key + if l.contains_key(&key) { + // grab key if it exists + let handler = l.get_mut(&key); + // check to see if we get back a handler or not + match handler { + // pass on Some(handler) + Some(_) => assert!(true), + // Fail on None + None => assert!(false) + } + } + }); + } + + #[test] + // check to see if on_event properly grabs the stored function from listen. + fn check_on_event(e in "[a-z]+", d in "[a-z]+") { + // clone e as the key + let key = e.clone(); + // call listen with e and the event_fn dummy func + listen(e.clone(), event_fn); + // call on event with e and d. + on_event(e, d); + + // open listeners + LISTENERS.with(|list| { + // lock the mutex + let l = list.lock().unwrap(); + + // assert that the key is contained in the listeners map + assert!(l.contains_key(&key)); + }); + } + } +} diff --git a/tauri/src/lib.rs b/tauri/src/lib.rs index 69af053cd..542982da4 100644 --- a/tauri/src/lib.rs +++ b/tauri/src/lib.rs @@ -79,3 +79,22 @@ pub fn call( error, ); } + +#[cfg(test)] +mod test { + use proptest::prelude::*; + + proptest! { + #[test] + // check to see if spawn executes a function. + fn check_spawn_task(task in "[a-z]+") { + // create dummy task function + let dummy_task = move || { + format!("{}-run-dummy-task", task); + assert!(true); + }; + // call spawn + crate::spawn(dummy_task); + } + } +}