diff --git a/tests/static.rs b/tests/static.rs new file mode 100644 index 0000000..471debd --- /dev/null +++ b/tests/static.rs @@ -0,0 +1,113 @@ +use std::cell::RefCell; + +use mlua::{Function, Lua, Result, Table}; + +#[test] +fn test_static_lua() -> Result<()> { + let lua = Lua::new().into_static(); + + thread_local! { + static TABLE: RefCell>> = RefCell::new(None); + } + + let f = lua.create_function(|_, table: Table| { + TABLE.with(|t| { + table.raw_insert(1, "hello")?; + *t.borrow_mut() = Some(table); + Ok(()) + }) + })?; + + f.call(lua.create_table()?)?; + drop(f); + lua.gc_collect()?; + + TABLE.with(|t| { + assert!(t.borrow().as_ref().unwrap().len().unwrap() == 1); + *t.borrow_mut() = None; + }); + + // Consume the Lua instance + unsafe { Lua::from_static(lua) }; + + Ok(()) +} + +#[test] +fn test_static_lua_coroutine() -> Result<()> { + let lua = Lua::new().into_static(); + + thread_local! { + static TABLE: RefCell>> = RefCell::new(None); + } + + let f = lua.create_function(|_, table: Table| { + TABLE.with(|t| { + table.raw_insert(1, "hello")?; + *t.borrow_mut() = Some(table); + Ok(()) + }) + })?; + + let co = lua.create_thread(f)?; + co.resume::<_, ()>(lua.create_table()?)?; + drop(co); + lua.gc_collect()?; + + TABLE.with(|t| { + assert_eq!( + t.borrow().as_ref().unwrap().get::<_, String>(1i32).unwrap(), + "hello".to_string() + ); + *t.borrow_mut() = None; + }); + + // Consume the Lua instance + unsafe { Lua::from_static(lua) }; + + Ok(()) +} + +#[cfg(feature = "async")] +#[tokio::test] +async fn test_static_async() -> Result<()> { + let lua = Lua::new().into_static(); + + let timer = lua.create_async_function(|_, (i, n, f): (u64, u64, Function)| async move { + tokio::task::spawn_local(async move { + let dur = std::time::Duration::from_millis(i); + for _ in 0..n { + tokio::task::spawn_local(f.call_async::<(), ()>(())); + tokio::time::sleep(dur).await; + } + }); + Ok(()) + })?; + lua.globals().set("timer", timer)?; + + { + let local_set = tokio::task::LocalSet::new(); + local_set + .run_until( + lua.load( + r#" + local cnt = 0 + timer(1, 100, function() + cnt = cnt + 1 + if cnt % 10 == 0 then + collectgarbage() + end + end) + "#, + ) + .exec_async(), + ) + .await?; + local_set.await; + } + + // Consume the Lua instance + unsafe { Lua::from_static(lua) }; + + Ok(()) +}