diff --git a/src/string.rs b/src/string.rs index f7c7ec4..55da706 100644 --- a/src/string.rs +++ b/src/string.rs @@ -64,7 +64,7 @@ impl<'lua> String<'lua> { /// ``` pub fn as_bytes(&self) -> &[u8] { let nulled = self.as_bytes_with_nul(); - &nulled[..nulled.len()-1] + &nulled[..nulled.len() - 1] } /// Get the bytes that make up this string, including the trailing nul byte. @@ -100,7 +100,10 @@ impl<'lua> AsRef<[u8]> for String<'lua> { // The only downside is that this disallows a comparison with `Cow`, as that only implements // `AsRef`, which collides with this impl. Requiring `AsRef` would fix that, but limit us // in other ways. -impl<'lua, T> PartialEq for String<'lua> where T: AsRef<[u8]> { +impl<'lua, T> PartialEq for String<'lua> +where + T: AsRef<[u8]>, +{ fn eq(&self, other: &T) -> bool { self.as_bytes() == other.as_ref() } @@ -109,11 +112,14 @@ impl<'lua, T> PartialEq for String<'lua> where T: AsRef<[u8]> { #[cfg(test)] mod tests { use super::*; - use Lua; + use lua::Lua; use std::borrow::Cow; - fn with_str(s: &str, f: F) where F: FnOnce(String) { + fn with_str(s: &str, f: F) + where + F: FnOnce(String), + { let lua = Lua::new(); let string = lua.create_string(s); f(string); @@ -122,13 +128,15 @@ mod tests { #[test] fn compare() { // 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, b"teststring")); // &[u8] - with_str("teststring", |t| assert_eq!(t, b"teststring".to_vec())); // Vec - with_str("teststring", |t| assert_eq!(t, "teststring".to_string())); // String - with_str("teststring", |t| assert_eq!(t, t)); // rlua::String - with_str("teststring", |t| assert_eq!(t, Cow::from(b"teststring".as_ref()))); // Cow (borrowed) - with_str("bla", |t| assert_eq!(t, Cow::from(b"bla".to_vec()))); // Cow (owned) + 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".to_vec())); // Vec + with_str("teststring", |t| assert_eq!(t, "teststring".to_string())); // String + with_str("teststring", |t| assert_eq!(t, t)); // rlua::String + with_str("teststring", |t| { + assert_eq!(t, Cow::from(b"teststring".as_ref())) + }); // Cow (borrowed) + with_str("bla", |t| assert_eq!(t, Cow::from(b"bla".to_vec()))); // Cow (owned) } #[test] diff --git a/src/table.rs b/src/table.rs index 22a50eb..f82db87 100644 --- a/src/table.rs +++ b/src/table.rs @@ -336,9 +336,9 @@ pub struct TablePairs<'lua, K, V> { } impl<'lua, K, V> Iterator for TablePairs<'lua, K, V> - where - K: FromLua<'lua>, - V: FromLua<'lua>, +where + K: FromLua<'lua>, + V: FromLua<'lua>, { type Item = Result<(K, V)>; @@ -366,10 +366,10 @@ impl<'lua, K, V> Iterator for TablePairs<'lua, K, V> ffi::lua_pop(lua.state, 1); Some((|| { - let key = K::from_lua(key, lua)?; - let value = V::from_lua(value, lua)?; - Ok((key, value)) - })()) + let key = K::from_lua(key, lua)?; + let value = V::from_lua(value, lua)?; + Ok((key, value)) + })()) } Err(e) => Some(Err(e)), } @@ -393,8 +393,8 @@ pub struct TableSequence<'lua, V> { } impl<'lua, V> Iterator for TableSequence<'lua, V> - where - V: FromLua<'lua>, +where + V: FromLua<'lua>, { type Item = Result; @@ -427,3 +427,208 @@ impl<'lua, V> Iterator for TableSequence<'lua, V> } } } + +#[cfg(test)] +mod tests { + use super::Table; + use error::Result; + use lua::{Value, Nil, Lua}; + + #[test] + fn test_set_get() { + let lua = Lua::new(); + let globals = lua.globals(); + globals.set("foo", "bar").unwrap(); + globals.set("baz", "baf").unwrap(); + assert_eq!(globals.get::<_, String>("foo").unwrap(), "bar"); + assert_eq!(globals.get::<_, String>("baz").unwrap(), "baf"); + } + + #[test] + fn test_table() { + let lua = Lua::new(); + let globals = lua.globals(); + + globals.set("table", lua.create_table()).unwrap(); + let table1: Table = globals.get("table").unwrap(); + let table2: Table = globals.get("table").unwrap(); + + table1.set("foo", "bar").unwrap(); + table2.set("baz", "baf").unwrap(); + + assert_eq!(table2.get::<_, String>("foo").unwrap(), "bar"); + assert_eq!(table1.get::<_, String>("baz").unwrap(), "baf"); + + lua.exec::<()>( + r#" + table1 = {1, 2, 3, 4, 5} + table2 = {} + table3 = {1, 2, nil, 4, 5} + "#, + None, + ).unwrap(); + + let table1 = globals.get::<_, Table>("table1").unwrap(); + let table2 = globals.get::<_, Table>("table2").unwrap(); + let table3 = globals.get::<_, Table>("table3").unwrap(); + + assert_eq!(table1.len().unwrap(), 5); + assert_eq!( + table1 + .clone() + .pairs() + .collect::>>() + .unwrap(), + vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)] + ); + assert_eq!( + table1 + .clone() + .sequence_values() + .collect::>>() + .unwrap(), + vec![1, 2, 3, 4, 5] + ); + + assert_eq!(table2.len().unwrap(), 0); + assert_eq!( + table2 + .clone() + .pairs() + .collect::>>() + .unwrap(), + vec![] + ); + assert_eq!( + table2 + .sequence_values() + .collect::>>() + .unwrap(), + vec![] + ); + + // sequence_values should only iterate until the first border + assert_eq!( + table3 + .sequence_values() + .collect::>>() + .unwrap(), + vec![1, 2] + ); + + globals + .set( + "table4", + lua.create_sequence_from(vec![1, 2, 3, 4, 5]).unwrap(), + ) + .unwrap(); + let table4 = globals.get::<_, Table>("table4").unwrap(); + assert_eq!( + table4.pairs().collect::>>().unwrap(), + vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)] + ); + } + + #[test] + fn test_table_scope() { + let lua = Lua::new(); + let globals = lua.globals(); + lua.exec::<()>( + r#" + touter = { + tin = {1, 2, 3} + } + "#, + None, + ).unwrap(); + + // Make sure that table gets do not borrow the table, but instead just borrow lua. + let tin; + { + let touter = globals.get::<_, Table>("touter").unwrap(); + tin = touter.get::<_, Table>("tin").unwrap(); + } + + assert_eq!(tin.get::<_, i64>(1).unwrap(), 1); + assert_eq!(tin.get::<_, i64>(2).unwrap(), 2); + assert_eq!(tin.get::<_, i64>(3).unwrap(), 3); + } + + #[test] + fn test_setmetatable_gc() { + let lua = Lua::new(); + lua.exec::<()>( + r#" + val = nil + table = {} + setmetatable(table, { + __gc = function() + val = "gcwascalled" + end + }) + table_badgc = {} + setmetatable(table_badgc, { + __gc = "what's a gc" + }) + table = nil + table_badgc = nil + collectgarbage("collect") + "#, + None, + ).unwrap(); + + let globals = lua.globals(); + assert_eq!(globals.get::<_, String>("val").unwrap(), "gcwascalled"); + } + + #[test] + fn test_metatable() { + let lua = Lua::new(); + + let table = lua.create_table(); + let metatable = lua.create_table(); + metatable.set("__index", lua.create_function(|_, ()| Ok("index_value"))).unwrap(); + table.set_metatable(Some(metatable)); + assert_eq!(table.get::<_, String>("any_key").unwrap(), "index_value"); + match table.raw_get::<_, Value>("any_key").unwrap() { + Nil => {} + _ => panic!(), + } + table.set_metatable(None); + match table.get::<_, Value>("any_key").unwrap() { + Nil => {} + _ => panic!(), + }; + } + + #[test] + fn test_table_error() { + let lua = Lua::new(); + let globals = lua.globals(); + lua.exec::<()>( + r#" + table = {} + setmetatable(table, { + __index = function() + error("lua error") + end, + __newindex = function() + error("lua error") + end, + __len = function() + error("lua error") + end + }) + "#, + None, + ).unwrap(); + + let bad_table: Table = globals.get("table").unwrap(); + assert!(bad_table.set(1, 1).is_err()); + assert!(bad_table.get::<_, i32>(1).is_err()); + assert!(bad_table.len().is_err()); + assert!(bad_table.raw_set(1, 1).is_ok()); + assert!(bad_table.raw_get::<_, i32>(1).is_ok()); + assert_eq!(bad_table.raw_len(), 1); + } +} diff --git a/src/tests.rs b/src/tests.rs index f9d29ac..3750d4b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -4,19 +4,9 @@ use std::panic::catch_unwind; use std::os::raw::c_void; use String as LuaString; -use {Lua, Nil, Result, ExternalError, LightUserData, UserDataMethods, UserData, Table, Thread, +use {Lua, Result, ExternalError, LightUserData, UserDataMethods, UserData, Table, Thread, ThreadStatus, Error, Function, Value, Variadic, MetaMethod}; -#[test] -fn test_set_get() { - let lua = Lua::new(); - let globals = lua.globals(); - globals.set("foo", "bar").unwrap(); - globals.set("baz", "baf").unwrap(); - assert_eq!(globals.get::<_, String>("foo").unwrap(), "bar"); - assert_eq!(globals.get::<_, String>("baz").unwrap(), "baf"); -} - #[test] fn test_load() { let lua = Lua::new(); @@ -79,91 +69,6 @@ fn test_eval() { } } -#[test] -fn test_table() { - let lua = Lua::new(); - let globals = lua.globals(); - - globals.set("table", lua.create_table()).unwrap(); - let table1: Table = globals.get("table").unwrap(); - let table2: Table = globals.get("table").unwrap(); - - table1.set("foo", "bar").unwrap(); - table2.set("baz", "baf").unwrap(); - - assert_eq!(table2.get::<_, String>("foo").unwrap(), "bar"); - assert_eq!(table1.get::<_, String>("baz").unwrap(), "baf"); - - lua.exec::<()>( - r#" - table1 = {1, 2, 3, 4, 5} - table2 = {} - table3 = {1, 2, nil, 4, 5} - "#, - None, - ).unwrap(); - - let table1 = globals.get::<_, Table>("table1").unwrap(); - let table2 = globals.get::<_, Table>("table2").unwrap(); - let table3 = globals.get::<_, Table>("table3").unwrap(); - - assert_eq!(table1.len().unwrap(), 5); - assert_eq!( - table1 - .clone() - .pairs() - .collect::>>() - .unwrap(), - vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)] - ); - assert_eq!( - table1 - .clone() - .sequence_values() - .collect::>>() - .unwrap(), - vec![1, 2, 3, 4, 5] - ); - - assert_eq!(table2.len().unwrap(), 0); - assert_eq!( - table2 - .clone() - .pairs() - .collect::>>() - .unwrap(), - vec![] - ); - assert_eq!( - table2 - .sequence_values() - .collect::>>() - .unwrap(), - vec![] - ); - - // sequence_values should only iterate until the first border - assert_eq!( - table3 - .sequence_values() - .collect::>>() - .unwrap(), - vec![1, 2] - ); - - globals - .set( - "table4", - lua.create_sequence_from(vec![1, 2, 3, 4, 5]).unwrap(), - ) - .unwrap(); - let table4 = globals.get::<_, Table>("table4").unwrap(); - assert_eq!( - table4.pairs().collect::>>().unwrap(), - vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)] - ); -} - #[test] fn test_function() { let lua = Lua::new(); @@ -338,31 +243,6 @@ fn test_metamethods() { assert!(lua.eval::<()>("userdata2.nonexist_field", None).is_err()); } -#[test] -fn test_scope() { - let lua = Lua::new(); - let globals = lua.globals(); - lua.exec::<()>( - r#" - touter = { - tin = {1, 2, 3} - } - "#, - None, - ).unwrap(); - - // Make sure that table gets do not borrow the table, but instead just borrow lua. - let tin; - { - let touter = globals.get::<_, Table>("touter").unwrap(); - tin = touter.get::<_, Table>("tin").unwrap(); - } - - assert_eq!(tin.get::<_, i64>(1).unwrap(), 1); - assert_eq!(tin.get::<_, i64>(2).unwrap(), 2); - assert_eq!(tin.get::<_, i64>(3).unwrap(), 3); -} - #[test] fn test_lua_multi() { let lua = Lua::new(); @@ -692,37 +572,6 @@ fn test_lightuserdata() { assert_eq!(res, LightUserData(42 as *mut c_void)); } -#[test] -fn test_table_error() { - let lua = Lua::new(); - let globals = lua.globals(); - lua.exec::<()>( - r#" - table = {} - setmetatable(table, { - __index = function() - error("lua error") - end, - __newindex = function() - error("lua error") - end, - __len = function() - error("lua error") - end - }) - "#, - None, - ).unwrap(); - - let bad_table: Table = globals.get("table").unwrap(); - assert!(bad_table.set(1, 1).is_err()); - assert!(bad_table.get::<_, i32>(1).is_err()); - assert!(bad_table.len().is_err()); - assert!(bad_table.raw_set(1, 1).is_ok()); - assert!(bad_table.raw_get::<_, i32>(1).is_ok()); - assert_eq!(bad_table.raw_len(), 1); -} - #[test] fn test_result_conversions() { let lua = Lua::new(); @@ -908,53 +757,6 @@ fn test_pcall_xpcall() { .call::<_, ()>(()); } -#[test] -fn test_setmetatable_gc() { - let lua = Lua::new(); - lua.exec::<()>( - r#" - val = nil - table = {} - setmetatable(table, { - __gc = function() - val = "gcwascalled" - end - }) - table_badgc = {} - setmetatable(table_badgc, { - __gc = "what's a gc" - }) - table = nil - table_badgc = nil - collectgarbage("collect") - "#, - None, - ).unwrap(); - - let globals = lua.globals(); - assert_eq!(globals.get::<_, String>("val").unwrap(), "gcwascalled"); -} - -#[test] -fn test_metatable() { - let lua = Lua::new(); - - let table = lua.create_table(); - let metatable = lua.create_table(); - metatable.set("__index", lua.create_function(|_, ()| Ok("index_value"))).unwrap(); - table.set_metatable(Some(metatable)); - assert_eq!(table.get::<_, String>("any_key").unwrap(), "index_value"); - match table.raw_get::<_, Value>("any_key").unwrap() { - Nil => {} - _ => panic!(), - } - table.set_metatable(None); - match table.get::<_, Value>("any_key").unwrap() { - Nil => {} - _ => panic!(), - }; -} - // Need to use compiletest-rs or similar to make sure these don't compile. /* #[test]