Update tests (excl. compile-fail)
This commit is contained in:
parent
45159bfda7
commit
54f4627195
|
@ -0,0 +1,53 @@
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type lua_State = libc::c_void;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type lua_CFunction = unsafe extern "C" fn(L: *mut lua_State) -> libc::c_int;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn luaL_newstate() -> *mut lua_State;
|
||||||
|
|
||||||
|
fn luaL_requiref(
|
||||||
|
L: *mut lua_State,
|
||||||
|
modname: *const libc::c_char,
|
||||||
|
openf: lua_CFunction,
|
||||||
|
glb: libc::c_int,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn lua_settop(L: *mut lua_State, idx: libc::c_int);
|
||||||
|
|
||||||
|
fn luaopen_base(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_coroutine(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_table(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_io(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_os(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_string(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_math(L: *mut lua_State) -> libc::c_int;
|
||||||
|
fn luaopen_package(L: *mut lua_State) -> libc::c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
fn make_lua() -> rlua::Lua {
|
||||||
|
macro_rules! cstr {
|
||||||
|
($s:expr) => {
|
||||||
|
concat!($s, "\0") as *const str as *const ::std::os::raw::c_char
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let state = luaL_newstate();
|
||||||
|
|
||||||
|
// Do not open the debug library, it can be used to cause unsafety.
|
||||||
|
luaL_requiref(state, cstr!("_G"), luaopen_base, 1);
|
||||||
|
luaL_requiref(state, cstr!("coroutine"), luaopen_coroutine, 1);
|
||||||
|
luaL_requiref(state, cstr!("table"), luaopen_table, 1);
|
||||||
|
luaL_requiref(state, cstr!("io"), luaopen_io, 1);
|
||||||
|
luaL_requiref(state, cstr!("os"), luaopen_os, 1);
|
||||||
|
luaL_requiref(state, cstr!("string"), luaopen_string, 1);
|
||||||
|
luaL_requiref(state, cstr!("math"), luaopen_math, 1);
|
||||||
|
luaL_requiref(state, cstr!("package"), luaopen_package, 1);
|
||||||
|
lua_settop(state, -8 - 1);
|
||||||
|
|
||||||
|
rlua::Lua::init_from_ptr(state)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
use bstr::{BStr, BString};
|
||||||
|
use rlua::Result;
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn byte_string_round_trip() -> Result<()> {
|
||||||
|
let lua = make_lua();
|
||||||
|
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
invalid_sequence_identifier = "\xa0\xa1"
|
||||||
|
invalid_2_octet_sequence_2nd = "\xc3\x28"
|
||||||
|
invalid_3_octet_sequence_2nd = "\xe2\x28\xa1"
|
||||||
|
invalid_3_octet_sequence_3rd = "\xe2\x82\x28"
|
||||||
|
invalid_4_octet_sequence_2nd = "\xf0\x28\x8c\xbc"
|
||||||
|
invalid_4_octet_sequence_3rd = "\xf0\x90\x28\xbc"
|
||||||
|
invalid_4_octet_sequence_4th = "\xf0\x28\x8c\x28"
|
||||||
|
|
||||||
|
an_actual_string = "Hello, world!"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()?;
|
||||||
|
|
||||||
|
let globals = lua.globals();
|
||||||
|
|
||||||
|
let isi = globals.get::<_, BString>("invalid_sequence_identifier")?;
|
||||||
|
assert_eq!(isi, [0xa0, 0xa1].as_ref());
|
||||||
|
|
||||||
|
let i2os2 = globals.get::<_, BString>("invalid_2_octet_sequence_2nd")?;
|
||||||
|
assert_eq!(i2os2, [0xc3, 0x28].as_ref());
|
||||||
|
|
||||||
|
let i3os2 = globals.get::<_, BString>("invalid_3_octet_sequence_2nd")?;
|
||||||
|
assert_eq!(i3os2, [0xe2, 0x28, 0xa1].as_ref());
|
||||||
|
|
||||||
|
let i3os3 = globals.get::<_, BString>("invalid_3_octet_sequence_3rd")?;
|
||||||
|
assert_eq!(i3os3, [0xe2, 0x82, 0x28].as_ref());
|
||||||
|
|
||||||
|
let i4os2 = globals.get::<_, BString>("invalid_4_octet_sequence_2nd")?;
|
||||||
|
assert_eq!(i4os2, [0xf0, 0x28, 0x8c, 0xbc].as_ref());
|
||||||
|
|
||||||
|
let i4os3 = globals.get::<_, BString>("invalid_4_octet_sequence_3rd")?;
|
||||||
|
assert_eq!(i4os3, [0xf0, 0x90, 0x28, 0xbc].as_ref());
|
||||||
|
|
||||||
|
let i4os4 = globals.get::<_, BString>("invalid_4_octet_sequence_4th")?;
|
||||||
|
assert_eq!(i4os4, [0xf0, 0x28, 0x8c, 0x28].as_ref());
|
||||||
|
|
||||||
|
let aas = globals.get::<_, BString>("an_actual_string")?;
|
||||||
|
assert_eq!(aas, b"Hello, world!".as_ref());
|
||||||
|
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_sequence_identifier", isi.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_2_octet_sequence_2nd", i2os2.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_3_octet_sequence_2nd", i3os2.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_3_octet_sequence_3rd", i3os3.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_4_octet_sequence_2nd", i4os2.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_4_octet_sequence_3rd", i4os3.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_invalid_4_octet_sequence_4th", i4os4.as_ref())?;
|
||||||
|
globals.set::<_, &BStr>("bstr_an_actual_string", aas.as_ref())?;
|
||||||
|
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
assert(bstr_invalid_sequence_identifier == invalid_sequence_identifier)
|
||||||
|
assert(bstr_invalid_2_octet_sequence_2nd == invalid_2_octet_sequence_2nd)
|
||||||
|
assert(bstr_invalid_3_octet_sequence_2nd == invalid_3_octet_sequence_2nd)
|
||||||
|
assert(bstr_invalid_3_octet_sequence_3rd == invalid_3_octet_sequence_3rd)
|
||||||
|
assert(bstr_invalid_4_octet_sequence_2nd == invalid_4_octet_sequence_2nd)
|
||||||
|
assert(bstr_invalid_4_octet_sequence_3rd == invalid_4_octet_sequence_3rd)
|
||||||
|
assert(bstr_invalid_4_octet_sequence_4th == invalid_4_octet_sequence_4th)
|
||||||
|
assert(bstr_an_actual_string == an_actual_string)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()?;
|
||||||
|
|
||||||
|
globals.set::<_, BString>("bstring_invalid_sequence_identifier", isi)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_2_octet_sequence_2nd", i2os2)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_3_octet_sequence_2nd", i3os2)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_3_octet_sequence_3rd", i3os3)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_4_octet_sequence_2nd", i4os2)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_4_octet_sequence_3rd", i4os3)?;
|
||||||
|
globals.set::<_, BString>("bstring_invalid_4_octet_sequence_4th", i4os4)?;
|
||||||
|
globals.set::<_, BString>("bstring_an_actual_string", aas)?;
|
||||||
|
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
assert(bstring_invalid_sequence_identifier == invalid_sequence_identifier)
|
||||||
|
assert(bstring_invalid_2_octet_sequence_2nd == invalid_2_octet_sequence_2nd)
|
||||||
|
assert(bstring_invalid_3_octet_sequence_2nd == invalid_3_octet_sequence_2nd)
|
||||||
|
assert(bstring_invalid_3_octet_sequence_3rd == invalid_3_octet_sequence_3rd)
|
||||||
|
assert(bstring_invalid_4_octet_sequence_2nd == invalid_4_octet_sequence_2nd)
|
||||||
|
assert(bstring_invalid_4_octet_sequence_3rd == invalid_4_octet_sequence_3rd)
|
||||||
|
assert(bstring_invalid_4_octet_sequence_4th == invalid_4_octet_sequence_4th)
|
||||||
|
assert(bstring_an_actual_string == an_actual_string)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -1,17 +1,14 @@
|
||||||
#![cfg(feature = "compiletest_rs")]
|
|
||||||
|
|
||||||
extern crate compiletest_rs as compiletest;
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn run_mode(mode: &'static str) {
|
fn run_mode(mode: &'static str) {
|
||||||
let mut config = compiletest::Config::default();
|
let mut config = compiletest_rs::Config::default();
|
||||||
|
|
||||||
config.mode = mode.parse().expect("Invalid mode");
|
config.mode = mode.parse().expect("Invalid mode");
|
||||||
config.src_base = PathBuf::from(format!("tests/{}", mode));
|
config.src_base = PathBuf::from(format!("tests/{}", mode));
|
||||||
config.target_rustcflags = Some("-L target/debug -L target/debug/deps".to_string());
|
config.link_deps();
|
||||||
|
config.clean_rmeta();
|
||||||
|
|
||||||
compiletest::run_tests(&config);
|
compiletest_rs::run_tests(&config);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,30 +1,33 @@
|
||||||
extern crate rlua;
|
use rlua::{Function, Result, String};
|
||||||
|
|
||||||
use rlua::{Function, Lua, String};
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_function() {
|
fn test_function() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function concat(arg1, arg2)
|
function concat(arg1, arg2)
|
||||||
return arg1 .. arg2
|
return arg1 .. arg2
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let concat = globals.get::<_, Function>("concat").unwrap();
|
let concat = globals.get::<_, Function>("concat")?;
|
||||||
assert_eq!(concat.call::<_, String>(("foo", "bar")).unwrap(), "foobar");
|
assert_eq!(concat.call::<_, String>(("foo", "bar"))?, "foobar");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bind() {
|
fn test_bind() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function concat(...)
|
function concat(...)
|
||||||
local res = ""
|
local res = ""
|
||||||
|
@ -34,25 +37,27 @@ fn test_bind() {
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let mut concat = globals.get::<_, Function>("concat").unwrap();
|
let mut concat = globals.get::<_, Function>("concat")?;
|
||||||
concat = concat.bind("foo").unwrap();
|
concat = concat.bind("foo")?;
|
||||||
concat = concat.bind("bar").unwrap();
|
concat = concat.bind("bar")?;
|
||||||
concat = concat.bind(("baz", "baf")).unwrap();
|
concat = concat.bind(("baz", "baf"))?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
concat.call::<_, String>(("hi", "wut")).unwrap(),
|
concat.call::<_, String>(("hi", "wut"))?,
|
||||||
"foobarbazbafhiwut"
|
"foobarbazbafhiwut"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rust_function() {
|
fn test_rust_function() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function lua_function()
|
function lua_function()
|
||||||
return rust_function()
|
return rust_function()
|
||||||
|
@ -61,13 +66,14 @@ fn test_rust_function() {
|
||||||
-- Test to make sure chunk return is ignored
|
-- Test to make sure chunk return is ignored
|
||||||
return 1
|
return 1
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let lua_function = globals.get::<_, Function>("lua_function").unwrap();
|
let lua_function = globals.get::<_, Function>("lua_function")?;
|
||||||
let rust_function = lua.create_function(|_, ()| Ok("hello")).unwrap();
|
let rust_function = lua.create_function(|_, ()| Ok("hello"))?;
|
||||||
|
|
||||||
globals.set("rust_function", rust_function).unwrap();
|
globals.set("rust_function", rust_function)?;
|
||||||
assert_eq!(lua_function.call::<_, String>(()).unwrap(), "hello");
|
assert_eq!(lua_function.call::<_, String>(())?, "hello");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rlua::{Error, Result, UserData};
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gc_control() -> Result<()> {
|
||||||
|
let lua = make_lua();
|
||||||
|
|
||||||
|
assert!(lua.gc_is_running());
|
||||||
|
lua.gc_stop();
|
||||||
|
assert!(!lua.gc_is_running());
|
||||||
|
lua.gc_restart();
|
||||||
|
assert!(lua.gc_is_running());
|
||||||
|
|
||||||
|
struct MyUserdata(Arc<()>);
|
||||||
|
impl UserData for MyUserdata {}
|
||||||
|
|
||||||
|
let rc = Arc::new(());
|
||||||
|
lua.globals()
|
||||||
|
.set("userdata", lua.create_userdata(MyUserdata(rc.clone()))?)?;
|
||||||
|
lua.globals().raw_remove("userdata")?;
|
||||||
|
|
||||||
|
assert_eq!(Arc::strong_count(&rc), 2);
|
||||||
|
lua.gc_collect()?;
|
||||||
|
lua.gc_collect()?;
|
||||||
|
assert_eq!(Arc::strong_count(&rc), 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gc_error() {
|
||||||
|
let lua = make_lua();
|
||||||
|
match lua
|
||||||
|
.load(
|
||||||
|
r#"
|
||||||
|
val = nil
|
||||||
|
table = {}
|
||||||
|
setmetatable(table, {
|
||||||
|
__gc = function()
|
||||||
|
error("gcwascalled")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
table = nil
|
||||||
|
collectgarbage("collect")
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()
|
||||||
|
{
|
||||||
|
Err(Error::GarbageCollectorError(_)) => {}
|
||||||
|
Err(e) => panic!("__gc error did not result in correct error, instead: {}", e),
|
||||||
|
Ok(()) => panic!("__gc error did not result in error"),
|
||||||
|
}
|
||||||
|
}
|
145
tests/scope.rs
145
tests/scope.rs
|
@ -1,44 +1,40 @@
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use rlua::{Error, Function, Lua, MetaMethod, String, UserData, UserDataMethods};
|
use rlua::{Error, Function, MetaMethod, Result, String, UserData, UserDataMethods};
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_func() {
|
fn scope_func() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let rc = Rc::new(Cell::new(0));
|
let rc = Rc::new(Cell::new(0));
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
let r = rc.clone();
|
let r = rc.clone();
|
||||||
let f = scope
|
let f = scope.create_function(move |_, ()| {
|
||||||
.create_function(move |_, ()| {
|
|
||||||
r.set(42);
|
r.set(42);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
lua.globals().set("bad", f.clone())?;
|
||||||
lua.globals().set("bad", f.clone()).unwrap();
|
f.call::<_, ()>(())?;
|
||||||
f.call::<_, ()>(()).unwrap();
|
|
||||||
assert_eq!(Rc::strong_count(&rc), 2);
|
assert_eq!(Rc::strong_count(&rc), 2);
|
||||||
});
|
Ok(())
|
||||||
|
})?;
|
||||||
assert_eq!(rc.get(), 42);
|
assert_eq!(rc.get(), 42);
|
||||||
assert_eq!(Rc::strong_count(&rc), 1);
|
assert_eq!(Rc::strong_count(&rc), 1);
|
||||||
|
|
||||||
match lua
|
match lua.globals().get::<_, Function>("bad")?.call::<_, ()>(()) {
|
||||||
.globals()
|
|
||||||
.get::<_, Function>("bad")
|
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(())
|
|
||||||
{
|
|
||||||
Err(Error::CallbackError { .. }) => {}
|
Err(Error::CallbackError { .. }) => {}
|
||||||
r => panic!("improper return for destructed function: {:?}", r),
|
r => panic!("improper return for destructed function: {:?}", r),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_drop() {
|
fn scope_drop() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
struct MyUserdata(Rc<()>);
|
struct MyUserdata(Rc<()>);
|
||||||
impl UserData for MyUserdata {
|
impl UserData for MyUserdata {
|
||||||
|
@ -50,27 +46,26 @@ fn scope_drop() {
|
||||||
let rc = Rc::new(());
|
let rc = Rc::new(());
|
||||||
|
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
lua.globals()
|
lua.globals().set(
|
||||||
.set(
|
|
||||||
"test",
|
"test",
|
||||||
scope
|
scope.create_static_userdata(MyUserdata(rc.clone()))?,
|
||||||
.create_static_userdata(MyUserdata(rc.clone()))
|
)?;
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(Rc::strong_count(&rc), 2);
|
assert_eq!(Rc::strong_count(&rc), 2);
|
||||||
});
|
Ok(())
|
||||||
|
})?;
|
||||||
assert_eq!(Rc::strong_count(&rc), 1);
|
assert_eq!(Rc::strong_count(&rc), 1);
|
||||||
|
|
||||||
match lua.exec::<_, ()>("test:method()", None) {
|
match lua.load("test:method()").exec() {
|
||||||
Err(Error::CallbackError { .. }) => {}
|
Err(Error::CallbackError { .. }) => {}
|
||||||
r => panic!("improper return for destructed userdata: {:?}", r),
|
r => panic!("improper return for destructed userdata: {:?}", r),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_capture() {
|
fn scope_capture() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
|
@ -78,33 +73,31 @@ fn scope_capture() {
|
||||||
.create_function_mut(|_, ()| {
|
.create_function_mut(|_, ()| {
|
||||||
i = 42;
|
i = 42;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})?
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(())
|
.call::<_, ()>(())
|
||||||
.unwrap();
|
})?;
|
||||||
});
|
|
||||||
assert_eq!(i, 42);
|
assert_eq!(i, 42);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn outer_lua_access() {
|
fn outer_lua_access() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let table = lua.create_table().unwrap();
|
|
||||||
|
let table = lua.create_table()?;
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
scope
|
scope
|
||||||
.create_function_mut(|_, ()| {
|
.create_function_mut(|_, ()| table.set("a", "b"))?
|
||||||
table.set("a", "b").unwrap();
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(())
|
.call::<_, ()>(())
|
||||||
.unwrap();
|
})?;
|
||||||
});
|
assert_eq!(table.get::<_, String>("a")?, "b");
|
||||||
assert_eq!(table.get::<_, String>("a").unwrap(), "b");
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_userdata_methods() {
|
fn scope_userdata_methods() -> Result<()> {
|
||||||
struct MyUserData<'a>(&'a Cell<i64>);
|
struct MyUserData<'a>(&'a Cell<i64>);
|
||||||
|
|
||||||
impl<'a> UserData for MyUserData<'a> {
|
impl<'a> UserData for MyUserData<'a> {
|
||||||
|
@ -121,12 +114,11 @@ fn scope_userdata_methods() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let i = Cell::new(42);
|
let i = Cell::new(42);
|
||||||
lua.scope(|scope| {
|
|
||||||
let f: Function = lua
|
let f: Function = lua
|
||||||
.eval(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
function(u)
|
function(u)
|
||||||
u:inc()
|
u:inc()
|
||||||
|
@ -135,19 +127,18 @@ fn scope_userdata_methods() {
|
||||||
u:dec()
|
u:dec()
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval()?;
|
||||||
|
|
||||||
f.call::<_, ()>(scope.create_nonstatic_userdata(MyUserData(&i)).unwrap())
|
lua.scope(|scope| f.call::<_, ()>(scope.create_nonstatic_userdata(MyUserData(&i))?))?;
|
||||||
.unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(i.get(), 44);
|
assert_eq!(i.get(), 44);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_userdata_functions() {
|
fn scope_userdata_functions() -> Result<()> {
|
||||||
struct MyUserData<'a>(&'a i64);
|
struct MyUserData<'a>(&'a i64);
|
||||||
|
|
||||||
impl<'a> UserData for MyUserData<'a> {
|
impl<'a> UserData for MyUserData<'a> {
|
||||||
|
@ -165,9 +156,11 @@ fn scope_userdata_functions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
|
let dummy = 0;
|
||||||
let f = lua
|
let f = lua
|
||||||
.exec::<_, Function>(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
i = 0
|
i = 0
|
||||||
return function(u)
|
return function(u)
|
||||||
|
@ -176,21 +169,18 @@ fn scope_userdata_functions() {
|
||||||
_ = 1 + u
|
_ = 1 + u
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval::<Function>()?;
|
||||||
|
|
||||||
let dummy = 0;
|
lua.scope(|scope| f.call::<_, ()>(scope.create_nonstatic_userdata(MyUserData(&dummy))?))?;
|
||||||
lua.scope(|scope| {
|
|
||||||
f.call::<_, ()>(scope.create_nonstatic_userdata(MyUserData(&dummy)).unwrap())
|
|
||||||
.unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(lua.globals().get::<_, i64>("i").unwrap(), 3);
|
assert_eq!(lua.globals().get::<_, i64>("i")?, 3);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope_userdata_mismatch() {
|
fn scope_userdata_mismatch() -> Result<()> {
|
||||||
struct MyUserData<'a>(&'a Cell<i64>);
|
struct MyUserData<'a>(&'a Cell<i64>);
|
||||||
|
|
||||||
impl<'a> UserData for MyUserData<'a> {
|
impl<'a> UserData for MyUserData<'a> {
|
||||||
|
@ -202,8 +192,9 @@ fn scope_userdata_mismatch() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
lua.exec::<_, ()>(
|
|
||||||
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function okay(a, b)
|
function okay(a, b)
|
||||||
a.inc(a)
|
a.inc(a)
|
||||||
|
@ -214,19 +205,18 @@ fn scope_userdata_mismatch() {
|
||||||
a.inc(b)
|
a.inc(b)
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let a = Cell::new(1);
|
let a = Cell::new(1);
|
||||||
let b = Cell::new(1);
|
let b = Cell::new(1);
|
||||||
|
|
||||||
let okay: Function = lua.globals().get("okay").unwrap();
|
let okay: Function = lua.globals().get("okay")?;
|
||||||
let bad: Function = lua.globals().get("bad").unwrap();
|
let bad: Function = lua.globals().get("bad")?;
|
||||||
|
|
||||||
lua.scope(|scope| {
|
lua.scope(|scope| {
|
||||||
let au = scope.create_nonstatic_userdata(MyUserData(&a)).unwrap();
|
let au = scope.create_nonstatic_userdata(MyUserData(&a))?;
|
||||||
let bu = scope.create_nonstatic_userdata(MyUserData(&b)).unwrap();
|
let bu = scope.create_nonstatic_userdata(MyUserData(&b))?;
|
||||||
assert!(okay.call::<_, ()>((au.clone(), bu.clone())).is_ok());
|
assert!(okay.call::<_, ()>((au.clone(), bu.clone())).is_ok());
|
||||||
match bad.call::<_, ()>((au, bu)) {
|
match bad.call::<_, ()>((au, bu)) {
|
||||||
Err(Error::CallbackError { ref cause, .. }) => match *cause.as_ref() {
|
Err(Error::CallbackError { ref cause, .. }) => match *cause.as_ref() {
|
||||||
|
@ -236,5 +226,8 @@ fn scope_userdata_mismatch() {
|
||||||
Err(other) => panic!("wrong error type {:?}", other),
|
Err(other) => panic!("wrong error type {:?}", other),
|
||||||
Ok(_) => panic!("incorrectly returned Ok"),
|
Ok(_) => panic!("incorrectly returned Ok"),
|
||||||
}
|
}
|
||||||
});
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rlua::{Lua, String};
|
use rlua::{Result, String};
|
||||||
|
|
||||||
fn with_str<F>(s: &str, f: F)
|
include!("_lua.rs");
|
||||||
where
|
|
||||||
F: FnOnce(String),
|
|
||||||
{
|
|
||||||
let lua = Lua::new();
|
|
||||||
let string = lua.create_string(s).unwrap();
|
|
||||||
f(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare() {
|
fn compare() {
|
||||||
|
fn with_str<F: FnOnce(String)>(s: &str, f: F) {
|
||||||
|
f(make_lua().create_string(s).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that all comparisons we want to have are usable
|
// Tests that all comparisons we want to have are usable
|
||||||
with_str("teststring", |t| assert_eq!(t, "teststring")); // &str
|
with_str("teststring", |t| assert_eq!(t, "teststring")); // &str
|
||||||
with_str("teststring", |t| assert_eq!(t, b"teststring")); // &[u8]
|
with_str("teststring", |t| assert_eq!(t, b"teststring")); // &[u8]
|
||||||
|
@ -28,27 +23,24 @@ fn compare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn string_views() {
|
fn string_views() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
lua.eval::<_, ()>(
|
|
||||||
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
ok = "null bytes are valid utf-8, wh\0 knew?"
|
ok = "null bytes are valid utf-8, wh\0 knew?"
|
||||||
err = "but \xff isn't :("
|
err = "but \xff isn't :("
|
||||||
empty = ""
|
empty = ""
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
let ok: String = globals.get("ok").unwrap();
|
let ok: String = globals.get("ok")?;
|
||||||
let err: String = globals.get("err").unwrap();
|
let err: String = globals.get("err")?;
|
||||||
let empty: String = globals.get("empty").unwrap();
|
let empty: String = globals.get("empty")?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(ok.to_str()?, "null bytes are valid utf-8, wh\0 knew?");
|
||||||
ok.to_str().unwrap(),
|
|
||||||
"null bytes are valid utf-8, wh\0 knew?"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ok.as_bytes(),
|
ok.as_bytes(),
|
||||||
&b"null bytes are valid utf-8, wh\0 knew?"[..]
|
&b"null bytes are valid utf-8, wh\0 knew?"[..]
|
||||||
|
@ -57,14 +49,19 @@ fn string_views() {
|
||||||
assert!(err.to_str().is_err());
|
assert!(err.to_str().is_err());
|
||||||
assert_eq!(err.as_bytes(), &b"but \xff isn't :("[..]);
|
assert_eq!(err.as_bytes(), &b"but \xff isn't :("[..]);
|
||||||
|
|
||||||
assert_eq!(empty.to_str().unwrap(), "");
|
assert_eq!(empty.to_str()?, "");
|
||||||
assert_eq!(empty.as_bytes_with_nul(), &[0]);
|
assert_eq!(empty.as_bytes_with_nul(), &[0]);
|
||||||
assert_eq!(empty.as_bytes(), &[]);
|
assert_eq!(empty.as_bytes(), &[]);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_string() {
|
fn raw_string() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let rs = lua.create_string(&[0, 1, 2, 3, 0, 1, 2, 3]).unwrap();
|
|
||||||
|
let rs = lua.create_string(&[0, 1, 2, 3, 0, 1, 2, 3])?;
|
||||||
assert_eq!(rs.as_bytes(), &[0, 1, 2, 3, 0, 1, 2, 3]);
|
assert_eq!(rs.as_bytes(), &[0, 1, 2, 3, 0, 1, 2, 3]);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
144
tests/table.rs
144
tests/table.rs
|
@ -1,159 +1,150 @@
|
||||||
extern crate rlua;
|
use rlua::{Nil, Result, Table, Value};
|
||||||
|
|
||||||
use rlua::{Lua, Nil, Result, Table, Value};
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_get() {
|
fn test_set_get() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
globals.set("foo", "bar").unwrap();
|
globals.set("foo", "bar")?;
|
||||||
globals.set("baz", "baf").unwrap();
|
globals.set("baz", "baf")?;
|
||||||
assert_eq!(globals.get::<_, String>("foo").unwrap(), "bar");
|
assert_eq!(globals.get::<_, String>("foo")?, "bar");
|
||||||
assert_eq!(globals.get::<_, String>("baz").unwrap(), "baf");
|
assert_eq!(globals.get::<_, String>("baz")?, "baf");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_table() {
|
fn test_table() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
globals.set("table", lua.create_table().unwrap()).unwrap();
|
globals.set("table", lua.create_table()?)?;
|
||||||
let table1: Table = globals.get("table").unwrap();
|
let table1: Table = globals.get("table")?;
|
||||||
let table2: Table = globals.get("table").unwrap();
|
let table2: Table = globals.get("table")?;
|
||||||
|
|
||||||
table1.set("foo", "bar").unwrap();
|
table1.set("foo", "bar")?;
|
||||||
table2.set("baz", "baf").unwrap();
|
table2.set("baz", "baf")?;
|
||||||
|
|
||||||
assert_eq!(table2.get::<_, String>("foo").unwrap(), "bar");
|
assert_eq!(table2.get::<_, String>("foo")?, "bar");
|
||||||
assert_eq!(table1.get::<_, String>("baz").unwrap(), "baf");
|
assert_eq!(table1.get::<_, String>("baz")?, "baf");
|
||||||
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
table1 = {1, 2, 3, 4, 5}
|
table1 = {1, 2, 3, 4, 5}
|
||||||
table2 = {}
|
table2 = {}
|
||||||
table3 = {1, 2, nil, 4, 5}
|
table3 = {1, 2, nil, 4, 5}
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let table1 = globals.get::<_, Table>("table1").unwrap();
|
let table1 = globals.get::<_, Table>("table1")?;
|
||||||
let table2 = globals.get::<_, Table>("table2").unwrap();
|
let table2 = globals.get::<_, Table>("table2")?;
|
||||||
let table3 = globals.get::<_, Table>("table3").unwrap();
|
let table3 = globals.get::<_, Table>("table3")?;
|
||||||
|
|
||||||
assert_eq!(table1.len().unwrap(), 5);
|
assert_eq!(table1.len()?, 5);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table1
|
table1
|
||||||
.clone()
|
.clone()
|
||||||
.pairs()
|
.pairs()
|
||||||
.collect::<Result<Vec<(i64, i64)>>>()
|
.collect::<Result<Vec<(i64, i64)>>>()?,
|
||||||
.unwrap(),
|
|
||||||
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
|
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table1
|
table1
|
||||||
.clone()
|
.clone()
|
||||||
.sequence_values()
|
.sequence_values()
|
||||||
.collect::<Result<Vec<i64>>>()
|
.collect::<Result<Vec<i64>>>()?,
|
||||||
.unwrap(),
|
|
||||||
vec![1, 2, 3, 4, 5]
|
vec![1, 2, 3, 4, 5]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(table2.len().unwrap(), 0);
|
assert_eq!(table2.len()?, 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table2
|
table2
|
||||||
.clone()
|
.clone()
|
||||||
.pairs()
|
.pairs()
|
||||||
.collect::<Result<Vec<(i64, i64)>>>()
|
.collect::<Result<Vec<(i64, i64)>>>()?,
|
||||||
.unwrap(),
|
|
||||||
vec![]
|
vec![]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table2
|
table2.sequence_values().collect::<Result<Vec<i64>>>()?,
|
||||||
.sequence_values()
|
|
||||||
.collect::<Result<Vec<i64>>>()
|
|
||||||
.unwrap(),
|
|
||||||
vec![]
|
vec![]
|
||||||
);
|
);
|
||||||
|
|
||||||
// sequence_values should only iterate until the first border
|
// sequence_values should only iterate until the first border
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table3
|
table3.sequence_values().collect::<Result<Vec<i64>>>()?,
|
||||||
.sequence_values()
|
|
||||||
.collect::<Result<Vec<i64>>>()
|
|
||||||
.unwrap(),
|
|
||||||
vec![1, 2]
|
vec![1, 2]
|
||||||
);
|
);
|
||||||
|
|
||||||
globals
|
globals.set("table4", lua.create_sequence_from(vec![1, 2, 3, 4, 5])?)?;
|
||||||
.set(
|
let table4 = globals.get::<_, Table>("table4")?;
|
||||||
"table4",
|
|
||||||
lua.create_sequence_from(vec![1, 2, 3, 4, 5]).unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let table4 = globals.get::<_, Table>("table4").unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table4.pairs().collect::<Result<Vec<(i64, i64)>>>().unwrap(),
|
table4.pairs().collect::<Result<Vec<(i64, i64)>>>()?,
|
||||||
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
|
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_table_scope() {
|
fn test_table_scope() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
touter = {
|
touter = {
|
||||||
tin = {1, 2, 3}
|
tin = {1, 2, 3}
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
// Make sure that table gets do not borrow the table, but instead just borrow lua.
|
// Make sure that table gets do not borrow the table, but instead just borrow lua.
|
||||||
let tin;
|
let tin;
|
||||||
{
|
{
|
||||||
let touter = globals.get::<_, Table>("touter").unwrap();
|
let touter = globals.get::<_, Table>("touter")?;
|
||||||
tin = touter.get::<_, Table>("tin").unwrap();
|
tin = touter.get::<_, Table>("tin")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(tin.get::<_, i64>(1).unwrap(), 1);
|
assert_eq!(tin.get::<_, i64>(1)?, 1);
|
||||||
assert_eq!(tin.get::<_, i64>(2).unwrap(), 2);
|
assert_eq!(tin.get::<_, i64>(2)?, 2);
|
||||||
assert_eq!(tin.get::<_, i64>(3).unwrap(), 3);
|
assert_eq!(tin.get::<_, i64>(3)?, 3);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_metatable() {
|
fn test_metatable() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let table = lua.create_table().unwrap();
|
let table = lua.create_table()?;
|
||||||
let metatable = lua.create_table().unwrap();
|
let metatable = lua.create_table()?;
|
||||||
metatable
|
metatable.set("__index", lua.create_function(|_, ()| Ok("index_value"))?)?;
|
||||||
.set(
|
|
||||||
"__index",
|
|
||||||
lua.create_function(|_, ()| Ok("index_value")).unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
table.set_metatable(Some(metatable));
|
table.set_metatable(Some(metatable));
|
||||||
assert_eq!(table.get::<_, String>("any_key").unwrap(), "index_value");
|
assert_eq!(table.get::<_, String>("any_key")?, "index_value");
|
||||||
match table.raw_get::<_, Value>("any_key").unwrap() {
|
match table.raw_get::<_, Value>("any_key")? {
|
||||||
Nil => {}
|
Nil => {}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
table.set_metatable(None);
|
table.set_metatable(None);
|
||||||
match table.get::<_, Value>("any_key").unwrap() {
|
match table.get::<_, Value>("any_key")? {
|
||||||
Nil => {}
|
Nil => {}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_table_error() {
|
fn test_table_error() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
table = {}
|
table = {}
|
||||||
setmetatable(table, {
|
setmetatable(table, {
|
||||||
|
@ -168,15 +159,16 @@ fn test_table_error() {
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let bad_table: Table = globals.get("table").unwrap();
|
let bad_table: Table = globals.get("table")?;
|
||||||
assert!(bad_table.set(1, 1).is_err());
|
assert!(bad_table.set(1, 1).is_err());
|
||||||
assert!(bad_table.get::<_, i32>(1).is_err());
|
assert!(bad_table.get::<_, i32>(1).is_err());
|
||||||
assert!(bad_table.len().is_err());
|
assert!(bad_table.len().is_err());
|
||||||
assert!(bad_table.raw_set(1, 1).is_ok());
|
assert!(bad_table.raw_set(1, 1).is_ok());
|
||||||
assert!(bad_table.raw_get::<_, i32>(1).is_ok());
|
assert!(bad_table.raw_get::<_, i32>(1).is_ok());
|
||||||
assert_eq!(bad_table.raw_len(), 1);
|
assert_eq!(bad_table.raw_len(), 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
628
tests/tests.rs
628
tests/tests.rs
|
@ -1,55 +1,39 @@
|
||||||
extern crate failure;
|
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{error, f32, f64, fmt};
|
use std::{error, f32, f64, fmt};
|
||||||
|
|
||||||
use failure::err_msg;
|
use rlua::{Error, ExternalError, Function, Nil, Result, String, Table, UserData, Value, Variadic};
|
||||||
use rlua::{
|
|
||||||
Error, ExternalError, Function, Lua, Nil, Result, String, Table, UserData, Value, Variadic,
|
include!("_lua.rs");
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_load() {
|
fn test_load() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let func = lua.load("return 1+2", None).unwrap();
|
let func = lua.load("return 1+2").into_function()?;
|
||||||
let result: i32 = func.call(()).unwrap();
|
let result: i32 = func.call(())?;
|
||||||
assert_eq!(result, 3);
|
assert_eq!(result, 3);
|
||||||
|
|
||||||
assert!(lua.load("§$%§&$%&", None).is_err());
|
assert!(lua.load("§$%§&$%&").exec().is_err());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_debug() {
|
fn test_exec() -> Result<()> {
|
||||||
let lua = unsafe { Lua::new_with_debug() };
|
let lua = make_lua();
|
||||||
match lua.eval("debug", None).unwrap() {
|
|
||||||
Value::Table(_) => {}
|
|
||||||
val => panic!("Expected table for debug library, got {:#?}", val),
|
|
||||||
}
|
|
||||||
let traceback_output = lua.eval::<_, String>("debug.traceback()", None).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
traceback_output.to_str().unwrap().split("\n").next(),
|
|
||||||
"stack traceback:".into()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_exec() {
|
|
||||||
let lua = Lua::new();
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
res = 'foo'..'bar'
|
res = 'foo'..'bar'
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
assert_eq!(globals.get::<_, String>("res").unwrap(), "foobar");
|
assert_eq!(globals.get::<_, String>("res")?, "foobar");
|
||||||
|
|
||||||
let module: Table = lua
|
let module: Table = lua
|
||||||
.exec(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
local module = {}
|
local module = {}
|
||||||
|
|
||||||
|
@ -59,27 +43,25 @@ fn test_exec() {
|
||||||
|
|
||||||
return module
|
return module
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval()?;
|
||||||
assert!(module.contains_key("func").unwrap());
|
assert!(module.contains_key("func")?);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module
|
module.get::<_, Function>("func")?.call::<_, String>(())?,
|
||||||
.get::<_, Function>("func")
|
|
||||||
.unwrap()
|
|
||||||
.call::<_, String>(())
|
|
||||||
.unwrap(),
|
|
||||||
"hello"
|
"hello"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eval() {
|
fn test_eval() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
assert_eq!(lua.eval::<_, i32>("1 + 1", None).unwrap(), 2);
|
|
||||||
assert_eq!(lua.eval::<_, bool>("false == false", None).unwrap(), true);
|
assert_eq!(lua.load("1 + 1").eval::<i32>()?, 2);
|
||||||
assert_eq!(lua.eval::<_, i32>("return 1 + 2", None).unwrap(), 3);
|
assert_eq!(lua.load("false == false").eval::<bool>()?, true);
|
||||||
match lua.eval::<_, ()>("if true then", None) {
|
assert_eq!(lua.load("return 1 + 2").eval::<i32>()?, 3);
|
||||||
|
match lua.load("if true then").eval::<()>() {
|
||||||
Err(Error::SyntaxError {
|
Err(Error::SyntaxError {
|
||||||
incomplete_input: true,
|
incomplete_input: true,
|
||||||
..
|
..
|
||||||
|
@ -89,13 +71,15 @@ fn test_eval() {
|
||||||
r
|
r
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lua_multi() {
|
fn test_lua_multi() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function concat(arg1, arg2)
|
function concat(arg1, arg2)
|
||||||
return arg1 .. arg2
|
return arg1 .. arg2
|
||||||
|
@ -105,42 +89,46 @@ fn test_lua_multi() {
|
||||||
return 1, 2, 3, 4, 5, 6
|
return 1, 2, 3, 4, 5, 6
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let concat = globals.get::<_, Function>("concat").unwrap();
|
let globals = lua.globals();
|
||||||
let mreturn = globals.get::<_, Function>("mreturn").unwrap();
|
let concat = globals.get::<_, Function>("concat")?;
|
||||||
|
let mreturn = globals.get::<_, Function>("mreturn")?;
|
||||||
|
|
||||||
assert_eq!(concat.call::<_, String>(("foo", "bar")).unwrap(), "foobar");
|
assert_eq!(concat.call::<_, String>(("foo", "bar"))?, "foobar");
|
||||||
let (a, b) = mreturn.call::<_, (u64, u64)>(()).unwrap();
|
let (a, b) = mreturn.call::<_, (u64, u64)>(())?;
|
||||||
assert_eq!((a, b), (1, 2));
|
assert_eq!((a, b), (1, 2));
|
||||||
let (a, b, v) = mreturn.call::<_, (u64, u64, Variadic<u64>)>(()).unwrap();
|
let (a, b, v) = mreturn.call::<_, (u64, u64, Variadic<u64>)>(())?;
|
||||||
assert_eq!((a, b), (1, 2));
|
assert_eq!((a, b), (1, 2));
|
||||||
assert_eq!(v[..], [3, 4, 5, 6]);
|
assert_eq!(v[..], [3, 4, 5, 6]);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_coercion() {
|
fn test_coercion() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
int = 123
|
int = 123
|
||||||
str = "123"
|
str = "123"
|
||||||
num = 123.0
|
num = 123.0
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
assert_eq!(globals.get::<_, String>("int").unwrap(), "123");
|
let globals = lua.globals();
|
||||||
assert_eq!(globals.get::<_, i32>("str").unwrap(), 123);
|
assert_eq!(globals.get::<_, String>("int")?, "123");
|
||||||
assert_eq!(globals.get::<_, i32>("num").unwrap(), 123);
|
assert_eq!(globals.get::<_, i32>("str")?, 123);
|
||||||
|
assert_eq!(globals.get::<_, i32>("num")?, 123);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_error() {
|
fn test_error() -> Result<()> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TestError;
|
pub struct TestError;
|
||||||
|
|
||||||
|
@ -155,14 +143,15 @@ fn test_error() {
|
||||||
"test error"
|
"test error"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&error::Error> {
|
fn cause(&self) -> Option<&dyn error::Error> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function no_error()
|
function no_error()
|
||||||
end
|
end
|
||||||
|
@ -212,24 +201,20 @@ fn test_error() {
|
||||||
understand_recursion()
|
understand_recursion()
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let rust_error_function = lua
|
let rust_error_function =
|
||||||
.create_function(|_, ()| -> Result<()> { Err(TestError.to_lua_err()) })
|
lua.create_function(|_, ()| -> Result<()> { Err(TestError.to_lua_err()) })?;
|
||||||
.unwrap();
|
globals.set("rust_error_function", rust_error_function)?;
|
||||||
globals
|
|
||||||
.set("rust_error_function", rust_error_function)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let no_error = globals.get::<_, Function>("no_error").unwrap();
|
let no_error = globals.get::<_, Function>("no_error")?;
|
||||||
let lua_error = globals.get::<_, Function>("lua_error").unwrap();
|
let lua_error = globals.get::<_, Function>("lua_error")?;
|
||||||
let rust_error = globals.get::<_, Function>("rust_error").unwrap();
|
let rust_error = globals.get::<_, Function>("rust_error")?;
|
||||||
let return_error = globals.get::<_, Function>("return_error").unwrap();
|
let return_error = globals.get::<_, Function>("return_error")?;
|
||||||
let return_string_error = globals.get::<_, Function>("return_string_error").unwrap();
|
let return_string_error = globals.get::<_, Function>("return_string_error")?;
|
||||||
let test_pcall = globals.get::<_, Function>("test_pcall").unwrap();
|
let test_pcall = globals.get::<_, Function>("test_pcall")?;
|
||||||
let understand_recursion = globals.get::<_, Function>("understand_recursion").unwrap();
|
let understand_recursion = globals.get::<_, Function>("understand_recursion")?;
|
||||||
|
|
||||||
assert!(no_error.call::<_, ()>(()).is_ok());
|
assert!(no_error.call::<_, ()>(()).is_ok());
|
||||||
match lua_error.call::<_, ()>(()) {
|
match lua_error.call::<_, ()>(()) {
|
||||||
|
@ -250,7 +235,10 @@ fn test_error() {
|
||||||
|
|
||||||
assert!(return_string_error.call::<_, Error>(()).is_ok());
|
assert!(return_string_error.call::<_, Error>(()).is_ok());
|
||||||
|
|
||||||
match lua.eval::<_, ()>("if youre happy and you know it syntax error", None) {
|
match lua
|
||||||
|
.load("if youre happy and you know it syntax error")
|
||||||
|
.exec()
|
||||||
|
{
|
||||||
Err(Error::SyntaxError {
|
Err(Error::SyntaxError {
|
||||||
incomplete_input: false,
|
incomplete_input: false,
|
||||||
..
|
..
|
||||||
|
@ -258,7 +246,7 @@ fn test_error() {
|
||||||
Err(_) => panic!("error is not LuaSyntaxError::Syntax kind"),
|
Err(_) => panic!("error is not LuaSyntaxError::Syntax kind"),
|
||||||
_ => panic!("error not returned"),
|
_ => panic!("error not returned"),
|
||||||
}
|
}
|
||||||
match lua.eval::<_, ()>("function i_will_finish_what_i()", None) {
|
match lua.load("function i_will_finish_what_i()").exec() {
|
||||||
Err(Error::SyntaxError {
|
Err(Error::SyntaxError {
|
||||||
incomplete_input: true,
|
incomplete_input: true,
|
||||||
..
|
..
|
||||||
|
@ -267,181 +255,181 @@ fn test_error() {
|
||||||
_ => panic!("error not returned"),
|
_ => panic!("error not returned"),
|
||||||
}
|
}
|
||||||
|
|
||||||
test_pcall.call::<_, ()>(()).unwrap();
|
test_pcall.call::<_, ()>(())?;
|
||||||
|
|
||||||
assert!(understand_recursion.call::<_, ()>(()).is_err());
|
assert!(understand_recursion.call::<_, ()>(()).is_err());
|
||||||
|
|
||||||
match catch_unwind(|| -> Result<()> {
|
match catch_unwind(|| -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function rust_panic()
|
function rust_panic()
|
||||||
pcall(function () rust_panic_function() end)
|
local _, err = pcall(function () rust_panic_function() end)
|
||||||
|
if err ~= nil then
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
)
|
||||||
)?;
|
.exec()?;
|
||||||
let rust_panic_function = lua
|
let rust_panic_function =
|
||||||
.create_function(|_, ()| -> Result<()> { panic!("test_panic") })
|
lua.create_function(|_, ()| -> Result<()> { panic!("test_panic") })?;
|
||||||
.unwrap();
|
|
||||||
globals.set("rust_panic_function", rust_panic_function)?;
|
globals.set("rust_panic_function", rust_panic_function)?;
|
||||||
|
|
||||||
let rust_panic = globals.get::<_, Function>("rust_panic")?;
|
let rust_panic = globals.get::<_, Function>("rust_panic")?;
|
||||||
|
|
||||||
rust_panic.call::<_, ()>(())
|
rust_panic.call::<_, ()>(())
|
||||||
}) {
|
}) {
|
||||||
Ok(Ok(_)) => panic!("no panic was detected, pcall caught it!"),
|
Ok(Ok(_)) => panic!("no panic was detected"),
|
||||||
Ok(Err(e)) => panic!("error during panic test {:?}", e),
|
Ok(Err(e)) => panic!("error during panic test {:?}", e),
|
||||||
Err(p) => assert!(*p.downcast::<&str>().unwrap() == "test_panic"),
|
Err(p) => assert!(*p.downcast::<&str>().unwrap() == "test_panic"),
|
||||||
};
|
};
|
||||||
|
|
||||||
match catch_unwind(|| -> Result<()> {
|
match catch_unwind(|| -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function rust_panic()
|
function rust_panic()
|
||||||
xpcall(function() rust_panic_function() end, function() end)
|
local _, err = pcall(function () rust_panic_function() end)
|
||||||
|
if err ~= nil then
|
||||||
|
error(tostring(err))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
)
|
||||||
)?;
|
.exec()?;
|
||||||
let rust_panic_function = lua
|
let rust_panic_function =
|
||||||
.create_function(|_, ()| -> Result<()> { panic!("test_panic") })
|
lua.create_function(|_, ()| -> Result<()> { panic!("test_panic") })?;
|
||||||
.unwrap();
|
|
||||||
globals.set("rust_panic_function", rust_panic_function)?;
|
globals.set("rust_panic_function", rust_panic_function)?;
|
||||||
|
|
||||||
let rust_panic = globals.get::<_, Function>("rust_panic")?;
|
let rust_panic = globals.get::<_, Function>("rust_panic")?;
|
||||||
|
|
||||||
rust_panic.call::<_, ()>(())
|
rust_panic.call::<_, ()>(())
|
||||||
}) {
|
}) {
|
||||||
Ok(Ok(_)) => panic!("no panic was detected, xpcall caught it!"),
|
Ok(Ok(_)) => panic!("no error was detected"),
|
||||||
Ok(Err(e)) => panic!("error during panic test {:?}", e),
|
Ok(Err(Error::RuntimeError(_))) => {}
|
||||||
Err(p) => assert!(*p.downcast::<&str>().unwrap() == "test_panic"),
|
Ok(Err(e)) => panic!("unexpected error during panic test {:?}", e),
|
||||||
|
Err(_) => panic!("panic was detected"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_result_conversions() {
|
fn test_result_conversions() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
let err = lua
|
let err = lua.create_function(|_, ()| {
|
||||||
.create_function(|_, ()| {
|
|
||||||
Ok(Err::<String, _>(
|
Ok(Err::<String, _>(
|
||||||
err_msg("only through failure can we succeed").to_lua_err(),
|
"only through failure can we succeed".to_lua_err(),
|
||||||
))
|
))
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
let ok = lua.create_function(|_, ()| Ok(Ok::<_, Error>("!".to_owned())))?;
|
||||||
let ok = lua
|
|
||||||
.create_function(|_, ()| Ok(Ok::<_, Error>("!".to_owned())))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
globals.set("err", err).unwrap();
|
globals.set("err", err)?;
|
||||||
globals.set("ok", ok).unwrap();
|
globals.set("ok", ok)?;
|
||||||
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
local r, e = err()
|
local r, e = err()
|
||||||
assert(r == nil)
|
assert(r == nil)
|
||||||
assert(tostring(e) == "only through failure can we succeed")
|
assert(tostring(e):find("only through failure can we succeed") ~= nil)
|
||||||
|
|
||||||
local r, e = ok()
|
local r, e = ok()
|
||||||
assert(r == "!")
|
assert(r == "!")
|
||||||
assert(e == nil)
|
assert(e == nil)
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_conversion() {
|
fn test_num_conversion() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_integer(Value::String(lua.create_string("1").unwrap())),
|
lua.coerce_integer(Value::String(lua.create_string("1")?))?,
|
||||||
Some(1)
|
Some(1)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_integer(Value::String(lua.create_string("1.0").unwrap())),
|
lua.coerce_integer(Value::String(lua.create_string("1.0")?))?,
|
||||||
Some(1)
|
Some(1)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_integer(Value::String(lua.create_string("1.5").unwrap())),
|
lua.coerce_integer(Value::String(lua.create_string("1.5")?))?,
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_number(Value::String(lua.create_string("1").unwrap())),
|
lua.coerce_number(Value::String(lua.create_string("1")?))?,
|
||||||
Some(1.0)
|
Some(1.0)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_number(Value::String(lua.create_string("1.0").unwrap())),
|
lua.coerce_number(Value::String(lua.create_string("1.0")?))?,
|
||||||
Some(1.0)
|
Some(1.0)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.coerce_number(Value::String(lua.create_string("1.5").unwrap())),
|
lua.coerce_number(Value::String(lua.create_string("1.5")?))?,
|
||||||
Some(1.5)
|
Some(1.5)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(lua.eval::<_, i64>("1.0", None).unwrap(), 1);
|
assert_eq!(lua.load("1.0").eval::<i64>()?, 1);
|
||||||
assert_eq!(lua.eval::<_, f64>("1.0", None).unwrap(), 1.0);
|
assert_eq!(lua.load("1.0").eval::<f64>()?, 1.0);
|
||||||
assert_eq!(lua.eval::<_, String>("1.0", None).unwrap(), "1.0");
|
assert_eq!(lua.load("1.0").eval::<String>()?, "1.0");
|
||||||
|
|
||||||
assert_eq!(lua.eval::<_, i64>("1.5", None).unwrap(), 1);
|
assert_eq!(lua.load("1.5").eval::<i64>()?, 1);
|
||||||
assert_eq!(lua.eval::<_, f64>("1.5", None).unwrap(), 1.5);
|
assert_eq!(lua.load("1.5").eval::<f64>()?, 1.5);
|
||||||
assert_eq!(lua.eval::<_, String>("1.5", None).unwrap(), "1.5");
|
assert_eq!(lua.load("1.5").eval::<String>()?, "1.5");
|
||||||
|
|
||||||
assert!(lua.eval::<_, u64>("-1", None).is_err());
|
assert!(lua.load("-1").eval::<u64>().is_err());
|
||||||
assert_eq!(lua.eval::<_, i64>("-1", None).unwrap(), -1);
|
assert_eq!(lua.load("-1").eval::<i64>()?, -1);
|
||||||
|
|
||||||
assert!(lua.unpack::<u64>(lua.pack(1u128 << 64).unwrap()).is_err());
|
assert!(lua.unpack::<u64>(lua.pack(1u128 << 64)?).is_err());
|
||||||
assert!(lua.eval::<_, i64>("math.huge", None).is_err());
|
assert!(lua.load("math.huge").eval::<i64>().is_err());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(lua.unpack::<f64>(lua.pack(f32::MAX)?)?, f32::MAX as f64);
|
||||||
lua.unpack::<f64>(lua.pack(f32::MAX).unwrap()).unwrap(),
|
assert!(lua.unpack::<f32>(lua.pack(f64::MAX)?).is_err());
|
||||||
f32::MAX as f64
|
|
||||||
);
|
|
||||||
assert!(lua.unpack::<f32>(lua.pack(f64::MAX).unwrap()).is_err());
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(lua.unpack::<i128>(lua.pack(1i128 << 64)?)?, 1i128 << 64);
|
||||||
lua.unpack::<i128>(lua.pack(1i128 << 64).unwrap()).unwrap(),
|
|
||||||
1i128 << 64
|
Ok(())
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pcall_xpcall() {
|
fn test_pcall_xpcall() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
// make sure that we handle not enough arguments
|
// make sure that we handle not enough arguments
|
||||||
|
|
||||||
assert!(lua.exec::<_, ()>("pcall()", None).is_err());
|
assert!(lua.load("pcall()").exec().is_err());
|
||||||
assert!(lua.exec::<_, ()>("xpcall()", None).is_err());
|
assert!(lua.load("xpcall()").exec().is_err());
|
||||||
assert!(lua.exec::<_, ()>("xpcall(function() end)", None).is_err());
|
assert!(lua.load("xpcall(function() end)").exec().is_err());
|
||||||
|
|
||||||
// Make sure that the return values from are correct on success
|
// Make sure that the return values from are correct on success
|
||||||
|
|
||||||
let (r, e) = lua
|
let (r, e) = lua
|
||||||
.eval::<_, (bool, String)>("pcall(function(p) return p end, 'foo')", None)
|
.load("pcall(function(p) return p end, 'foo')")
|
||||||
.unwrap();
|
.eval::<(bool, String)>()?;
|
||||||
assert!(r);
|
assert!(r);
|
||||||
assert_eq!(e, "foo");
|
assert_eq!(e, "foo");
|
||||||
|
|
||||||
let (r, e) = lua
|
let (r, e) = lua
|
||||||
.eval::<_, (bool, String)>("xpcall(function(p) return p end, print, 'foo')", None)
|
.load("xpcall(function(p) return p end, print, 'foo')")
|
||||||
.unwrap();
|
.eval::<(bool, String)>()?;
|
||||||
assert!(r);
|
assert!(r);
|
||||||
assert_eq!(e, "foo");
|
assert_eq!(e, "foo");
|
||||||
|
|
||||||
// Make sure that the return values are correct on errors, and that error handling works
|
// Make sure that the return values are correct on errors, and that error handling works
|
||||||
|
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
pcall_error = nil
|
pcall_error = nil
|
||||||
pcall_status, pcall_error = pcall(error, "testerror")
|
pcall_status, pcall_error = pcall(error, "testerror")
|
||||||
|
@ -449,45 +437,37 @@ fn test_pcall_xpcall() {
|
||||||
xpcall_error = nil
|
xpcall_error = nil
|
||||||
xpcall_status, _ = xpcall(error, function(err) xpcall_error = err end, "testerror")
|
xpcall_status, _ = xpcall(error, function(err) xpcall_error = err end, "testerror")
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
assert_eq!(globals.get::<_, bool>("pcall_status").unwrap(), false);
|
assert_eq!(globals.get::<_, bool>("pcall_status")?, false);
|
||||||
assert_eq!(
|
assert_eq!(globals.get::<_, String>("pcall_error")?, "testerror");
|
||||||
globals.get::<_, String>("pcall_error").unwrap(),
|
|
||||||
"testerror"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(globals.get::<_, bool>("xpcall_statusr").unwrap(), false);
|
assert_eq!(globals.get::<_, bool>("xpcall_statusr")?, false);
|
||||||
assert_eq!(
|
assert_eq!(globals.get::<_, String>("xpcall_error")?, "testerror");
|
||||||
globals.get::<_, String>("xpcall_error").unwrap(),
|
|
||||||
"testerror"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Make sure that weird xpcall error recursion at least doesn't cause unsafety or panics.
|
// Make sure that weird xpcall error recursion at least doesn't cause unsafety or panics.
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function xpcall_recursion()
|
function xpcall_recursion()
|
||||||
xpcall(error, function(err) error(err) end, "testerror")
|
xpcall(error, function(err) error(err) end, "testerror")
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
let _ = globals
|
let _ = globals
|
||||||
.get::<_, Function>("xpcall_recursion")
|
.get::<_, Function>("xpcall_recursion")?
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(());
|
.call::<_, ()>(());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_recursive_mut_callback_error() {
|
fn test_recursive_mut_callback_error() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let mut v = Some(Box::new(123));
|
let mut v = Some(Box::new(123));
|
||||||
let f = lua
|
let f = lua.create_function_mut::<_, (), _>(move |lua, mutate: bool| {
|
||||||
.create_function_mut::<_, (), _>(move |lua, mutate: bool| {
|
|
||||||
if mutate {
|
if mutate {
|
||||||
v = None;
|
v = None;
|
||||||
} else {
|
} else {
|
||||||
|
@ -501,15 +481,9 @@ fn test_recursive_mut_callback_error() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
lua.globals().set("f", f)?;
|
||||||
lua.globals().set("f", f).unwrap();
|
match lua.globals().get::<_, Function>("f")?.call::<_, ()>(false) {
|
||||||
match lua
|
|
||||||
.globals()
|
|
||||||
.get::<_, Function>("f")
|
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(false)
|
|
||||||
{
|
|
||||||
Err(Error::CallbackError { ref cause, .. }) => match *cause.as_ref() {
|
Err(Error::CallbackError { ref cause, .. }) => match *cause.as_ref() {
|
||||||
Error::CallbackError { ref cause, .. } => match *cause.as_ref() {
|
Error::CallbackError { ref cause, .. } => match *cause.as_ref() {
|
||||||
Error::RecursiveMutCallback { .. } => {}
|
Error::RecursiveMutCallback { .. } => {}
|
||||||
|
@ -519,72 +493,50 @@ fn test_recursive_mut_callback_error() {
|
||||||
},
|
},
|
||||||
other => panic!("incorrect result: {:?}", other),
|
other => panic!("incorrect result: {:?}", other),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_metatable_nil() {
|
fn test_set_metatable_nil() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
a = {}
|
a = {}
|
||||||
setmetatable(a, nil)
|
setmetatable(a, nil)
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_gc_error() {
|
|
||||||
let lua = Lua::new();
|
|
||||||
match lua.exec::<_, ()>(
|
|
||||||
r#"
|
|
||||||
val = nil
|
|
||||||
table = {}
|
|
||||||
setmetatable(table, {
|
|
||||||
__gc = function()
|
|
||||||
error("gcwascalled")
|
|
||||||
end
|
|
||||||
})
|
|
||||||
table = nil
|
|
||||||
collectgarbage("collect")
|
|
||||||
"#,
|
|
||||||
None,
|
|
||||||
) {
|
|
||||||
Err(Error::GarbageCollectorError(_)) => {}
|
|
||||||
Err(e) => panic!("__gc error did not result in correct error, instead: {}", e),
|
|
||||||
Ok(()) => panic!("__gc error did not result in error"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_named_registry_value() {
|
|
||||||
let lua = Lua::new();
|
|
||||||
|
|
||||||
lua.set_named_registry_value::<i32>("test", 42).unwrap();
|
|
||||||
let f = lua
|
|
||||||
.create_function(move |lua, ()| {
|
|
||||||
assert_eq!(lua.named_registry_value::<i32>("test")?, 42);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
}
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
f.call::<_, ()>(()).unwrap();
|
#[test]
|
||||||
|
fn test_named_registry_value() -> Result<()> {
|
||||||
|
let lua = make_lua();
|
||||||
|
|
||||||
lua.unset_named_registry_value("test").unwrap();
|
lua.set_named_registry_value::<_, i32>("test", 42)?;
|
||||||
match lua.named_registry_value("test").unwrap() {
|
let f = lua.create_function(move |lua, ()| {
|
||||||
|
assert_eq!(lua.named_registry_value::<_, i32>("test")?, 42);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
f.call::<_, ()>(())?;
|
||||||
|
|
||||||
|
lua.unset_named_registry_value("test")?;
|
||||||
|
match lua.named_registry_value("test")? {
|
||||||
Nil => {}
|
Nil => {}
|
||||||
val => panic!("registry value was not Nil, was {:?}", val),
|
val => panic!("registry value was not Nil, was {:?}", val),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_registry_value() {
|
fn test_registry_value() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let mut r = Some(lua.create_registry_value::<i32>(42).unwrap());
|
let mut r = Some(lua.create_registry_value::<i32>(42)?);
|
||||||
let f = lua
|
let f = lua.create_function_mut(move |lua, ()| {
|
||||||
.create_function_mut(move |lua, ()| {
|
|
||||||
if let Some(r) = r.take() {
|
if let Some(r) = r.take() {
|
||||||
assert_eq!(lua.registry_value::<i32>(&r)?, 42);
|
assert_eq!(lua.registry_value::<i32>(&r)?, 42);
|
||||||
lua.remove_registry_value(r).unwrap();
|
lua.remove_registry_value(r).unwrap();
|
||||||
|
@ -592,138 +544,129 @@ fn test_registry_value() {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
f.call::<_, ()>(()).unwrap();
|
f.call::<_, ()>(())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drop_registry_value() {
|
fn test_drop_registry_value() -> Result<()> {
|
||||||
struct MyUserdata(Arc<()>);
|
struct MyUserdata(Arc<()>);
|
||||||
|
|
||||||
impl UserData for MyUserdata {}
|
impl UserData for MyUserdata {}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let rc = Arc::new(());
|
let rc = Arc::new(());
|
||||||
|
|
||||||
let r = lua.create_registry_value(MyUserdata(rc.clone())).unwrap();
|
let r = lua.create_registry_value(MyUserdata(rc.clone()))?;
|
||||||
assert_eq!(Arc::strong_count(&rc), 2);
|
assert_eq!(Arc::strong_count(&rc), 2);
|
||||||
|
|
||||||
drop(r);
|
drop(r);
|
||||||
lua.expire_registry_values();
|
lua.expire_registry_values();
|
||||||
|
|
||||||
lua.exec::<_, ()>(r#"collectgarbage("collect")"#, None)
|
lua.load(r#"collectgarbage("collect")"#).exec()?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(Arc::strong_count(&rc), 1);
|
assert_eq!(Arc::strong_count(&rc), 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
fn test_lua_registry_ownership() -> Result<()> {
|
||||||
fn test_mismatched_lua_ref() {
|
let lua1 = make_lua();
|
||||||
let lua1 = Lua::new();
|
let lua2 = make_lua();
|
||||||
let lua2 = Lua::new();
|
|
||||||
|
|
||||||
let s = lua1.create_string("hello").unwrap();
|
let r1 = lua1.create_registry_value("hello")?;
|
||||||
let f = lua2.create_function(|_, _: String| Ok(())).unwrap();
|
let r2 = lua2.create_registry_value("hello")?;
|
||||||
|
|
||||||
f.call::<_, ()>(s).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_lua_registry_ownership() {
|
|
||||||
let lua1 = Lua::new();
|
|
||||||
let lua2 = Lua::new();
|
|
||||||
|
|
||||||
let r1 = lua1.create_registry_value("hello").unwrap();
|
|
||||||
let r2 = lua2.create_registry_value("hello").unwrap();
|
|
||||||
|
|
||||||
assert!(lua1.owns_registry_value(&r1));
|
assert!(lua1.owns_registry_value(&r1));
|
||||||
assert!(!lua2.owns_registry_value(&r1));
|
assert!(!lua2.owns_registry_value(&r1));
|
||||||
assert!(lua2.owns_registry_value(&r2));
|
assert!(lua2.owns_registry_value(&r2));
|
||||||
assert!(!lua1.owns_registry_value(&r2));
|
assert!(!lua1.owns_registry_value(&r2));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mismatched_registry_key() {
|
fn test_mismatched_registry_key() -> Result<()> {
|
||||||
let lua1 = Lua::new();
|
let lua1 = make_lua();
|
||||||
let lua2 = Lua::new();
|
let lua2 = make_lua();
|
||||||
|
|
||||||
let r = lua1.create_registry_value("hello").unwrap();
|
let r = lua1.create_registry_value("hello")?;
|
||||||
match lua2.remove_registry_value(r) {
|
match lua2.remove_registry_value(r) {
|
||||||
Err(Error::MismatchedRegistryKey) => {}
|
Err(Error::MismatchedRegistryKey) => {}
|
||||||
r => panic!("wrong result type for mismatched registry key, {:?}", r),
|
r => panic!("wrong result type for mismatched registry key, {:?}", r),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_many_returns() {
|
fn too_many_returns() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let f = lua
|
let f = lua.create_function(|_, ()| Ok(Variadic::from_iter(1..1000000)))?;
|
||||||
.create_function(|_, ()| Ok(Variadic::from_iter(1..1000000)))
|
|
||||||
.unwrap();
|
|
||||||
assert!(f.call::<_, Vec<u32>>(()).is_err());
|
assert!(f.call::<_, Vec<u32>>(()).is_err());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_many_arguments() {
|
fn too_many_arguments() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
lua.exec::<_, ()>("function test(...) end", None).unwrap();
|
lua.load("function test(...) end").exec()?;
|
||||||
let args = Variadic::from_iter(1..1000000);
|
let args = Variadic::from_iter(1..1000000);
|
||||||
assert!(lua
|
assert!(lua
|
||||||
.globals()
|
.globals()
|
||||||
.get::<_, Function>("test")
|
.get::<_, Function>("test")?
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(args)
|
.call::<_, ()>(args)
|
||||||
.is_err());
|
.is_err());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_many_recursions() {
|
fn too_many_recursions() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let f = lua
|
let f = lua
|
||||||
.create_function(move |lua, ()| lua.globals().get::<_, Function>("f")?.call::<_, ()>(()))
|
.create_function(move |lua, ()| lua.globals().get::<_, Function>("f")?.call::<_, ()>(()))?;
|
||||||
.unwrap();
|
lua.globals().set("f", f)?;
|
||||||
lua.globals().set("f", f).unwrap();
|
|
||||||
|
|
||||||
assert!(lua
|
assert!(lua
|
||||||
.globals()
|
.globals()
|
||||||
.get::<_, Function>("f")
|
.get::<_, Function>("f")?
|
||||||
.unwrap()
|
|
||||||
.call::<_, ()>(())
|
.call::<_, ()>(())
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn too_many_binds() {
|
fn too_many_binds() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function f(...)
|
function f(...)
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let concat = globals.get::<_, Function>("f").unwrap();
|
let concat = globals.get::<_, Function>("f")?;
|
||||||
assert!(concat.bind(Variadic::from_iter(1..1000000)).is_err());
|
assert!(concat.bind(Variadic::from_iter(1..1000000)).is_err());
|
||||||
assert!(concat
|
assert!(concat
|
||||||
.call::<_, ()>(Variadic::from_iter(1..1000000))
|
.call::<_, ()>(Variadic::from_iter(1..1000000))
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn large_args() {
|
fn large_args() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
globals
|
globals.set(
|
||||||
.set(
|
|
||||||
"c",
|
"c",
|
||||||
lua.create_function(|_, args: Variadic<usize>| {
|
lua.create_function(|_, args: Variadic<usize>| {
|
||||||
let mut s = 0;
|
let mut s = 0;
|
||||||
|
@ -732,42 +675,99 @@ fn large_args() {
|
||||||
assert_eq!(i, args[i]);
|
assert_eq!(i, args[i]);
|
||||||
}
|
}
|
||||||
Ok(s)
|
Ok(s)
|
||||||
})
|
})?,
|
||||||
.unwrap(),
|
)?;
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let f: Function = lua
|
let f: Function = lua
|
||||||
.eval(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
return function(...)
|
return function(...)
|
||||||
return c(...)
|
return c(...)
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval()?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
f.call::<_, usize>((0..100).collect::<Variadic<usize>>())
|
f.call::<_, usize>((0..100).collect::<Variadic<usize>>())?,
|
||||||
.unwrap(),
|
|
||||||
4950
|
4950
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn large_args_ref() {
|
fn large_args_ref() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let f = lua
|
let f = lua.create_function(|_, args: Variadic<String>| {
|
||||||
.create_function(|_, args: Variadic<String>| {
|
|
||||||
for i in 0..args.len() {
|
for i in 0..args.len() {
|
||||||
assert_eq!(args[i], i.to_string());
|
assert_eq!(args[i], i.to_string());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
f.call::<_, ()>((0..100).map(|i| i.to_string()).collect::<Variadic<_>>())
|
f.call::<_, ()>((0..100).map(|i| i.to_string()).collect::<Variadic<_>>())?;
|
||||||
.unwrap();
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chunk_env() -> Result<()> {
|
||||||
|
let lua = make_lua();
|
||||||
|
|
||||||
|
let assert: Function = lua.globals().get("assert")?;
|
||||||
|
|
||||||
|
let env1 = lua.create_table()?;
|
||||||
|
env1.set("assert", assert.clone())?;
|
||||||
|
|
||||||
|
let env2 = lua.create_table()?;
|
||||||
|
env2.set("assert", assert)?;
|
||||||
|
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
test_var = 1
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.set_environment(env1.clone())?
|
||||||
|
.exec()?;
|
||||||
|
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
assert(test_var == nil)
|
||||||
|
test_var = 2
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.set_environment(env2.clone())?
|
||||||
|
.exec()?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
lua.load("test_var").set_environment(env1)?.eval::<i32>()?,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
lua.load("test_var").set_environment(env2)?.eval::<i32>()?,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn context_thread() -> Result<()> {
|
||||||
|
let lua = make_lua();
|
||||||
|
|
||||||
|
let f = lua
|
||||||
|
.load(
|
||||||
|
r#"
|
||||||
|
local thread = ...
|
||||||
|
assert(coroutine.running() == thread)
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.into_function()?;
|
||||||
|
|
||||||
|
f.call::<_, ()>(lua.current_thread())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
|
|
||||||
use rlua::{Error, Function, Lua, Result, Thread, ThreadStatus};
|
use rlua::{Error, Function, Result, Thread, ThreadStatus};
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_thread() {
|
fn test_thread() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let thread = lua
|
|
||||||
.create_thread(
|
let thread = lua.create_thread(
|
||||||
lua.eval::<_, Function>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function (s)
|
function (s)
|
||||||
local sum = s
|
local sum = s
|
||||||
|
@ -19,27 +19,24 @@ fn test_thread() {
|
||||||
return sum
|
return sum
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.eval()?,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(0).unwrap(), 0);
|
assert_eq!(thread.resume::<_, i64>(0)?, 0);
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(1).unwrap(), 1);
|
assert_eq!(thread.resume::<_, i64>(1)?, 1);
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(2).unwrap(), 3);
|
assert_eq!(thread.resume::<_, i64>(2)?, 3);
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(3).unwrap(), 6);
|
assert_eq!(thread.resume::<_, i64>(3)?, 6);
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(4).unwrap(), 10);
|
assert_eq!(thread.resume::<_, i64>(4)?, 10);
|
||||||
assert_eq!(thread.status(), ThreadStatus::Unresumable);
|
assert_eq!(thread.status(), ThreadStatus::Unresumable);
|
||||||
|
|
||||||
let accumulate = lua
|
let accumulate = lua.create_thread(
|
||||||
.create_thread(
|
lua.load(
|
||||||
lua.eval::<_, Function>(
|
|
||||||
r#"
|
r#"
|
||||||
function (sum)
|
function (sum)
|
||||||
while true do
|
while true do
|
||||||
|
@ -47,22 +44,20 @@ fn test_thread() {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.eval::<Function>()?,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
accumulate.resume::<_, ()>(i).unwrap();
|
accumulate.resume::<_, ()>(i)?;
|
||||||
}
|
}
|
||||||
assert_eq!(accumulate.resume::<_, i64>(4).unwrap(), 10);
|
assert_eq!(accumulate.resume::<_, i64>(4)?, 10);
|
||||||
assert_eq!(accumulate.status(), ThreadStatus::Resumable);
|
assert_eq!(accumulate.status(), ThreadStatus::Resumable);
|
||||||
assert!(accumulate.resume::<_, ()>("error").is_err());
|
assert!(accumulate.resume::<_, ()>("error").is_err());
|
||||||
assert_eq!(accumulate.status(), ThreadStatus::Error);
|
assert_eq!(accumulate.status(), ThreadStatus::Error);
|
||||||
|
|
||||||
let thread = lua
|
let thread = lua
|
||||||
.eval::<_, Thread>(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
coroutine.create(function ()
|
coroutine.create(function ()
|
||||||
while true do
|
while true do
|
||||||
|
@ -70,14 +65,13 @@ fn test_thread() {
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval::<Thread>()?;
|
||||||
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
assert_eq!(thread.status(), ThreadStatus::Resumable);
|
||||||
assert_eq!(thread.resume::<_, i64>(()).unwrap(), 42);
|
assert_eq!(thread.resume::<_, i64>(())?, 42);
|
||||||
|
|
||||||
let thread: Thread = lua
|
let thread: Thread = lua
|
||||||
.eval(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
coroutine.create(function(arg)
|
coroutine.create(function(arg)
|
||||||
assert(arg == 42)
|
assert(arg == 42)
|
||||||
|
@ -86,34 +80,38 @@ fn test_thread() {
|
||||||
return 987
|
return 987
|
||||||
end)
|
end)
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.eval()?;
|
||||||
|
|
||||||
assert_eq!(thread.resume::<_, u32>(42).unwrap(), 123);
|
assert_eq!(thread.resume::<_, u32>(42)?, 123);
|
||||||
assert_eq!(thread.resume::<_, u32>(43).unwrap(), 987);
|
assert_eq!(thread.resume::<_, u32>(43)?, 987);
|
||||||
|
|
||||||
match thread.resume::<_, u32>(()) {
|
match thread.resume::<_, u32>(()) {
|
||||||
Err(Error::CoroutineInactive) => {}
|
Err(Error::CoroutineInactive) => {}
|
||||||
Err(_) => panic!("resuming dead coroutine error is not CoroutineInactive kind"),
|
Err(_) => panic!("resuming dead coroutine error is not CoroutineInactive kind"),
|
||||||
_ => panic!("resuming dead coroutine did not return error"),
|
_ => panic!("resuming dead coroutine did not return error"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coroutine_from_closure() {
|
fn coroutine_from_closure() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let thrd_main = lua.create_function(|_, ()| Ok(())).unwrap();
|
|
||||||
lua.globals().set("main", thrd_main).unwrap();
|
let thrd_main = lua.create_function(|_, ()| Ok(()))?;
|
||||||
let thrd: Thread = lua.eval("coroutine.create(main)", None).unwrap();
|
lua.globals().set("main", thrd_main)?;
|
||||||
thrd.resume::<_, ()>(()).unwrap();
|
let thrd: Thread = lua.load("coroutine.create(main)").eval()?;
|
||||||
|
thrd.resume::<_, ()>(())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coroutine_panic() {
|
fn coroutine_panic() {
|
||||||
match catch_unwind(|| -> Result<()> {
|
match catch_unwind(|| -> Result<()> {
|
||||||
// check that coroutines propagate panics correctly
|
// check that coroutines propagate panics correctly
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let thrd_main = lua.create_function(|_, ()| -> Result<()> {
|
let thrd_main = lua.create_function(|_, ()| -> Result<()> {
|
||||||
panic!("test_panic");
|
panic!("test_panic");
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
|
|
||||||
use rlua::{Function, LightUserData, Lua};
|
use rlua::{Function, LightUserData, Result};
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lightuserdata() {
|
fn test_lightuserdata() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function id(a)
|
function id(a)
|
||||||
return a
|
return a
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
|
|
||||||
let res = globals
|
let res = globals
|
||||||
.get::<_, Function>("id")
|
.get::<_, Function>("id")?
|
||||||
.unwrap()
|
.call::<_, LightUserData>(LightUserData(42 as *mut c_void))?;
|
||||||
.call::<_, LightUserData>(LightUserData(42 as *mut c_void))
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(res, LightUserData(42 as *mut c_void));
|
assert_eq!(res, LightUserData(42 as *mut c_void));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,36 @@
|
||||||
extern crate failure;
|
|
||||||
extern crate rlua;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use failure::err_msg;
|
use rlua::{
|
||||||
use rlua::{ExternalError, Function, Lua, MetaMethod, String, UserData, UserDataMethods};
|
AnyUserData, ExternalError, Function, MetaMethod, Result, String, UserData, UserDataMethods,
|
||||||
|
};
|
||||||
|
|
||||||
|
include!("_lua.rs");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_user_data() {
|
fn test_user_data() -> Result<()> {
|
||||||
struct UserData1(i64);
|
struct UserData1(i64);
|
||||||
struct UserData2(Box<i64>);
|
struct UserData2(Box<i64>);
|
||||||
|
|
||||||
impl UserData for UserData1 {};
|
impl UserData for UserData1 {};
|
||||||
impl UserData for UserData2 {};
|
impl UserData for UserData2 {};
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
|
let userdata1 = lua.create_userdata(UserData1(1))?;
|
||||||
let userdata1 = lua.create_userdata(UserData1(1)).unwrap();
|
let userdata2 = lua.create_userdata(UserData2(Box::new(2)))?;
|
||||||
let userdata2 = lua.create_userdata(UserData2(Box::new(2))).unwrap();
|
|
||||||
|
|
||||||
assert!(userdata1.is::<UserData1>());
|
assert!(userdata1.is::<UserData1>());
|
||||||
assert!(!userdata1.is::<UserData2>());
|
assert!(!userdata1.is::<UserData2>());
|
||||||
assert!(userdata2.is::<UserData2>());
|
assert!(userdata2.is::<UserData2>());
|
||||||
assert!(!userdata2.is::<UserData1>());
|
assert!(!userdata2.is::<UserData1>());
|
||||||
|
|
||||||
assert_eq!(userdata1.borrow::<UserData1>().unwrap().0, 1);
|
assert_eq!(userdata1.borrow::<UserData1>()?.0, 1);
|
||||||
assert_eq!(*userdata2.borrow::<UserData2>().unwrap().0, 2);
|
assert_eq!(*userdata2.borrow::<UserData2>()?.0, 2);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_methods() {
|
fn test_methods() -> Result<()> {
|
||||||
struct MyUserData(i64);
|
struct MyUserData(i64);
|
||||||
|
|
||||||
impl UserData for MyUserData {
|
impl UserData for MyUserData {
|
||||||
|
@ -42,11 +43,11 @@ fn test_methods() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
let userdata = lua.create_userdata(MyUserData(42)).unwrap();
|
let userdata = lua.create_userdata(MyUserData(42))?;
|
||||||
globals.set("userdata", userdata.clone()).unwrap();
|
globals.set("userdata", userdata.clone())?;
|
||||||
lua.exec::<_, ()>(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
function get_it()
|
function get_it()
|
||||||
return userdata:get_value()
|
return userdata:get_value()
|
||||||
|
@ -56,20 +57,21 @@ fn test_methods() {
|
||||||
return userdata:set_value(i)
|
return userdata:set_value(i)
|
||||||
end
|
end
|
||||||
"#,
|
"#,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.exec()?;
|
||||||
let get = globals.get::<_, Function>("get_it").unwrap();
|
let get = globals.get::<_, Function>("get_it")?;
|
||||||
let set = globals.get::<_, Function>("set_it").unwrap();
|
let set = globals.get::<_, Function>("set_it")?;
|
||||||
assert_eq!(get.call::<_, i64>(()).unwrap(), 42);
|
assert_eq!(get.call::<_, i64>(())?, 42);
|
||||||
userdata.borrow_mut::<MyUserData>().unwrap().0 = 64;
|
userdata.borrow_mut::<MyUserData>()?.0 = 64;
|
||||||
assert_eq!(get.call::<_, i64>(()).unwrap(), 64);
|
assert_eq!(get.call::<_, i64>(())?, 64);
|
||||||
set.call::<_, ()>(100).unwrap();
|
set.call::<_, ()>(100)?;
|
||||||
assert_eq!(get.call::<_, i64>(()).unwrap(), 100);
|
assert_eq!(get.call::<_, i64>(())?, 100);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_metamethods() {
|
fn test_metamethods() -> Result<()> {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct MyUserData(i64);
|
struct MyUserData(i64);
|
||||||
|
|
||||||
|
@ -88,35 +90,30 @@ fn test_metamethods() {
|
||||||
if index.to_str()? == "inner" {
|
if index.to_str()? == "inner" {
|
||||||
Ok(data.0)
|
Ok(data.0)
|
||||||
} else {
|
} else {
|
||||||
Err(err_msg("no such custom index").to_lua_err())
|
Err("no such custom index".to_lua_err())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
globals.set("userdata1", MyUserData(7)).unwrap();
|
globals.set("userdata1", MyUserData(7))?;
|
||||||
globals.set("userdata2", MyUserData(3)).unwrap();
|
globals.set("userdata2", MyUserData(3))?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lua.eval::<_, MyUserData>("userdata1 + userdata2", None)
|
lua.load("userdata1 + userdata2").eval::<MyUserData>()?.0,
|
||||||
.unwrap()
|
|
||||||
.0,
|
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
|
||||||
lua.eval::<_, MyUserData>("userdata1 - userdata2", None)
|
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
|
||||||
.unwrap()
|
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
||||||
.0,
|
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
||||||
4
|
|
||||||
);
|
Ok(())
|
||||||
assert_eq!(lua.eval::<_, i64>("userdata1:get()", None).unwrap(), 7);
|
|
||||||
assert_eq!(lua.eval::<_, i64>("userdata2.inner", None).unwrap(), 3);
|
|
||||||
assert!(lua.eval::<_, ()>("userdata2.nonexist_field", None).is_err());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gc_userdata() {
|
fn test_gc_userdata() -> Result<()> {
|
||||||
struct MyUserdata {
|
struct MyUserdata {
|
||||||
id: u8,
|
id: u8,
|
||||||
}
|
}
|
||||||
|
@ -130,14 +127,11 @@ fn test_gc_userdata() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
{
|
lua.globals().set("userdata", MyUserdata { id: 123 })?;
|
||||||
let globals = lua.globals();
|
|
||||||
globals.set("userdata", MyUserdata { id: 123 }).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(lua
|
assert!(lua
|
||||||
.eval::<_, ()>(
|
.load(
|
||||||
r#"
|
r#"
|
||||||
local tbl = setmetatable({
|
local tbl = setmetatable({
|
||||||
userdata = userdata
|
userdata = userdata
|
||||||
|
@ -150,40 +144,96 @@ fn test_gc_userdata() {
|
||||||
userdata = nil -- make table and userdata collectable
|
userdata = nil -- make table and userdata collectable
|
||||||
collectgarbage("collect")
|
collectgarbage("collect")
|
||||||
hatch:access()
|
hatch:access()
|
||||||
"#,
|
"#
|
||||||
None
|
|
||||||
)
|
)
|
||||||
|
.exec()
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn detroys_userdata() {
|
fn detroys_userdata() -> Result<()> {
|
||||||
struct MyUserdata(Arc<()>);
|
struct MyUserdata(Arc<()>);
|
||||||
|
|
||||||
impl UserData for MyUserdata {}
|
impl UserData for MyUserdata {}
|
||||||
|
|
||||||
let rc = Arc::new(());
|
let rc = Arc::new(());
|
||||||
|
|
||||||
let lua = Lua::new();
|
let lua = make_lua();
|
||||||
{
|
lua.globals().set("userdata", MyUserdata(rc.clone()))?;
|
||||||
let globals = lua.globals();
|
|
||||||
globals.set("userdata", MyUserdata(rc.clone())).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(Arc::strong_count(&rc), 2);
|
assert_eq!(Arc::strong_count(&rc), 2);
|
||||||
drop(lua); // should destroy all objects
|
|
||||||
|
// should destroy all objects
|
||||||
|
let _ = lua.globals().raw_remove("userdata")?;
|
||||||
|
lua.gc_collect()?;
|
||||||
|
|
||||||
assert_eq!(Arc::strong_count(&rc), 1);
|
assert_eq!(Arc::strong_count(&rc), 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn user_value() {
|
fn user_value() -> Result<()> {
|
||||||
let lua = Lua::new();
|
|
||||||
|
|
||||||
struct MyUserData;
|
struct MyUserData;
|
||||||
impl UserData for MyUserData {}
|
impl UserData for MyUserData {}
|
||||||
|
|
||||||
let ud = lua.create_userdata(MyUserData).unwrap();
|
let lua = make_lua();
|
||||||
ud.set_user_value("hello").unwrap();
|
let ud = lua.create_userdata(MyUserData)?;
|
||||||
assert_eq!(ud.get_user_value::<String>().unwrap(), "hello");
|
ud.set_user_value("hello")?;
|
||||||
|
assert_eq!(ud.get_user_value::<String>()?, "hello");
|
||||||
assert!(ud.get_user_value::<u32>().is_err());
|
assert!(ud.get_user_value::<u32>().is_err());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_functions() -> Result<()> {
|
||||||
|
struct MyUserData(i64);
|
||||||
|
|
||||||
|
impl UserData for MyUserData {
|
||||||
|
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
methods.add_function("get_value", |_, ud: AnyUserData| {
|
||||||
|
Ok(ud.borrow::<MyUserData>()?.0)
|
||||||
|
});
|
||||||
|
methods.add_function("set_value", |_, (ud, value): (AnyUserData, i64)| {
|
||||||
|
ud.borrow_mut::<MyUserData>()?.0 = value;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
methods.add_function("get_constant", |_, ()| Ok(7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let lua = make_lua();
|
||||||
|
let globals = lua.globals();
|
||||||
|
let userdata = lua.create_userdata(MyUserData(42))?;
|
||||||
|
globals.set("userdata", userdata.clone())?;
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
function get_it()
|
||||||
|
return userdata:get_value()
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_it(i)
|
||||||
|
return userdata:set_value(i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_constant()
|
||||||
|
return userdata.get_constant()
|
||||||
|
end
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()?;
|
||||||
|
let get = globals.get::<_, Function>("get_it")?;
|
||||||
|
let set = globals.get::<_, Function>("set_it")?;
|
||||||
|
let get_constant = globals.get::<_, Function>("get_constant")?;
|
||||||
|
assert_eq!(get.call::<_, i64>(())?, 42);
|
||||||
|
userdata.borrow_mut::<MyUserData>()?.0 = 64;
|
||||||
|
assert_eq!(get.call::<_, i64>(())?, 64);
|
||||||
|
set.call::<_, ()>(100)?;
|
||||||
|
assert_eq!(get.call::<_, i64>(())?, 100);
|
||||||
|
assert_eq!(get_constant.call::<_, i64>(())?, 7);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue