diff --git a/tests/function.rs b/tests/function.rs index cec11f3..b8c1070 100644 --- a/tests/function.rs +++ b/tests/function.rs @@ -1,27 +1,34 @@ -use mlua::{Error, Function, Lua, Result, String, Table}; +use mlua::{Error, Function, Lua, Result, String, Table, Variadic}; #[test] -fn test_function() -> Result<()> { +fn test_function_call() -> Result<()> { let lua = Lua::new(); - let globals = lua.globals(); - lua.load( - r#" - function concat(arg1, arg2) - return arg1 .. arg2 - end - "#, - ) - .exec()?; - - let concat = globals.get::("concat")?; + let concat = lua + .load(r#"function(arg1, arg2) return arg1 .. arg2 end"#) + .eval::()?; assert_eq!(concat.call::(("foo", "bar"))?, "foobar"); Ok(()) } #[test] -fn test_bind() -> Result<()> { +fn test_function_call_error() -> Result<()> { + let lua = Lua::new(); + + let concat_err = lua + .load(r#"function(arg1, arg2) error("concat error") end"#) + .eval::()?; + match concat_err.call::(("foo", "bar")) { + Err(Error::RuntimeError(msg)) if msg.contains("concat error") => {} + other => panic!("unexpected result: {other:?}"), + } + + Ok(()) +} + +#[test] +fn test_function_bind() -> Result<()> { let lua = Lua::new(); let globals = lua.globals(); @@ -54,59 +61,13 @@ fn test_bind() -> Result<()> { } #[test] -fn test_rust_function() -> Result<()> { +#[cfg(not(target_arch = "wasm32"))] +fn test_function_bind_error() -> Result<()> { let lua = Lua::new(); - let globals = lua.globals(); - lua.load( - r#" - function lua_function() - return rust_function() - end - - -- Test to make sure chunk return is ignored - return 1 - "#, - ) - .exec()?; - - let lua_function = globals.get::("lua_function")?; - let rust_function = lua.create_function(|_, ()| Ok("hello"))?; - - globals.set("rust_function", rust_function)?; - assert_eq!(lua_function.call::(())?, "hello"); - - Ok(()) -} - -#[test] -fn test_c_function() -> Result<()> { - let lua = Lua::new(); - - unsafe extern "C-unwind" fn c_function(state: *mut mlua::lua_State) -> std::os::raw::c_int { - ffi::lua_pushboolean(state, 1); - ffi::lua_setglobal(state, b"c_function\0" as *const _ as *const _); - 0 - } - - let func = unsafe { lua.create_c_function(c_function)? }; - func.call::<()>(())?; - assert_eq!(lua.globals().get::("c_function")?, true); - - Ok(()) -} - -#[cfg(not(feature = "luau"))] -#[test] -fn test_dump() -> Result<()> { - let lua = unsafe { Lua::unsafe_new() }; - - let concat_lua = lua - .load(r#"function(arg1, arg2) return arg1 .. arg2 end"#) - .eval::()?; - let concat = lua.load(&concat_lua.dump(false)).into_function()?; - - assert_eq!(concat.call::(("foo", "bar"))?, "foobar"); + let func = lua.load(r#"function(...) end"#).eval::()?; + assert!(func.bind(Variadic::from_iter(1..1000000)).is_err()); + assert!(func.call::<()>(Variadic::from_iter(1..1000000)).is_err()); Ok(()) } @@ -114,14 +75,15 @@ fn test_dump() -> Result<()> { #[test] fn test_function_environment() -> Result<()> { let lua = Lua::new(); + let globals = lua.globals(); // We must not get or set environment for C functions let rust_func = lua.create_function(|_, ()| Ok("hello"))?; assert_eq!(rust_func.environment(), None); - assert_eq!(rust_func.set_environment(lua.globals()).ok(), Some(false)); + assert_eq!(rust_func.set_environment(globals.clone()).ok(), Some(false)); // Test getting Lua function environment - lua.globals().set("hello", "global")?; + globals.set("hello", "global")?; let lua_func = lua .load( r#" @@ -135,7 +97,7 @@ fn test_function_environment() -> Result<()> { .eval::()?; let lua_func2 = lua.load("return hello").into_function()?; assert_eq!(lua_func.call::(())?, "global"); - assert_eq!(lua_func.environment(), Some(lua.globals())); + assert_eq!(lua_func.environment().as_ref(), Some(&globals)); // Test changing the environment let env = lua.create_table_from([("hello", "local")])?; @@ -154,9 +116,9 @@ fn test_function_environment() -> Result<()> { "#, ) .exec()?; - let lucky = lua.globals().get::("lucky")?; + let lucky = globals.get::("lucky")?; assert_eq!(lucky.call::(())?, "number is 15"); - let new_env = lua.globals().get::("new_env")?; + let new_env = globals.get::
("new_env")?; lucky.set_environment(new_env)?; assert_eq!(lucky.call::(())?, "15"); @@ -235,6 +197,95 @@ fn test_function_info() -> Result<()> { Ok(()) } +#[cfg(not(feature = "luau"))] +#[test] +fn test_function_dump() -> Result<()> { + let lua = unsafe { Lua::unsafe_new() }; + + let concat_lua = lua + .load(r#"function(arg1, arg2) return arg1 .. arg2 end"#) + .eval::()?; + let concat = lua.load(&concat_lua.dump(false)).into_function()?; + + assert_eq!(concat.call::(("foo", "bar"))?, "foobar"); + + Ok(()) +} + +#[cfg(feature = "luau")] +#[test] +fn test_finction_coverage() -> Result<()> { + let lua = Lua::new(); + + lua.set_compiler(mlua::Compiler::default().set_coverage_level(1)); + + let f = lua + .load( + r#"local s = "abc" + assert(#s == 3) + + function abc(i) + if i < 5 then + return 0 + else + return 1 + end + end + + (function() + (function() abc(10) end)() + end)() + "#, + ) + .into_function()?; + + f.call::<()>(())?; + + let mut report = Vec::new(); + f.coverage(|cov| { + report.push(cov); + }); + + assert_eq!( + report[0], + mlua::CoverageInfo { + function: None, + line_defined: 1, + depth: 0, + hits: vec![-1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1], + } + ); + assert_eq!( + report[1], + mlua::CoverageInfo { + function: Some("abc".into()), + line_defined: 4, + depth: 1, + hits: vec![-1, -1, -1, -1, -1, 1, 0, -1, 1, -1, -1, -1, -1, -1, -1, -1], + } + ); + assert_eq!( + report[2], + mlua::CoverageInfo { + function: None, + line_defined: 12, + depth: 1, + hits: vec![-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1], + } + ); + assert_eq!( + report[3], + mlua::CoverageInfo { + function: None, + line_defined: 13, + depth: 2, + hits: vec![-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1], + } + ); + + Ok(()) +} + #[test] fn test_function_pointer() -> Result<()> { let lua = Lua::new(); diff --git a/tests/luau.rs b/tests/luau.rs index 2c24c17..0b37f7d 100644 --- a/tests/luau.rs +++ b/tests/luau.rs @@ -6,10 +6,7 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; -use mlua::{ - Compiler, CoverageInfo, Error, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, - VmState, -}; +use mlua::{Compiler, Error, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, VmState}; #[test] fn test_version() -> Result<()> { @@ -392,79 +389,6 @@ fn test_interrupts() -> Result<()> { Ok(()) } -#[test] -fn test_coverage() -> Result<()> { - let lua = Lua::new(); - - lua.set_compiler(Compiler::default().set_coverage_level(1)); - - let f = lua - .load( - r#"local s = "abc" - assert(#s == 3) - - function abc(i) - if i < 5 then - return 0 - else - return 1 - end - end - - (function() - (function() abc(10) end)() - end)() - "#, - ) - .into_function()?; - - f.call::<()>(())?; - - let mut report = Vec::new(); - f.coverage(|cov| { - report.push(cov); - }); - - assert_eq!( - report[0], - CoverageInfo { - function: None, - line_defined: 1, - depth: 0, - hits: vec![-1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1], - } - ); - assert_eq!( - report[1], - CoverageInfo { - function: Some("abc".into()), - line_defined: 4, - depth: 1, - hits: vec![-1, -1, -1, -1, -1, 1, 0, -1, 1, -1, -1, -1, -1, -1, -1, -1], - } - ); - assert_eq!( - report[2], - CoverageInfo { - function: None, - line_defined: 12, - depth: 1, - hits: vec![-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1], - } - ); - assert_eq!( - report[3], - CoverageInfo { - function: None, - line_defined: 13, - depth: 2, - hits: vec![-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1], - } - ); - - Ok(()) -} - #[test] fn test_fflags() { // We cannot really on any particular feature flag to be present diff --git a/tests/tests.rs b/tests/tests.rs index a819d06..f4faac5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -925,26 +925,6 @@ fn test_too_many_recursions() -> Result<()> { Ok(()) } -#[test] -#[cfg(not(target_arch = "wasm32"))] -fn test_too_many_binds() -> Result<()> { - let lua = Lua::new(); - let globals = lua.globals(); - lua.load( - r#" - function f(...) - end - "#, - ) - .exec()?; - - let concat = globals.get::("f")?; - assert!(concat.bind(Variadic::from_iter(1..1000000)).is_err()); - assert!(concat.call::<()>(Variadic::from_iter(1..1000000)).is_err()); - - Ok(()) -} - #[test] #[cfg(not(target_arch = "wasm32"))] fn test_ref_stack_exhaustion() {