1+ // Tauri Python Plugin
2+ // © Copyright 2024, by Marco Mengelkoch
3+ // Licensed under MIT License, see License file for more details
4+ // git clone https://github.com/marcomq/tauri-plugin-python
5+
6+ use super :: * ;
7+ use tauri:: { test:: { self , MockRuntime } , AppHandle } ;
8+
9+ /// Creates a mock Tauri app and initializes the PyRunner state.
10+ /// It also runs some initial Python code to set up a variable and a function for testing.
11+ async fn mock_app_handle ( ) -> AppHandle < MockRuntime > {
12+ let app = test:: mock_app ( ) ;
13+ let runner = PyRunner :: new ( ) ;
14+ app. manage ( runner) ;
15+
16+ let runner = app. state :: < PyRunner > ( ) . inner ( ) ;
17+ runner
18+ . run ( "my_var = 123\n def my_func(a, b):\n return a + b" )
19+ . await
20+ . unwrap ( ) ;
21+
22+ app. handle ( ) . clone ( )
23+ }
24+
25+ #[ tokio:: test]
26+ async fn test_read_variable ( ) {
27+ let app = mock_app_handle ( ) . await ;
28+ let payload = StringRequest {
29+ value : "my_var" . into ( ) ,
30+ } ;
31+ let response = app. read_variable ( payload) . await . unwrap ( ) ;
32+ assert_eq ! ( response. value, "123" ) ;
33+ }
34+
35+ #[ tokio:: test]
36+ async fn test_run_python ( ) {
37+ let app = mock_app_handle ( ) . await ;
38+ let payload = StringRequest {
39+ value : "new_var = 456" . into ( ) ,
40+ } ;
41+ app. run_python ( payload) . await . unwrap ( ) ;
42+
43+ // Verify the code was run by reading the variable back
44+ let read_payload = StringRequest {
45+ value : "new_var" . into ( ) ,
46+ } ;
47+ let response = app. read_variable ( read_payload) . await . unwrap ( ) ;
48+ assert_eq ! ( response. value, "456" ) ;
49+ }
50+
51+ #[ tokio:: test]
52+ async fn test_register_and_call_function ( ) {
53+ let app = mock_app_handle ( ) . await ;
54+
55+ // 1. Register the function
56+ let register_payload = RegisterRequest {
57+ python_function_call : "my_func" . into ( ) ,
58+ number_of_args : Some ( 2 ) ,
59+ } ;
60+ app. register_function ( register_payload) . await . unwrap ( ) ;
61+
62+ // 2. Call the registered function
63+ let call_payload = RunRequest {
64+ function_name : "my_func" . into ( ) ,
65+ args : vec ! [ serde_json:: json!( 10 ) , serde_json:: json!( 20 ) ] ,
66+ } ;
67+ let response = app. call_function ( call_payload) . await . unwrap ( ) ;
68+ assert_eq ! ( response. value, "30" ) ;
69+ }
70+
71+ #[ tokio:: test]
72+ async fn test_call_unregistered_function_fails ( ) {
73+ let app = mock_app_handle ( ) . await ;
74+ let call_payload = RunRequest {
75+ function_name : "unregistered_func" . into ( ) ,
76+ args : vec ! [ ] ,
77+ } ;
78+ let result = app. call_function ( call_payload) . await ;
79+ assert ! ( result. is_err( ) ) ;
80+ let err_msg = result. unwrap_err ( ) . to_string ( ) ;
81+ assert ! ( err_msg. contains( "Function unregistered_func has not been registered yet" ) ) ;
82+ }
83+
84+ #[ tokio:: test]
85+ async fn test_register_after_call_fails ( ) {
86+ let app = mock_app_handle ( ) . await ;
87+
88+ // 1. Register and call a function to set the INIT_BLOCKED flag
89+ let register_payload = RegisterRequest {
90+ python_function_call : "my_func" . into ( ) ,
91+ number_of_args : Some ( 2 ) ,
92+ } ;
93+ app. register_function ( register_payload) . await . unwrap ( ) ;
94+ let call_payload = RunRequest {
95+ function_name : "my_func" . into ( ) ,
96+ args : vec ! [ serde_json:: json!( 1 ) , serde_json:: json!( 2 ) ] ,
97+ } ;
98+ app. call_function ( call_payload) . await . unwrap ( ) ;
99+
100+ // 2. Attempt to register another function, which should now fail
101+ let second_register_payload = RegisterRequest {
102+ python_function_call : "my_var" . into ( ) , // can be anything
103+ number_of_args : None ,
104+ } ;
105+ let result = app. register_function ( second_register_payload) . await ;
106+ assert ! ( result. is_err( ) ) ;
107+ assert ! ( result. unwrap_err( ) . to_string( ) . contains( "Cannot register after function called" ) ) ;
108+ }
0 commit comments