aboutsummaryrefslogtreecommitdiffstats
path: root/lib/LuaBridge/Tests/Source/ClassTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/LuaBridge/Tests/Source/ClassTests.cpp')
-rw-r--r--lib/LuaBridge/Tests/Source/ClassTests.cpp1665
1 files changed, 0 insertions, 1665 deletions
diff --git a/lib/LuaBridge/Tests/Source/ClassTests.cpp b/lib/LuaBridge/Tests/Source/ClassTests.cpp
deleted file mode 100644
index ab789f4..0000000
--- a/lib/LuaBridge/Tests/Source/ClassTests.cpp
+++ /dev/null
@@ -1,1665 +0,0 @@
-// https://github.com/vinniefalco/LuaBridge
-//
-// Copyright 2019, Dmitry Tarakanov
-// SPDX-License-Identifier: MIT
-
-#include "TestBase.h"
-
-#include <exception>
-#include <map>
-#include <memory>
-
-struct ClassTests : TestBase
-{
- template <class T>
- T variable (const std::string& name)
- {
- runLua ("result = " + name);
- return result <T> ();
- }
-};
-
-namespace {
-
-struct EmptyBase
-{
-};
-
-template <class T, class Base>
-struct Class : Base
-{
- Class ()
- : data ()
- {
- }
-
- Class (T data)
- : data (data)
- {
- }
-
- static Class <T, Base> staticFunction (Class <T, Base> value)
- {
- return value;
- }
-
- std::string toString () const
- {
- std::ostringstream stream;
- stream << data;
- return stream.str ();
- }
-
- bool operator== (const Class <T, Base>& rhs) const
- {
- return data == rhs.data;
- }
-
- bool operator< (const Class <T, Base>& rhs) const
- {
- return data < rhs.data;
- }
-
- bool operator<= (const Class <T, Base>& rhs) const
- {
- return data <= rhs.data;
- }
-
- Class <T, Base> operator+ (const Class <T, Base>& rhs) const
- {
- return Class <T, Base> (data + rhs.data);
- }
-
- Class <T, Base> operator- (const Class <T, Base>& rhs) const
- {
- return Class <T, Base> (data - rhs.data);
- }
-
- Class <T, Base> operator* (const Class <T, Base>& rhs) const
- {
- return Class <T, Base> (data * rhs.data);
- }
-
- Class <T, Base> operator/ (const Class <T, Base>& rhs) const
- {
- return Class <T, Base> (data / rhs.data);
- }
-
- Class <T, Base> operator% (const Class <T, Base>& rhs) const
- {
- return Class <T, Base> (data % rhs.data);
- }
-
- Class <T, Base> operator() (T param)
- {
- return Class <T, Base> (param);
- }
-
- int len () const
- {
- return data;
- }
-
- Class <T, Base> negate () const
- {
- return Class <T, Base> (-data);
- }
-
- T method (T value)
- {
- return value;
- }
-
- T methodState (T value, lua_State*)
- {
- return value;
- }
-
- T constMethod (T value) const
- {
- return value;
- }
-
- T getData () const
- {
- return data;
- }
-
- void setData (T data)
- {
- this->data = data;
- }
-
- T getDataState (lua_State*) const
- {
- return data;
- }
-
- void setDataState (T data, lua_State*)
- {
- this->data = data;
- }
-
- mutable T data;
- static T staticData;
-};
-
-template <class T, class Base>
-T Class <T, Base>::staticData = {};
-
-} // namespace
-
-TEST_F (ClassTests, PassingUnregisteredClassToLuaThrows)
-{
- using Unregistered = Class <int, EmptyBase>;
-
- runLua ("function process_fn (value) end");
-
- auto process_fn = luabridge::getGlobal (L, "process_fn");
- ASSERT_TRUE (process_fn.isFunction ());
-
- Unregistered value (1);
- const Unregistered constValue (2);
- ASSERT_THROW (process_fn (value), std::exception);
- ASSERT_THROW (process_fn (constValue), std::exception);
- ASSERT_THROW (process_fn (&value), std::exception);
- ASSERT_THROW (process_fn (&constValue), std::exception);
-}
-
-TEST_F (ClassTests, PassWrongClassFromLuaThrows)
-{
- using Right = Class <int, EmptyBase>;
- using WrongBase = Class <float, EmptyBase>;
- using Wrong = Class <int, WrongBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Right> ("Right")
- .endClass ()
- .beginClass <WrongBase> ("WrongBase")
- .endClass ()
- .beginClass <Wrong> ("Wrong")
- .addConstructor <void (*) (int)> ()
- .endClass ()
- .addFunction ("processRight", &Right::staticFunction);
-
- // bad argument #1 to 'processRight' (Right expected, got Wrong)
- ASSERT_THROW (runLua ("result = processRight (Wrong (5))"), std::exception);
- ASSERT_TRUE (result ().isNil ());
-}
-
-TEST_F (ClassTests, PassDerivedClassInsteadOfBase)
-{
- using Base = Class <int, EmptyBase>;
- using Derived = Class <float, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addConstructor <void (*) (float)> ()
- .endClass ()
- .addFunction ("processBase", &Base::staticFunction);
-
- runLua ("result = processBase (Derived (3.14))");
- ASSERT_EQ (0, result <Base> ().data);
-}
-
-namespace {
-
-template <class T, class Base>
-T processNonConst (Class <T, Base>* object)
-{
- return object->data;
-}
-
-} // namespace
-
-TEST_F (ClassTests, PassConstClassInsteadOfNonConstThrows)
-{
- using Base = Class <int, EmptyBase>;
- using Derived = Class <float, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ()
- .addFunction ("processNonConst", &processNonConst <float, Base>);
-
- const Derived constObject (1.2f);
- luabridge::setGlobal (L, &constObject, "constObject");
-
- // bad argument #1 to 'processNonConst' (Derived expected, got const Derived)
- ASSERT_THROW (runLua ("result = processNonConst (constObject)"), std::exception);
- ASSERT_TRUE (result ().isNil ());
-}
-
-TEST_F (ClassTests, PassOtherTypeInsteadOfNonConstThrows)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> () // Show that it does't matter
- .endClass ()
- .addFunction ("processNonConst", &processNonConst <int, EmptyBase>);
-
- // bad argument #1 to 'processNonConst' (Int expected, got number)
- ASSERT_THROW (runLua ("result = processNonConst (1)"), std::exception);
- ASSERT_TRUE (result ().isNil ());
-}
-
-TEST_F (ClassTests, PassRegisteredClassInsteadOfUnregisteredThrows)
-{
- using Int = Class <int, EmptyBase>;
- using Float = Class <float, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Float> ("Float")
- .addConstructor <void (*) (float)> ()
- .endClass ()
- .addFunction ("processUnregisteredInt", &Int::staticFunction);
-
- // bad argument #1 to 'processUnregisteredInt' (unregistered class expected, got Float)
- ASSERT_THROW (runLua ("result = processUnregisteredInt (Float (1.2))"), std::exception);
- ASSERT_TRUE (result ().isNil ());
-}
-
-namespace {
-
-Class <int, EmptyBase>& returnRef ()
-{
- static Class <int, EmptyBase> value (1);
- return value;
-}
-
-const Class <int, EmptyBase>& returnConstRef ()
-{
- return returnRef ();
-}
-
-Class <int, EmptyBase>* returnPtr ()
-{
- return &returnRef ();
-}
-
-const Class <int, EmptyBase>* returnConstPtr ()
-{
- return &returnConstRef ();
-}
-
-Class <int, EmptyBase> returnValue ()
-{
- return Class <int, EmptyBase> (2);
-}
-
-void addHelperFunctions (lua_State* L)
-{
- luabridge::getGlobalNamespace (L)
- .addFunction ("returnRef", &returnRef)
- .addFunction ("returnConstRef", &returnConstRef)
- .addFunction ("returnPtr", &returnPtr)
- .addFunction ("returnConstPtr", &returnConstPtr)
- .addFunction ("returnValue", &returnValue);
-}
-
-} // namespace
-
-TEST_F (ClassTests, PassingUnregisteredClassFromLuaThrows)
-{
- using Unregistered = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .addFunction ("returnRef", &returnRef)
- .addFunction ("returnConstRef", &returnConstRef)
- .addFunction ("returnPtr", &returnPtr)
- .addFunction ("returnConstPtr", &returnConstPtr)
- .addFunction ("returnValue", &returnValue);
-
- ASSERT_THROW (runLua ("result = returnRef ()"), std::exception);
- ASSERT_THROW (runLua ("result = returnConstRef ()"), std::exception);
- ASSERT_THROW (runLua ("result = returnPtr ()"), std::exception);
- ASSERT_THROW (runLua ("result = returnConstPtr ()"), std::exception);
- ASSERT_THROW (runLua ("result = returnValue ()"), std::exception);
-}
-
-TEST_F (ClassTests, DeriveFromUnregisteredClassThrows)
-{
- using Base = Class <int, EmptyBase>;
- using Derived = Class <float, Base>;
-
- ASSERT_THROW (
- (luabridge::getGlobalNamespace (L).deriveClass <Derived, Base> ("Derived")),
- std::exception);
-
- ASSERT_EQ (1, lua_gettop (L));
-}
-
-struct ClassFunctions : ClassTests
-{
-};
-
-TEST_F (ClassFunctions, MemberFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", &Int::method)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-}
-
-TEST_F (ClassFunctions, MemberFunctions_PassState)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", &Int::methodState)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-}
-
-TEST_F (ClassFunctions, ConstMemberFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("constMethod", &Int::constMethod)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():constMethod (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ():constMethod (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua ("result = returnPtr ():constMethod (3)");
- ASSERT_EQ (3, result <int> ());
-
- runLua ("result = returnConstPtr ():constMethod (4)");
- ASSERT_EQ (4, result <int> ());
-
- runLua ("result = returnValue ():constMethod (5)");
- ASSERT_EQ (5, result <int> ());
-}
-
-#ifdef LUABRIDGE_CXX11
-
-namespace {
-
-template <class T, class Base>
-T proxyFunction (Class <T, Base>* object, T value)
-{
- object->data = value;
- return value;
-}
-
-template <class T, class Base>
-T proxyFunctionState (Class <T, Base>* object, T value, lua_State*)
-{
- object->data = value;
- return value;
-}
-
-template <class T, class Base>
-T proxyConstFunction (const Class <T, Base>* object, T value)
-{
- return value;
-}
-
-} // namespace
-
-TEST_F (ClassFunctions, ProxyFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", &proxyFunction <int, EmptyBase>)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-}
-
-TEST_F (ClassFunctions, ProxyFunctions_PassState)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", &proxyFunctionState <int, EmptyBase>)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-}
-
-TEST_F (ClassFunctions, ConstProxyFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("constMethod", &proxyConstFunction <int, EmptyBase>)
- .endClass ();
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():constMethod (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ():constMethod (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua ("result = returnPtr ():constMethod (3)");
- ASSERT_EQ (3, result <int> ());
-
- runLua ("result = returnConstPtr ():constMethod (4)");
- ASSERT_EQ (4, result <int> ());
-
- runLua ("result = returnValue ():constMethod (5)");
- ASSERT_EQ (5, result <int> ());
-}
-
-TEST_F (ClassFunctions, StdFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- auto sharedData = std::make_shared <int> ();
- std::weak_ptr <int> data = sharedData; // Check __gc meta-method
-
- std::function <int (Int*, int)> function = [sharedData] (Int* object, int value)
- {
- object->data = value;
- return value;
- };
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", std::move(function))
- .endClass ();
-
- sharedData = nullptr;
- ASSERT_FALSE (data.expired ());
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-
- runLua ("result = nil");
- lua_close (L); // Force garbage collection
- L = nullptr;
-
- ASSERT_TRUE (data.expired());
-}
-
-TEST_F (ClassFunctions, StdFunctions_PassState)
-{
- using Int = Class <int, EmptyBase>;
-
- auto sharedData = std::make_shared <int> ();
- std::weak_ptr <int> data = sharedData; // Check __gc meta-method
-
- std::function <int (Int*, int, lua_State*)> function = [sharedData] (Int* object, int value, lua_State*)
- {
- object->data = value;
- return value;
- };
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("method", std::move(function))
- .endClass ();
-
- sharedData = nullptr;
- ASSERT_FALSE (data.expired ());
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():method (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnPtr ():method (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua("result = returnConstPtr ().method"); // Don't call, just get
- ASSERT_TRUE (result ().isNil ());
-
- runLua ("result = returnValue ():method (3)");
- ASSERT_EQ (3, result <int> ());
-
- runLua ("result = nil");
- lua_close (L); // Force garbage collection
- L = nullptr;
-
- ASSERT_TRUE (data.expired());
-}
-
-TEST_F (ClassFunctions, ConstStdFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- auto sharedData = std::make_shared <int> ();
- std::weak_ptr <int> data = sharedData; // Check __gc meta-method
-
- std::function <int (const Int*, int)> function = [sharedData] (const Int* object, int value)
- {
- object->data = value;
- return value;
- };
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("constMethod", std::move(function))
- .endClass ();
-
- sharedData = nullptr;
- ASSERT_FALSE (data.expired ());
-
- addHelperFunctions (L);
-
- runLua ("result = returnRef ():constMethod (1)");
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = returnConstRef ():constMethod (2)");
- ASSERT_EQ (2, result <int> ());
-
- runLua ("result = returnPtr ():constMethod (3)");
- ASSERT_EQ (3, result <int> ());
-
- runLua ("result = returnConstPtr ():constMethod (4)");
- ASSERT_EQ (4, result <int> ());
-
- runLua ("result = returnValue ():constMethod (5)");
- ASSERT_EQ (5, result <int> ());
-
- runLua ("result = nil");
- lua_close (L); // Force garbage collection
- L = nullptr;
-
- ASSERT_TRUE (data.expired());
-}
-
-#endif // LUABRIDGE_CXX11
-
-struct ClassProperties : ClassTests
-{
-};
-
-TEST_F (ClassProperties, FieldPointers)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &Int::data, true)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = 2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (2, result () ["data"].cast <int> ());
-
- runLua ("result = Int (42).data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (42, result <int> ());
-}
-
-TEST_F (ClassProperties, FieldPointers_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &Int::data, false)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- ASSERT_THROW (runLua ("result.data = 2"), std::exception);
-
- runLua ("result = Int (42).data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (42, result <int> ());
-}
-
-TEST_F (ClassProperties, MemberFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &Int::getData, &Int::setData)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = -2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (-2, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, MemberFunctions_PassState)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &Int::getDataState, &Int::setDataState)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = -2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (-2, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, MemberFunctions_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &Int::getData)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- ASSERT_THROW (runLua ("result.data = -2"), std::exception);
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, MemberFunctions_Derived)
-{
- using Base = Class <std::string, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty ("data", &Base::getData, &Base::setData)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ();
-
- Derived derived (12);
- derived.Base::data = "abc";
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isString ());
- ASSERT_EQ ("abc", result <std::string> ());
-
- runLua ("derived.data = 5"); // Lua just casts integer to string
- ASSERT_EQ ("5", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-
- runLua ("derived.data = '123'");
- ASSERT_EQ ("123", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-}
-
-TEST_F (ClassProperties, MemberFunctions_Overridden)
-{
- using Base = Class <float, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty ("data", &Base::getData, &Base::setData)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addProperty ("data", &Derived::getData, &Derived::setData)
- .endClass ();
-
- Derived derived (50);
- derived.Base::data = 1.23f;
- luabridge::setGlobal (L, static_cast <Base*> (&derived), "base");
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = base.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1.23f, result <float> ());
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (50, result <int> ());
-
- runLua ("base.data = -3.14");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (50, derived.data);
-
- runLua ("derived.data = 7");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (7, derived.data);
-}
-
-namespace {
-
-template <class T, class BaseClass>
-T getData (const Class <T, BaseClass>* object)
-{
- return object->data;
-}
-
-template <class T, class BaseClass>
-void setData (Class <T, BaseClass>* object, T data)
-{
- object->data = data;
-}
-
-} // namespace
-
-TEST_F (ClassProperties, ProxyFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &getData <int, EmptyBase>, &setData <int, EmptyBase>)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = -2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (-2, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, ProxyFunctions_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &getData <int, EmptyBase>)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- ASSERT_THROW (runLua ("result.data = -2"), std::exception);
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, ProxyFunctions_Derived)
-{
- using Base = Class <std::string, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty ("data", &getData <std::string, EmptyBase>, &setData <std::string, EmptyBase>)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ();
-
- Derived derived (12);
- derived.Base::data = "abc";
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isString ());
- ASSERT_EQ ("abc", result <std::string> ());
-
- runLua ("derived.data = 5"); // Lua just casts integer to string
- ASSERT_EQ ("5", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-
- runLua ("derived.data = '123'");
- ASSERT_EQ ("123", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-}
-
-TEST_F (ClassProperties, ProxyFunctions_Overridden)
-{
- using Base = Class <float, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty("data", &getData <float, EmptyBase>, &setData <float, EmptyBase>)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addProperty ("data", &getData <int, Base>, &setData <int, Base>)
- .endClass ();
-
- Derived derived (50);
- derived.Base::data = 1.23f;
- luabridge::setGlobal (L, static_cast <Base*> (&derived), "base");
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = base.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1.23f, result <float> ());
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (50, result <int> ());
-
- runLua ("base.data = -3.14");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (50, derived.data);
-
- runLua ("derived.data = 7");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (7, derived.data);
-}
-
-namespace {
-
-template <class T, class BaseClass>
-int getDataC (lua_State* L)
-{
- auto objectRef = luabridge::LuaRef::fromStack (L, 1);
- auto* object = objectRef.cast <const Class <T, BaseClass>*> ();
- luabridge::Stack <T>::push (L, object->data);
- return 1;
-}
-
-template <class T, class BaseClass>
-int setDataC (lua_State* L)
-{
- auto objectRef = luabridge::LuaRef::fromStack (L, 1);
- auto* object = objectRef.cast <const Class <T, BaseClass>*>();
- auto valueRef = luabridge::LuaRef::fromStack (L, 2);
- T value = valueRef.cast <T> ();
- object->data = value;
- return 0;
-}
-
-} // namespace
-
-TEST_F (ClassProperties, ProxyCFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &getDataC <int, EmptyBase>, &setDataC <int, EmptyBase>)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = -2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (-2, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, ProxyCFunctions_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", &getDataC <int, EmptyBase>)
- .endClass ();
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- ASSERT_THROW (runLua ("result.data = -2"), std::exception);
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-}
-
-TEST_F (ClassProperties, ProxyCFunctions_Derived)
-{
- using Base = Class <std::string, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty ("data", &getDataC <std::string, EmptyBase>, &setDataC <std::string, EmptyBase>)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ();
-
- Derived derived (12);
- derived.Base::data = "abc";
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isString ());
- ASSERT_EQ ("abc", result <std::string> ());
-
- runLua ("derived.data = 5"); // Lua just casts integer to string
- ASSERT_EQ ("5", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-
- runLua ("derived.data = '123'");
- ASSERT_EQ ("123", derived.Base::data);
- ASSERT_EQ (12, derived.data);
-}
-
-TEST_F (ClassProperties, ProxyCFunctions_Overridden)
-{
- using Base = Class <float, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addProperty ("data", &getDataC <float, EmptyBase>, &setDataC <float, EmptyBase>)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addProperty ("data", &getData <int, Base>, &setData <int, Base>)
- .endClass ();
-
- Derived derived (50);
- derived.Base::data = 1.23f;
- luabridge::setGlobal (L, static_cast <Base*> (&derived), "base");
- luabridge::setGlobal (L, &derived, "derived");
-
- runLua ("result = base.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1.23f, result <float> ());
-
- runLua ("result = derived.data");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (50, result <int> ());
-
- runLua ("base.data = -3.14");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (50, derived.data);
-
- runLua ("derived.data = 7");
- ASSERT_EQ (-3.14f, derived.Base::data);
- ASSERT_EQ (7, derived.data);
-}
-
-#ifdef LUABRIDGE_CXX11
-
-TEST_F (ClassProperties, StdFunctions)
-{
- using Int = Class <int, EmptyBase>;
-
- auto sharedGetterData = std::make_shared <int> ();
- std::weak_ptr <int> getterData = sharedGetterData; // Check __gc meta-method
-
- auto sharedSetterData = std::make_shared <int> ();
- std::weak_ptr <int> setterData = sharedGetterData; // Check __gc meta-method
-
- std::function <int (const Int*)> getter = [sharedGetterData] (const Int* object)
- {
- return object->data;
- };
-
- std::function <void (Int*, int)> setter = [sharedSetterData] (Int* object, int value)
- {
- object->data = value;
- };
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", std::move (getter), std::move (setter))
- .endClass ();
-
- sharedGetterData = nullptr;
- ASSERT_FALSE (getterData.expired ());
-
- sharedSetterData = nullptr;
- ASSERT_FALSE (setterData.expired());
-
- runLua ("result = Int (501)");
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result.data = -2");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (-2, result () ["data"].cast <int> ());
-
- runLua ("result = nil");
- lua_close (L); // Force garbage collection
- L = nullptr;
-
- ASSERT_TRUE (getterData.expired ());
- ASSERT_TRUE (setterData.expired ());
-}
-
-TEST_F (ClassProperties, StdFunctions_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- auto sharedGetterData = std::make_shared <int> ();
- std::weak_ptr <int> getterData = sharedGetterData; // Check __gc meta-method
-
- std::function <int (const Int*)> getter = [sharedGetterData] (const Int* object)
- {
- return object->data;
- };
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addProperty ("data", std::move (getter))
- .endClass ();
-
- sharedGetterData = nullptr;
- ASSERT_FALSE (getterData.expired ());
-
- runLua ("result = Int (501)");
- ASSERT_TRUE (result () ["data"].isNumber ());
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- ASSERT_THROW (runLua ("result.data = -2"), std::exception);
- ASSERT_EQ (501, result () ["data"].cast <int> ());
-
- runLua ("result = nil");
- lua_close (L); // Force garbage collection
- L = nullptr;
-
- ASSERT_TRUE (getterData.expired ());
-}
-
-#endif // LUABRIDGE_CXX11
-
-struct ClassStaticFunctions : ClassTests
-{
-};
-
-TEST_F (ClassStaticFunctions, Functions)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addStaticFunction ("static", &Int::staticFunction)
- .endClass ();
-
- runLua ("result = Int.static (Int (35))");
- ASSERT_EQ (35, result <Int> ().data);
-}
-
-TEST_F (ClassStaticFunctions, Functions_Derived)
-{
- using Base = Class <std::string, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addConstructor <void (*) (std::string)> ()
- .addStaticFunction ("static", &Base::staticFunction)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ();
-
- runLua ("result = Derived.static (Base ('abc'))");
- ASSERT_EQ ("abc", result <Base> ().data);
-}
-
-TEST_F (ClassStaticFunctions, Functions_Overridden)
-{
- using Base = Class <std::string, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addConstructor <void (*) (std::string)> ()
- .addStaticFunction ("staticFunction", &Base::staticFunction)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addConstructor <void (*) (int)> ()
- .addStaticFunction ("staticFunction", &Derived::staticFunction)
- .endClass ();
-
- runLua ("result = Base.staticFunction (Base ('abc'))");
- ASSERT_EQ ("abc", result <Base> ().data);
-
- runLua ("result = Derived.staticFunction (Derived (123))");
- ASSERT_EQ (123, result <Derived> ().data);
-}
-
-struct ClassStaticProperties : ClassTests
-{
-};
-
-TEST_F (ClassStaticProperties, FieldPointers)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addStaticProperty ("staticData", &Int::staticData, true)
- .endClass ();
-
- Int::staticData = 10;
-
- runLua ("result = Int.staticData");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (10, result <int> ());
-
- runLua ("Int.staticData = 20");
- ASSERT_EQ (20, Int::staticData);
-}
-
-TEST_F (ClassStaticProperties, FieldPointers_ReadOnly)
-{
- using Int = Class <int, EmptyBase>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addStaticProperty ("staticData", &Int::staticData, false)
- .endClass ();
-
- Int::staticData = 10;
-
- runLua ("result = Int.staticData");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (10, result <int> ());
-
- ASSERT_THROW (runLua ("Int.staticData = 20"), std::exception);
- ASSERT_EQ (10, Int::staticData);
-}
-
-TEST_F (ClassStaticProperties, FieldPointers_Derived)
-{
- using Base = Class <float, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addStaticProperty ("staticData", &Base::staticData, true)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .endClass ();
-
- Base::staticData = 1.23f;
- Derived::staticData = 50;
-
- runLua ("result = Derived.staticData");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1.23f, result <float> ());
-
- runLua ("Derived.staticData = -3.14");
- ASSERT_EQ (-3.14f, Base::staticData);
- ASSERT_EQ (50, Derived::staticData);
-}
-
-TEST_F (ClassStaticProperties, FieldPointers_Overridden)
-{
- using Base = Class <float, EmptyBase>;
- using Derived = Class <int, Base>;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Base> ("Base")
- .addStaticProperty ("staticData", &Base::staticData, true)
- .endClass ()
- .deriveClass <Derived, Base> ("Derived")
- .addStaticProperty ("staticData", &Derived::staticData, true)
- .endClass ();
-
- Base::staticData = 1.23f;
- Derived::staticData = 50;
-
- runLua ("result = Base.staticData");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1.23f, result <float> ());
-
- runLua ("result = Derived.staticData");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (50, result <int> ());
-
- runLua ("Base.staticData = -3.14");
- ASSERT_EQ (-3.14f, Base::staticData);
- ASSERT_EQ (50, Derived::staticData);
-
- runLua ("Derived.staticData = 7");
- ASSERT_EQ (-3.14f, Base::staticData);
- ASSERT_EQ (7, Derived::staticData);
-}
-
-struct ClassMetaMethods : ClassTests
-{
-};
-
-TEST_F (ClassMetaMethods, __call)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__call", &Int::operator())
- .endClass ();
-
- runLua ("result = Int (1) (-1)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (-1, result <Int> ().data);
-
- runLua ("result = Int (2) (5)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (5, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __tostring)
-{
- typedef Class <int, EmptyBase> Int;
- typedef Class <std::string, EmptyBase> StringClass;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__tostring", &Int::toString)
- .endClass ()
- .beginClass <StringClass> ("String")
- .addConstructor <void (*) (std::string)> ()
- .addFunction ("__tostring", &StringClass::toString)
- .endClass ();
-
- runLua ("result = tostring (Int (-123))");
- ASSERT_EQ ("-123", result <std::string> ());
-
-#if LUA_VERSION_NUM >= 502
- // Lua 5.1 string.format doesn't use __tostring
- runLua ("result = string.format ('%s%s', String ('abc'), Int (-123))");
- ASSERT_EQ ("abc-123", result <std::string> ());
-#endif
-}
-
-TEST_F (ClassMetaMethods, __eq)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__eq", &Int::operator==)
- .endClass ();
-
- runLua ("result = Int (1) == Int (1)");
- ASSERT_EQ (true, result <bool> ());
-
- runLua ("result = Int (1) ~= Int (1)");
- ASSERT_EQ (false, result <bool> ());
-
- runLua ("result = Int (1) == Int (2)");
- ASSERT_EQ (false, result <bool> ());
-
- runLua ("result = Int (1) ~= Int (2)");
- ASSERT_EQ (true, result <bool> ());
-}
-
-TEST_F (ClassMetaMethods, __lt)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__lt", &Int::operator<)
- .endClass ();
-
- runLua ("result = Int (1) < Int (1)");
- ASSERT_EQ (false, result <bool> ());
-
- runLua ("result = Int (1) < Int (2)");
- ASSERT_EQ (true, result <bool> ());
-
- runLua ("result = Int (2) < Int (1)");
- ASSERT_EQ (false, result <bool> ());
-}
-
-TEST_F (ClassMetaMethods, __le)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__le", &Int::operator<=)
- .endClass ();
-
- runLua ("result = Int (1) <= Int (1)");
- ASSERT_EQ (true, result <bool> ());
-
- runLua ("result = Int (1) <= Int (2)");
- ASSERT_EQ (true, result <bool> ());
-
- runLua ("result = Int (2) <= Int (1)");
- ASSERT_EQ (false, result <bool> ());
-}
-
-TEST_F (ClassMetaMethods, __add)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__add", &Int::operator+)
- .endClass ();
-
- runLua ("result = Int (1) + Int (2)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (3, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __sub)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__sub", &Int::operator-)
- .endClass ();
-
- runLua ("result = Int (1) - Int (2)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (-1, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __mul)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__mul", &Int::operator*)
- .endClass ();
-
- runLua ("result = Int (-2) * Int (-5)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (10, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __div)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__div", &Int::operator/)
- .endClass ();
-
- runLua ("result = Int (10) / Int (2)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (5, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __mod)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__mod", &Int::operator%)
- .endClass ();
-
- runLua ("result = Int (7) % Int (2)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (1, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __pow)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__pow", &Int::operator-)
- .endClass ();
-
- runLua ("result = Int (5) ^ Int (2)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (3, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __unm)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__unm", &Int::negate)
- .endClass ();
-
- runLua ("result = -Int (-3)");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ (3, result <Int> ().data);
-}
-
-TEST_F (ClassMetaMethods, __concat)
-{
- typedef Class <std::string, EmptyBase> String;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <String> ("String")
- .addConstructor <void (*) (std::string)> ()
- .addFunction ("__concat", &String::operator+)
- .endClass ();
-
- ASSERT_THROW (runLua ("result = String ('a') + String ('b')"), std::exception);
-
- runLua ("result = String ('ab') .. String ('cd')");
- ASSERT_TRUE (result ().isUserdata ());
- ASSERT_EQ ("abcd", result <String> ().data);
-}
-
-TEST_F (ClassMetaMethods, __len)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addConstructor <void (*) (int)> ()
- .addFunction ("__len", &Int::len)
- .endClass ();
-
- runLua ("result = #Int (1)");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = #Int (5)");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (5, result <int> ());
-}
-
-namespace {
-
-struct Table
-{
- int index (const std::string& key)
- {
- return map.at (key);
- }
-
- void newIndex (const std::string& key, int value)
- {
- map.emplace (key, value);
- }
-
- std::map <std::string, int> map;
-};
-
-} // namespace
-
-TEST_F (ClassMetaMethods, __index)
-{
- luabridge::getGlobalNamespace (L)
- .beginClass <Table> ("Table")
- .addFunction ("__index", &Table::index)
- .endClass ();
-
- Table t {{{"a", 1}, {"b", 2}}};
-
- luabridge::setGlobal (L, &t, "t");
-
- runLua ("result = t.a");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (1, result <int> ());
-
- runLua ("result = t.b");
- ASSERT_TRUE (result ().isNumber ());
- ASSERT_EQ (2, result <int> ());
-
- ASSERT_THROW (runLua ("result = t.c"), std::exception); // at ("c") throws
-}
-
-TEST_F (ClassMetaMethods, __newindex)
-{
- typedef Class <int, EmptyBase> Int;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Table> ("Table")
- .addFunction ("__newindex", &Table::newIndex)
- .endClass ();
-
- Table t;
-
- luabridge::setGlobal (L, &t, "t");
-
- runLua ("t.a = 1\n"
- "t ['b'] = 2");
-
- ASSERT_EQ ((std::map <std::string, int> {{"a", 1}, {"b", 2}}), t.map);
-}
-
-TEST_F (ClassMetaMethods, __gcForbidden)
-{
- typedef Class <int, EmptyBase> Int;
-
- ASSERT_THROW (
- luabridge::getGlobalNamespace (L)
- .beginClass <Int> ("Int")
- .addFunction ("__gc", &Int::method)
- .endClass (),
- std::exception);
-}
-
-TEST_F (ClassTests, EnclosedClassProperties)
-{
- typedef Class <int, EmptyBase> Inner;
- typedef Class <Inner, EmptyBase> Outer;
-
- luabridge::getGlobalNamespace (L)
- .beginClass <Inner> ("Inner")
- .addProperty ("data", &Inner::data)
- .endClass ()
- .beginClass <Outer> ("Outer")
- .addProperty ("data", &Outer::data)
- .endClass ();
-
- Outer outer (Inner (0));
- luabridge::setGlobal (L, &outer, "outer");
-
- outer.data.data = 1;
- runLua ("outer.data.data = 10");
- ASSERT_EQ (10, outer.data.data);
-
- runLua ("result = outer.data.data");
- ASSERT_EQ (10, result <int> ());
-}