[TestMethod] public void MemberAccess() { using (var lua = new Lua(true)) { lua.RegisterType(typeof(ExposedClass)); lua.DoString(@" assert(ExposedClass.PublicS) assert(ExposedClass().Public) " ); UAssert.Throws <LuaScriptException>(() => { lua.DoString(@" InternalS = ExposedClass.InternalS Internal = ExposedClass().Internal " ); }); UAssert.Throws <LuaScriptException>(() => { lua.DoString(@" ProtectedS = ExposedClass.ProtectedS Protected = ExposedClass().Protected " ); }); UAssert.Throws <LuaScriptException>(() => { lua.DoString(@" PrivateS = ExposedClass.PrivateS Private = ExposedClass().Private " ); }); CollectionAssert.DoesNotContain(lua.DoString("return InternalS,Internal,ProtectedS,Protected,PrivateS,Private"), true); } }
static T GetPCallError <T>(object[] results) { var err = GetPCallError(results); UAssert.IsInstanceOf <T>(err); return((T)err); }
static LuaScriptException GetPCallException(object[] results) { Assert.AreEqual(2, results.Length); Assert.AreEqual(false, results[0]); UAssert.IsInstanceOf <LuaScriptException>(results[1]); return((LuaScriptException)results[1]); }
[TestMethod] public void RawSetValue() { using (var lua = NewTest()) using (var table = (LuaTable)lua.DoString("return newTestTable(false, true)", "@Table.cs.RawSetValue.lua")[0]) { // array for (int i = 1; i <= _ArrayEnd * 2; ++i) { if (i <= _ArrayEnd) { UAssert.AreEqual <double>(i, table.GetValue(i)); } else { Assert.AreEqual(LuaType.Nil, table.GetValue(i).Type); } table.RawSetValue(i, 12); UAssert.AreEqual <double>(12.0, table.GetValue(i)); table.RawSetValue((double)i, 1212); UAssert.AreEqual <double>(1212.0, table.GetValue(i)); } // associative array var keys = Enumerable.Concat(_Keys, _EmptyKeys).ToArray(); for (int i = 0; i < keys.Length; ++i) { string k = keys[i]; if (i < _Keys.Count) { UAssert.AreEqual <double>(i + 1, table.GetValue(k)); } else { Assert.AreEqual(LuaType.Nil, table.GetValue(k).Type); } table.RawSetValue(k, 12); UAssert.AreEqual <double>(12.0, table.GetValue(k)); } // double key UAssert.AreEqual <string>(_DoubleValue, table.GetValue(_Double)); table.RawSetValue(_Double, 12); UAssert.AreEqual <double>(12.0, table.GetValue(_Double)); Assert.AreEqual(LuaType.Nil, table.GetValue(_EmptyDouble).Type); table.RawSetValue(_EmptyDouble, 12); UAssert.AreEqual <double>(12.0, table.GetValue(_EmptyDouble)); } }
[TestMethod] public void SetValue() { using (var lua = NewTest()) using (var table = (LuaTable)lua.DoString("return newTestTable(false, true)", "@Table.cs.SetValue.lua")[0]) { // - try overwriting values, which the metatable can't intercept - // array for (double i = 1; i <= _ArrayEnd; ++i) { UAssert.AreEqual <double>(i, table.GetValue(i)); table.SetValue(i, 12); UAssert.AreEqual <double>(12.0, table.GetValue(i)); } // associative array for (int i = 0; i < _Keys.Count; ++i) { var k = _Keys[i]; UAssert.AreEqual <double>(i + 1, table.GetValue(k)); table.SetValue(k, 12); UAssert.AreEqual <double>(12.0, table.GetValue(k)); } // double key UAssert.AreEqual <string>(_DoubleValue, table.GetValue(_Double)); table.SetValue(_Double, 12); UAssert.AreEqual <double>(12.0, table.GetValue(_Double)); // - try adding values, which the metatable will intercept - for (double i = _ArrayEnd + 1; i <= _ArrayEnd * 2; ++i) { Assert.AreEqual(LuaType.Nil, table.GetValue(i).Type); table.SetValue(i, 12); UAssert.AreEqual <string>(_MetaWrite, table.GetValue(i)); } foreach (string k in _EmptyKeys) { Assert.AreEqual(LuaType.Nil, table.GetValue(k).Type); table.SetValue(k, 12); UAssert.AreEqual <string>(_MetaWrite, table.GetValue(k)); } } }
[TestMethod] public void Delegate() { using (var lua = new Lua()) { int a = 0; lua["a"] = new Action(() => ++ a); try { lua.DoString("a()"); Assert.Fail("Update this unit test if support for calling delegates directly has been added."); } catch (LuaScriptException ex) { Assert.AreEqual(@"[string ""a()""]:1: attempt to call global 'a' (a userdata value)", ex.Message); } Assert.AreEqual(0, a); lua.DoString("a:Invoke()"); Assert.AreEqual(1, a); int b = 0; lua["b"] = new Action <Func <int, int> >(f => b = f(b)); lua.DoString("b:Invoke(function(current) return current + 1 end)"); Assert.AreEqual(1, b); try { lua.DoString("b:Invoke(function(current) return {} end)"); Assert.Fail("Can't convert table to int."); } catch (LuaScriptException ex_outer) { UAssert.IsInstanceOf <NullReferenceException>(ex_outer.InnerException); var ex = (NullReferenceException)ex_outer.InnerException; Assert.AreEqual("LuaInterface_generatedcode", ex.Source); Assert.AreEqual("LuaGeneratedClass", ex.TargetSite.DeclaringType.FullName.Substring(0, "LuaGeneratedClass".Length)); Assert.AreEqual("Int32 CallFunction(Int32)", ex.TargetSite.ToString()); // todo: improve generated code to throw a proper exception and update this test } } }
[TestMethod] public void Reflection() { using (var lua = new Lua()) { // with access to the object returned by GetType() it is possible to use MethodInfo.Invoke on arbitrary methods // therefore, SecureLuaFunctions blacklists all types in the System.Reflection namespace // blacklisted types are converted to strings (ToString) and the string is pushed instead. lua["object"] = new object(); lua.DoString(@"t = object:GetType()"); string[] expressions = { "t.Assembly", "t.Module", "t:GetMethod('ToString')", "t:GetConstructors()", // this evaluates to the string "System.Reflection.ConstructorInfo[]" "t:GetMethod('ReferenceEquals')", // note that ReferenceEquals is a static method }; foreach (var expr in expressions) { var result = lua.Eval(expr); UAssert.IsInstanceOf <string>(result, expr); } } }