#![cfg(all(feature = "send", feature = "async"))]
use std::time::Duration;
use luaur_rt::{AsyncThread, Lua, Result};
fn assert_send<T: Send>() {}
#[test]
fn test_async_driver_is_send() {
assert_send::<Lua>();
assert_send::<AsyncThread<i64>>();
assert_send::<AsyncThread<()>>();
}
#[test]
fn test_move_vm_then_drive_pending_async_on_worker_thread() -> Result<()> {
let lua = Lua::new();
let f = lua.create_async_function(|_lua, (a, b): (i64, i64)| async move {
tokio::time::sleep(Duration::from_millis(10)).await;
Ok(a + b)
})?;
lua.globals().set("add", f)?;
let handle = std::thread::spawn(move || -> Result<i64> {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.expect("failed to build tokio runtime on worker thread");
rt.block_on(async move { lua.load("return add(40, 2)").eval_async().await })
});
let result = handle.join().expect("worker thread panicked")?;
assert_eq!(result, 42);
Ok(())
}
#[test]
fn test_async_callback_captures_send_data() -> Result<()> {
let payload: Vec<i64> = std::thread::spawn(|| vec![10, 20, 30])
.join()
.expect("worker panicked");
let lua = Lua::new();
let sum = lua.create_async_function(move |_lua, ()| {
let payload = payload.clone();
async move {
tokio::time::sleep(Duration::from_millis(1)).await;
Ok(payload.iter().sum::<i64>())
}
})?;
lua.globals().set("sum", sum)?;
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.expect("failed to build tokio runtime");
let total: i64 = rt.block_on(async { lua.load("return sum()").eval_async().await })?;
assert_eq!(total, 60);
Ok(())
}