more efforts to automate rhai bindings
This commit is contained in:
@@ -1,15 +1,23 @@
|
||||
use rhai_wrapper::wrap_for_rhai;
|
||||
use rhai_wrapper::{ToRhaiMap, FromRhaiMap};
|
||||
use rhai::{CustomType, TypeBuilder, Engine, INT, FLOAT, Array};
|
||||
use rhai_macros_derive::{ToRhaiMap as ToRhaiMapDerive, FromRhaiMap as FromRhaiMapDerive};
|
||||
use rhai_macros_derive::{ToRhaiMap as ToRhaiMapDerive, FromRhaiMap as FromRhaiMapDerive, export_fn};
|
||||
|
||||
#[export_fn(rhai_name = "add_rhai")]
|
||||
fn add(a: INT, b: INT) -> INT { a + b }
|
||||
#[export_fn(rhai_name = "mul_rhai")]
|
||||
fn mul(a: INT, b: INT) -> INT { a * b }
|
||||
#[export_fn(rhai_name = "greet_rhai")]
|
||||
fn greet(name: String) -> String { format!("Hello, {name}!") }
|
||||
#[export_fn(rhai_name = "get_forty_two_rhai")]
|
||||
fn get_forty_two() -> INT { 42 }
|
||||
#[export_fn(rhai_name = "shout_rhai")]
|
||||
fn shout() -> String { "HEY!".to_string() }
|
||||
#[export_fn(rhai_name = "add_float_rhai")]
|
||||
fn add_float(a: FLOAT, b: FLOAT) -> FLOAT { a + b }
|
||||
#[export_fn(rhai_name = "is_even_rhai")]
|
||||
fn is_even(n: INT) -> bool { n % 2 == 0 }
|
||||
#[export_fn(rhai_name = "maybe_add_rhai")]
|
||||
fn maybe_add(a: INT, b: INT, do_add: bool) -> Option<INT> { if do_add { Some(a + b) } else { None } }
|
||||
|
||||
// Renamed from sum_vec, takes rhai::Array
|
||||
@@ -110,69 +118,83 @@ fn get_polygon_id_and_num_vertices(poly: Polygon) -> String {
|
||||
#[test]
|
||||
fn test_add() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("add", wrap_for_rhai!(add));
|
||||
let result = engine.eval::<INT>("add(2, 3)").unwrap();
|
||||
engine.register_fn("add_rhai", add_rhai_wrapper);
|
||||
let result = engine.eval::<INT>("add_rhai(2, 3)").unwrap();
|
||||
assert_eq!(result, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mul() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("mul", wrap_for_rhai!(mul));
|
||||
let result = engine.eval::<INT>("mul(4, 5)").unwrap();
|
||||
engine.register_fn("mul_rhai", mul_rhai_wrapper);
|
||||
let result = engine.eval::<INT>("mul_rhai(4, 5)").unwrap();
|
||||
assert_eq!(result, 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_greet() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("greet", wrap_for_rhai!(greet));
|
||||
let result = engine.eval::<String>(r#"greet("Alice")"#).unwrap();
|
||||
engine.register_fn("greet_rhai", greet_rhai_wrapper);
|
||||
let result = engine.eval::<String>(r#"greet_rhai("Alice")"#).unwrap();
|
||||
assert_eq!(result, "Hello, Alice!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_forty_two() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("get_forty_two", wrap_for_rhai!(get_forty_two));
|
||||
let result = engine.eval::<INT>("get_forty_two()").unwrap();
|
||||
engine.register_fn("get_forty_two_rhai", get_forty_two_rhai_wrapper);
|
||||
let result = engine.eval::<INT>("get_forty_two_rhai()").unwrap();
|
||||
assert_eq!(result, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shout() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("shout", wrap_for_rhai!(shout));
|
||||
let result = engine.eval::<String>("shout()").unwrap();
|
||||
engine.register_fn("shout_rhai", shout_rhai_wrapper);
|
||||
let result = engine.eval::<String>("shout_rhai()").unwrap();
|
||||
assert_eq!(result, "HEY!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_float() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("add_float", wrap_for_rhai!(add_float));
|
||||
let result = engine.eval::<FLOAT>("add_float(1.5, 2.25)").unwrap();
|
||||
assert!((result - 3.75).abs() < 1e-8);
|
||||
engine.register_fn("add_float_rhai", add_float_rhai_wrapper);
|
||||
let result = engine.eval::<FLOAT>("add_float_rhai(2.5, 3.5)").unwrap();
|
||||
assert_eq!(result, 6.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_even() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("is_even", wrap_for_rhai!(is_even));
|
||||
let result = engine.eval::<bool>("is_even(4)").unwrap();
|
||||
assert!(result);
|
||||
let result = engine.eval::<bool>("is_even(5)").unwrap();
|
||||
assert!(!result);
|
||||
engine.register_fn("is_even_rhai", is_even_rhai_wrapper);
|
||||
let result_true = engine.eval::<bool>("is_even_rhai(4)").unwrap();
|
||||
assert_eq!(result_true, true);
|
||||
let result_false = engine.eval::<bool>("is_even_rhai(3)").unwrap();
|
||||
assert_eq!(result_false, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maybe_add() {
|
||||
let mut engine = Engine::new();
|
||||
engine.register_fn("maybe_add", wrap_for_rhai!(maybe_add));
|
||||
let result = engine.eval::<Option<INT>>("maybe_add(2, 3, true)").unwrap();
|
||||
assert_eq!(result, Some(5));
|
||||
let result = engine.eval::<Option<INT>>("maybe_add(2, 3, false)").unwrap();
|
||||
assert_eq!(result, None);
|
||||
engine.register_fn("maybe_add_rhai", maybe_add_rhai_wrapper);
|
||||
|
||||
// Test case where None is returned (expecting an error or specific handling in Rhai)
|
||||
// Rhai treats Option::None as an empty Dynamic, which can lead to type mismatch if not handled.
|
||||
// For now, let's check if the script produces a specific type or if it can be evaluated to Dynamic.
|
||||
// If the function returns None, eval might return an error if trying to cast to INT.
|
||||
// Let's eval to Dynamic and check if it's empty (Rhai's representation of None).
|
||||
let result_none = engine.eval::<rhai::Dynamic>("maybe_add_rhai(2, 3, false)").unwrap();
|
||||
|
||||
// Debug prints
|
||||
println!("Debug [test_maybe_add]: result_none = {:?}", result_none);
|
||||
println!("Debug [test_maybe_add]: result_none.type_name() = {}", result_none.type_name());
|
||||
println!("Debug [test_maybe_add]: result_none.is::<()>() = {}", result_none.is::<()>());
|
||||
|
||||
assert!(result_none.is_unit(), "Expected Rhai None (unit Dynamic)");
|
||||
|
||||
// Test case where Some is returned
|
||||
let result_some = engine.eval::<INT>("maybe_add_rhai(2, 3, true)").unwrap();
|
||||
assert_eq!(result_some, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -502,21 +524,20 @@ mod new_export_fn_tests {
|
||||
assert_eq!(result, 15);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_export_fn_custom_type_arg_return() { // This test was commented out, keeping as is for now
|
||||
// let mut engine = Engine::new();
|
||||
// engine.build_type::<Point>();
|
||||
// // engine.register_fn("offset_simple_point", offset_simple_point_rhai_wrapper);
|
||||
#[test]
|
||||
fn test_export_fn_custom_type_arg_return_new() {
|
||||
let mut engine = Engine::new();
|
||||
engine.build_type::<Point>();
|
||||
engine.register_fn("offset_simple_point", offset_simple_point_rhai_wrapper);
|
||||
|
||||
// // let script = r#"
|
||||
// // let p = #{ x: 10, y: 20 };
|
||||
// // let p_offset = offset_simple_point(p, 5);
|
||||
// // p_offset.x
|
||||
// // "#;
|
||||
// // let result = engine.eval::<INT>(script).unwrap();
|
||||
// // assert_eq!(result, 15);
|
||||
|
||||
// }
|
||||
let script = r#"
|
||||
let p = #{ x: 10, y: 20 };
|
||||
let p_offset = offset_simple_point(p, 5);
|
||||
p_offset.x
|
||||
"#;
|
||||
let result = engine.eval::<INT>(script).unwrap();
|
||||
assert_eq!(result, 15);
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, FromRhaiMapDerive, ToRhaiMapDerive, CustomType)]
|
||||
@@ -556,17 +577,4 @@ mod new_export_fn_tests {
|
||||
assert_eq!(result_struct.optional_nested_vec.as_ref().unwrap().len(), 1);
|
||||
assert_eq!(result_struct.optional_nested_vec.as_ref().unwrap()[0], SampleStruct { value: 3, name: "n3".to_string() });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_export_fn_custom_type_arg_return_new() {
|
||||
let mut engine = Engine::new();
|
||||
engine.build_type::<Point>();
|
||||
engine.register_fn("offset_simple_point", offset_simple_point_rhai_wrapper);
|
||||
|
||||
let script = r#"
|
||||
42
|
||||
"#;
|
||||
let result = engine.eval::<INT>(script).unwrap();
|
||||
assert_eq!(result, 42);
|
||||
}
|
||||
}
|
||||
|
709
rhai_wrapper/tests/wrapper_macros_test.rs
Normal file
709
rhai_wrapper/tests/wrapper_macros_test.rs
Normal file
@@ -0,0 +1,709 @@
|
||||
use rhai::{Engine, INT, FLOAT, Dynamic, Map, Array, EvalAltResult, CustomType, TypeBuilder};
|
||||
use rhai_wrapper::{
|
||||
wrap_option_return, wrap_vec_return, wrap_option_vec_return,
|
||||
wrap_option_return_result, wrap_vec_return_result, wrap_option_vec_return_result,
|
||||
wrap_option_method_result, wrap_vec_method_result, wrap_option_vec_method_result,
|
||||
ToRhaiMap, FromRhaiMap
|
||||
};
|
||||
use rhai_macros_derive::{ToRhaiMap as ToRhaiMapDerive, FromRhaiMap as FromRhaiMapDerive};
|
||||
use std::fmt;
|
||||
|
||||
// Test structs
|
||||
#[derive(Debug, Clone, PartialEq, CustomType, ToRhaiMapDerive, FromRhaiMapDerive)]
|
||||
struct User {
|
||||
id: INT,
|
||||
name: String,
|
||||
age: INT,
|
||||
}
|
||||
|
||||
impl User {
|
||||
fn to_rhai_map(&self) -> Map {
|
||||
let mut map = Map::new();
|
||||
map.insert("id".into(), self.id.into());
|
||||
map.insert("name".into(), self.name.clone().into());
|
||||
map.insert("age".into(), self.age.into());
|
||||
map
|
||||
}
|
||||
|
||||
fn from_rhai_map(map: Map) -> Result<Self, String> {
|
||||
let id = map.get("id")
|
||||
.and_then(|d| d.as_int().ok())
|
||||
.ok_or_else(|| "Field 'id' not found or not an INT".to_string())?;
|
||||
|
||||
let name = map.get("name")
|
||||
.and_then(|d| d.clone().into_string().ok())
|
||||
.ok_or_else(|| "Field 'name' not found or not a String".to_string())?;
|
||||
|
||||
let age = map.get("age")
|
||||
.and_then(|d| d.as_int().ok())
|
||||
.ok_or_else(|| "Field 'age' not found or not an INT".to_string())?;
|
||||
|
||||
Ok(User { id, name, age })
|
||||
}
|
||||
}
|
||||
|
||||
// Mock DB connection type
|
||||
struct OurDB {
|
||||
// Some mock state
|
||||
error_mode: bool,
|
||||
}
|
||||
|
||||
impl OurDB {
|
||||
fn new(error_mode: bool) -> Self {
|
||||
OurDB { error_mode }
|
||||
}
|
||||
}
|
||||
|
||||
// Custom error type for testing
|
||||
#[derive(Debug)]
|
||||
struct DBError {
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for DBError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "DB Error: {}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
// Test functions for wrap_option_return
|
||||
fn get_user_by_id(_db: &OurDB, id: INT) -> Option<User> {
|
||||
if id > 0 {
|
||||
Some(User { id, name: format!("User {}", id), age: 30 })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Test functions for wrap_vec_return
|
||||
fn get_all_users(_db: &OurDB) -> Vec<User> {
|
||||
vec![
|
||||
User { id: 1, name: "User 1".to_string(), age: 30 },
|
||||
User { id: 2, name: "User 2".to_string(), age: 25 },
|
||||
]
|
||||
}
|
||||
|
||||
fn get_users_by_age(_db: &OurDB, min_age: INT) -> Vec<User> {
|
||||
vec![
|
||||
User { id: 1, name: "User 1".to_string(), age: 30 },
|
||||
User { id: 2, name: "User 2".to_string(), age: 25 },
|
||||
].into_iter().filter(|u| u.age >= min_age).collect()
|
||||
}
|
||||
|
||||
fn get_all_user_ids() -> Vec<INT> {
|
||||
vec![1, 2, 3]
|
||||
}
|
||||
|
||||
// Test functions for wrap_option_vec_return
|
||||
fn find_users_by_name(_db: &OurDB, name_part: String) -> Option<Vec<User>> {
|
||||
if name_part.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(vec![
|
||||
User { id: 1, name: format!("{} One", name_part), age: 30 },
|
||||
User { id: 2, name: format!("{} Two", name_part), age: 25 },
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
// Test functions for result-returning wrappers
|
||||
fn get_user_by_id_result(db: &OurDB, id: INT) -> Result<Option<User>, DBError> {
|
||||
if db.error_mode {
|
||||
Err(DBError { message: "DB connection error".to_string() })
|
||||
} else if id > 0 {
|
||||
Ok(Some(User { id, name: format!("User {}", id), age: 30 }))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_all_users_result(db: &OurDB) -> Result<Vec<User>, DBError> {
|
||||
if db.error_mode {
|
||||
Err(DBError { message: "DB connection error".to_string() })
|
||||
} else {
|
||||
Ok(vec![
|
||||
User { id: 1, name: "User 1".to_string(), age: 30 },
|
||||
User { id: 2, name: "User 2".to_string(), age: 25 },
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
fn find_users_by_name_result(db: &OurDB, name_part: String) -> Result<Option<Vec<User>>, DBError> {
|
||||
if db.error_mode {
|
||||
Err(DBError { message: "DB connection error".to_string() })
|
||||
} else if name_part.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(vec![
|
||||
User { id: 1, name: format!("{} One", name_part), age: 30 },
|
||||
User { id: 2, name: format!("{} Two", name_part), age: 25 },
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
// Test methods for method wrappers
|
||||
struct UserCollection {
|
||||
users: Vec<User>,
|
||||
error_mode: bool,
|
||||
}
|
||||
|
||||
impl UserCollection {
|
||||
fn new(error_mode: bool) -> Self {
|
||||
UserCollection {
|
||||
users: vec![
|
||||
User { id: 1, name: "User 1".to_string(), age: 30 },
|
||||
User { id: 2, name: "User 2".to_string(), age: 25 },
|
||||
],
|
||||
error_mode,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_by_id(&self, id: INT) -> Result<Option<User>, DBError> {
|
||||
if self.error_mode {
|
||||
Err(DBError { message: "Collection error".to_string() })
|
||||
} else {
|
||||
Ok(self.users.iter().find(|u| u.id == id).cloned())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_all(&self) -> Result<Vec<User>, DBError> {
|
||||
if self.error_mode {
|
||||
Err(DBError { message: "Collection error".to_string() })
|
||||
} else {
|
||||
Ok(self.users.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn find_by_name(&self, name_part: String) -> Result<Option<Vec<User>>, DBError> {
|
||||
if self.error_mode {
|
||||
Err(DBError { message: "Collection error".to_string() })
|
||||
} else if name_part.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(self.users.iter()
|
||||
.filter(|u| u.name.contains(&name_part))
|
||||
.cloned()
|
||||
.collect()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_return() {
|
||||
let mut engine = Engine::new();
|
||||
let db = OurDB::new(false);
|
||||
|
||||
// Register the wrapped function
|
||||
engine.register_fn(
|
||||
"get_user_by_id_rhai",
|
||||
wrap_option_return!(get_user_by_id, &OurDB, INT => User)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with existing user
|
||||
let script1 = r#"
|
||||
let user = get_user_by_id_rhai(db, 1);
|
||||
user.id
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"user.id",
|
||||
(db.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 1);
|
||||
|
||||
// Test with non-existing user
|
||||
let script2 = r#"
|
||||
let user = get_user_by_id_rhai(db, 0);
|
||||
if user == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if user == () { 42 } else { 0 }",
|
||||
(db, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_vec_return() {
|
||||
let mut engine = Engine::new();
|
||||
let db = OurDB::new(false);
|
||||
|
||||
// Register the wrapped functions
|
||||
engine.register_fn(
|
||||
"get_all_users_rhai",
|
||||
wrap_vec_return!(get_all_users, &OurDB => User)
|
||||
);
|
||||
|
||||
engine.register_fn(
|
||||
"get_users_by_age_rhai",
|
||||
wrap_vec_return!(get_users_by_age, &OurDB, INT => User)
|
||||
);
|
||||
|
||||
engine.register_fn(
|
||||
"get_all_user_ids_rhai",
|
||||
wrap_vec_return!(get_all_user_ids, () => INT)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test get_all_users
|
||||
let script1 = r#"
|
||||
let users = get_all_users_rhai(db);
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(db.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test get_users_by_age
|
||||
let script2 = r#"
|
||||
let users = get_users_by_age_rhai(db, 30);
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"users.len()",
|
||||
(db, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 1);
|
||||
|
||||
// Test get_all_user_ids
|
||||
let script3 = r#"
|
||||
let ids = get_all_user_ids_rhai();
|
||||
ids.len()
|
||||
"#;
|
||||
|
||||
let result3 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script3,
|
||||
"ids.len()",
|
||||
()
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result3, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_vec_return() {
|
||||
let mut engine = Engine::new();
|
||||
let db = OurDB::new(false);
|
||||
|
||||
// Register the wrapped function
|
||||
engine.register_fn(
|
||||
"find_users_by_name_rhai",
|
||||
wrap_option_vec_return!(find_users_by_name, &OurDB, String => User)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with found users
|
||||
let script1 = r#"
|
||||
let users = find_users_by_name_rhai(db, "User");
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(db.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test with no users found
|
||||
let script2 = r#"
|
||||
let users = find_users_by_name_rhai(db, "");
|
||||
if users == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if users == () { 42 } else { 0 }",
|
||||
(db, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_return_result() {
|
||||
let mut engine = Engine::new();
|
||||
let db_ok = OurDB::new(false);
|
||||
let db_err = OurDB::new(true);
|
||||
|
||||
// Register the wrapped function
|
||||
engine.register_result_fn(
|
||||
"get_user_by_id_result_rhai",
|
||||
wrap_option_return_result!(get_user_by_id_result, &OurDB, INT => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with existing user
|
||||
let script1 = r#"
|
||||
let user = get_user_by_id_result_rhai(db, 1);
|
||||
user.id
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"user.id",
|
||||
(db_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 1);
|
||||
|
||||
// Test with non-existing user
|
||||
let script2 = r#"
|
||||
let user = get_user_by_id_result_rhai(db, 0);
|
||||
if user == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if user == () { 42 } else { 0 }",
|
||||
(db_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
|
||||
// Test with error
|
||||
let script3 = r#"
|
||||
try {
|
||||
let user = get_user_by_id_result_rhai(db, 1);
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("DB connection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result3 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script3,
|
||||
"try_catch_block",
|
||||
(db_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result3, 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_vec_return_result() {
|
||||
let mut engine = Engine::new();
|
||||
let db_ok = OurDB::new(false);
|
||||
let db_err = OurDB::new(true);
|
||||
|
||||
// Register the wrapped function
|
||||
engine.register_result_fn(
|
||||
"get_all_users_result_rhai",
|
||||
wrap_vec_return_result!(get_all_users_result, &OurDB => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with successful result
|
||||
let script1 = r#"
|
||||
let users = get_all_users_result_rhai(db);
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(db_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test with error
|
||||
let script2 = r#"
|
||||
try {
|
||||
let users = get_all_users_result_rhai(db);
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("DB connection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"try_catch_block",
|
||||
(db_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_vec_return_result() {
|
||||
let mut engine = Engine::new();
|
||||
let db_ok = OurDB::new(false);
|
||||
let db_err = OurDB::new(true);
|
||||
|
||||
// Register the wrapped function
|
||||
engine.register_result_fn(
|
||||
"find_users_by_name_result_rhai",
|
||||
wrap_option_vec_return_result!(find_users_by_name_result, &OurDB, String => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with found users
|
||||
let script1 = r#"
|
||||
let users = find_users_by_name_result_rhai(db, "User");
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(db_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test with no users found
|
||||
let script2 = r#"
|
||||
let users = find_users_by_name_result_rhai(db, "");
|
||||
if users == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if users == () { 42 } else { 0 }",
|
||||
(db_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
|
||||
// Test with error
|
||||
let script3 = r#"
|
||||
try {
|
||||
let users = find_users_by_name_result_rhai(db, "User");
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("DB connection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result3 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script3,
|
||||
"try_catch_block",
|
||||
(db_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result3, 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_method_result() {
|
||||
let mut engine = Engine::new();
|
||||
let collection_ok = UserCollection::new(false);
|
||||
let collection_err = UserCollection::new(true);
|
||||
|
||||
// Register the wrapped method
|
||||
engine.register_result_fn(
|
||||
"get_by_id_rhai",
|
||||
wrap_option_method_result!(get_by_id, &UserCollection, INT => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with existing user
|
||||
let script1 = r#"
|
||||
let user = get_by_id_rhai(collection, 1);
|
||||
user.id
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"user.id",
|
||||
(collection_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 1);
|
||||
|
||||
// Test with non-existing user
|
||||
let script2 = r#"
|
||||
let user = get_by_id_rhai(collection, 999);
|
||||
if user == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if user == () { 42 } else { 0 }",
|
||||
(collection_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
|
||||
// Test with error
|
||||
let script3 = r#"
|
||||
try {
|
||||
let user = get_by_id_rhai(collection, 1);
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("Collection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result3 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script3,
|
||||
"try_catch_block",
|
||||
(collection_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result3, 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_vec_method_result() {
|
||||
let mut engine = Engine::new();
|
||||
let collection_ok = UserCollection::new(false);
|
||||
let collection_err = UserCollection::new(true);
|
||||
|
||||
// Register the wrapped method
|
||||
engine.register_result_fn(
|
||||
"get_all_rhai",
|
||||
wrap_vec_method_result!(get_all, &UserCollection => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with successful result
|
||||
let script1 = r#"
|
||||
let users = get_all_rhai(collection);
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(collection_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test with error
|
||||
let script2 = r#"
|
||||
try {
|
||||
let users = get_all_rhai(collection);
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("Collection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"try_catch_block",
|
||||
(collection_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_option_vec_method_result() {
|
||||
let mut engine = Engine::new();
|
||||
let collection_ok = UserCollection::new(false);
|
||||
let collection_err = UserCollection::new(true);
|
||||
|
||||
// Register the wrapped method
|
||||
engine.register_result_fn(
|
||||
"find_by_name_rhai",
|
||||
wrap_option_vec_method_result!(find_by_name, &UserCollection, String => User, DBError)
|
||||
);
|
||||
|
||||
// Register the User type
|
||||
engine.build_type::<User>();
|
||||
|
||||
// Test with found users
|
||||
let script1 = r#"
|
||||
let users = find_by_name_rhai(collection, "User");
|
||||
users.len()
|
||||
"#;
|
||||
|
||||
let result1 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script1,
|
||||
"users.len()",
|
||||
(collection_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result1, 2);
|
||||
|
||||
// Test with no users found
|
||||
let script2 = r#"
|
||||
let users = find_by_name_rhai(collection, "");
|
||||
if users == () { 42 } else { 0 }
|
||||
"#;
|
||||
|
||||
let result2 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script2,
|
||||
"if users == () { 42 } else { 0 }",
|
||||
(collection_ok.clone(), )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result2, 42);
|
||||
|
||||
// Test with error
|
||||
let script3 = r#"
|
||||
try {
|
||||
let users = find_by_name_rhai(collection, "User");
|
||||
0
|
||||
} catch(err) {
|
||||
if err.contains("Collection error") { 99 } else { 0 }
|
||||
}
|
||||
"#;
|
||||
|
||||
let result3 = engine.call_fn::<INT>(
|
||||
&mut rhai::Scope::new(),
|
||||
script3,
|
||||
"try_catch_block",
|
||||
(collection_err, )
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(result3, 99);
|
||||
}
|
Reference in New Issue
Block a user