mlua/tests/thread.rs

122 lines
3.8 KiB
Rust
Raw Normal View History

extern crate rlua;
2018-02-09 23:52:05 -05:00
use std::panic::catch_unwind;
use rlua::{Error, Function, Lua, Result, Thread, ThreadStatus};
2018-02-09 23:52:05 -05:00
#[test]
fn test_thread() {
let lua = Lua::new();
2018-08-05 09:51:39 -04:00
let thread =
lua.create_thread(
lua.eval::<Function>(
r#"
2018-02-09 23:52:05 -05:00
function (s)
local sum = s
for i = 1,4 do
sum = sum + coroutine.yield(sum)
end
return sum
end
"#,
2018-08-05 09:51:39 -04:00
None,
).unwrap(),
).unwrap();
2018-02-09 23:52:05 -05:00
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(0).unwrap(), 0);
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(1).unwrap(), 1);
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(2).unwrap(), 3);
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(3).unwrap(), 6);
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(4).unwrap(), 10);
assert_eq!(thread.status(), ThreadStatus::Unresumable);
2018-08-05 09:51:39 -04:00
let accumulate =
lua.create_thread(
lua.eval::<Function>(
r#"
2018-02-09 23:52:05 -05:00
function (sum)
while true do
sum = sum + coroutine.yield(sum)
end
end
"#,
2018-08-05 09:51:39 -04:00
None,
).unwrap(),
).unwrap();
2018-02-09 23:52:05 -05:00
for i in 0..4 {
accumulate.resume::<_, ()>(i).unwrap();
}
assert_eq!(accumulate.resume::<_, i64>(4).unwrap(), 10);
assert_eq!(accumulate.status(), ThreadStatus::Resumable);
assert!(accumulate.resume::<_, ()>("error").is_err());
assert_eq!(accumulate.status(), ThreadStatus::Error);
2018-08-05 09:51:39 -04:00
let thread =
lua.eval::<Thread>(
r#"
2018-02-09 23:52:05 -05:00
coroutine.create(function ()
while true do
coroutine.yield(42)
end
end)
"#,
2018-08-05 09:51:39 -04:00
None,
).unwrap();
2018-02-09 23:52:05 -05:00
assert_eq!(thread.status(), ThreadStatus::Resumable);
assert_eq!(thread.resume::<_, i64>(()).unwrap(), 42);
2018-08-05 09:51:39 -04:00
let thread: Thread =
lua.eval(
r#"
2018-02-09 23:52:05 -05:00
coroutine.create(function(arg)
assert(arg == 42)
local yieldarg = coroutine.yield(123)
assert(yieldarg == 43)
return 987
end)
"#,
2018-08-05 09:51:39 -04:00
None,
).unwrap();
2018-02-09 23:52:05 -05:00
assert_eq!(thread.resume::<_, u32>(42).unwrap(), 123);
assert_eq!(thread.resume::<_, u32>(43).unwrap(), 987);
match thread.resume::<_, u32>(()) {
Err(Error::CoroutineInactive) => {}
Err(_) => panic!("resuming dead coroutine error is not CoroutineInactive kind"),
_ => panic!("resuming dead coroutine did not return error"),
}
}
#[test]
fn coroutine_from_closure() {
let lua = Lua::new();
let thrd_main = lua.create_function(|_, ()| Ok(())).unwrap();
lua.globals().set("main", thrd_main).unwrap();
let thrd: Thread = lua.eval("coroutine.create(main)", None).unwrap();
thrd.resume::<_, ()>(()).unwrap();
}
#[test]
fn coroutine_panic() {
match catch_unwind(|| -> Result<()> {
// check that coroutines propagate panics correctly
let lua = Lua::new();
let thrd_main = lua.create_function(|_, ()| -> Result<()> {
panic!("test_panic");
})?;
lua.globals().set("main", thrd_main.clone())?;
let thrd: Thread = lua.create_thread(thrd_main)?;
thrd.resume(())
}) {
2018-02-09 23:52:05 -05:00
Ok(r) => panic!("coroutine panic not propagated, instead returned {:?}", r),
Err(p) => assert!(*p.downcast::<&str>().unwrap() == "test_panic"),
2018-02-09 23:52:05 -05:00
}
}