rhai/tests/side_effects.rs

82 lines
2.2 KiB
Rust
Raw Normal View History

2020-03-22 03:18:16 +01:00
///! This test simulates an external command object that is driven by a script.
use rhai::{Engine, EvalAltResult, Scope, INT};
2020-06-22 03:46:36 +02:00
use std::sync::{Arc, Mutex, RwLock};
2020-06-22 03:46:36 +02:00
/// Simulate a command object.
2020-03-22 03:18:16 +01:00
struct Command {
2020-06-22 03:46:36 +02:00
/// Simulate an external state.
2020-08-05 18:24:25 +02:00
state: INT,
2020-03-22 03:18:16 +01:00
}
impl Command {
/// Do some action.
2020-08-05 18:24:25 +02:00
pub fn action(&mut self, val: INT) {
2020-03-22 03:18:16 +01:00
self.state = val;
}
/// Get current value.
2020-08-05 18:24:25 +02:00
pub fn get(&self) -> INT {
2020-03-22 03:18:16 +01:00
self.state
}
}
2020-06-22 03:46:36 +02:00
type API = Arc<Mutex<Command>>;
#[cfg(not(feature = "no_object"))]
#[test]
fn test_side_effects_command() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new();
let mut scope = Scope::new();
2020-06-21 18:03:45 +02:00
// Create the command object with initial state, handled by an `Arc`.
let command = Arc::new(Mutex::new(Command { state: 12 }));
assert_eq!(command.lock().unwrap().get(), 12);
2020-06-22 03:46:36 +02:00
// Create the API object.
let api = command.clone(); // Notice this clones the `Arc` only
2020-06-22 03:46:36 +02:00
// Make the API object a singleton in the script environment.
scope.push_constant("Command", api);
2020-03-22 03:18:16 +01:00
// Register type.
2020-06-22 03:46:36 +02:00
engine.register_type_with_name::<API>("CommandType");
2020-08-05 18:24:25 +02:00
engine.register_fn("action", |api: &mut API, x: INT| {
2020-06-22 03:46:36 +02:00
let mut command = api.lock().unwrap();
let val = command.get();
command.action(val + x);
});
engine.register_get("value", |command: &mut API| command.lock().unwrap().get());
2020-03-22 03:18:16 +01:00
assert_eq!(
engine.eval_with_scope::<INT>(
&mut scope,
2021-04-20 06:01:35 +02:00
"
2020-03-22 03:18:16 +01:00
// Drive the command object via the wrapper
Command.action(30);
Command.value
"
)?,
42
);
2020-03-22 03:18:16 +01:00
// Make sure the actions are properly performed
assert_eq!(command.lock().unwrap().get(), 42);
Ok(())
}
#[test]
fn test_side_effects_print() -> Result<(), Box<EvalAltResult>> {
let result = Arc::new(RwLock::new(String::new()));
2020-04-16 17:31:48 +02:00
let mut engine = Engine::new();
2020-04-16 17:31:48 +02:00
// Override action of 'print' function
let logger = result.clone();
engine.on_print(move |s| logger.write().unwrap().push_str(s));
engine.run("print(40 + 2);")?;
assert_eq!(*result.read().unwrap(), "42");
Ok(())
}