?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. // https://github.com/vinniefalco/LuaBridge
  2. // Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
  3. // Copyright 2007, Nathan Reed
  4. // SPDX-License-Identifier: MIT
  5.  
  6. // A set of tests of different types' communication with Lua
  7.  
  8. #include "TestBase.h"
  9.  
  10. #include "LuaBridge/RefCountedPtr.h"
  11.  
  12. #include <cstring>
  13. #include <iostream>
  14. #include <memory>
  15. #include <string>
  16.  
  17. namespace LuaBridgeTests {
  18.  
  19. using namespace std;
  20. using namespace luabridge;
  21.  
  22. //==============================================================================
  23.  
  24. /*
  25.  * Test classes
  26.  */
  27.  
  28. bool g_success = true;
  29.  
  30. bool testSucceeded()
  31. {
  32.     bool b = g_success;
  33.     g_success = false;
  34.     return b;
  35. }
  36.  
  37. typedef int fn_type;
  38. enum
  39. {
  40.     FN_CTOR,
  41.     FN_DTOR,
  42.     FN_STATIC,
  43.     FN_VIRTUAL,
  44.     FN_PROPGET,
  45.     FN_PROPSET,
  46.     FN_STATIC_PROPGET,
  47.     FN_STATIC_PROPSET,
  48.     FN_OPERATOR,
  49.     NUM_FN_TYPES
  50. };
  51.  
  52. struct fn_called
  53. {
  54.     bool called[NUM_FN_TYPES];
  55.     fn_called() { memset(called, 0, NUM_FN_TYPES * sizeof(bool)); }
  56. };
  57.  
  58. fn_called A_functions, B_functions;
  59.  
  60. bool testAFnCalled(fn_type f)
  61. {
  62.     bool b = A_functions.called[f];
  63.     A_functions.called[f] = false;
  64.     return b;
  65. }
  66.  
  67. bool testBFnCalled(fn_type f)
  68. {
  69.     bool b = B_functions.called[f];
  70.     B_functions.called[f] = false;
  71.     return b;
  72. }
  73.  
  74. class A
  75. {
  76. protected:
  77.     string name;
  78.     mutable bool success;
  79.  
  80. public:
  81.     A(string const& name_) : name(name_), success(false), testProp(47)
  82.     {
  83.         A_functions.called[FN_CTOR] = true;
  84.     }
  85.     virtual ~A() { A_functions.called[FN_DTOR] = true; }
  86.  
  87.     virtual void testVirtual() { A_functions.called[FN_VIRTUAL] = true; }
  88.  
  89.     const char* getName() const { return name.c_str(); }
  90.  
  91.     void setSuccess() const { success = true; }
  92.  
  93.     bool testSucceeded() const
  94.     {
  95.         bool b = success;
  96.         success = false;
  97.         return b;
  98.     }
  99.  
  100.     static void testStatic() { A_functions.called[FN_STATIC] = true; }
  101.  
  102.     int testProp;
  103.     int testPropGet() const
  104.     {
  105.         A_functions.called[FN_PROPGET] = true;
  106.         return testProp;
  107.     }
  108.     void testPropSet(int x)
  109.     {
  110.         A_functions.called[FN_PROPSET] = true;
  111.         testProp = x;
  112.     }
  113.  
  114.     static int testStaticProp;
  115.     static int testStaticPropGet()
  116.     {
  117.         A_functions.called[FN_STATIC_PROPGET] = true;
  118.         return testStaticProp;
  119.     }
  120.     static void testStaticPropSet(int x)
  121.     {
  122.         A_functions.called[FN_STATIC_PROPSET] = true;
  123.         testStaticProp = x;
  124.     }
  125.  
  126.     RefCountedPtr<A> operator+(A const& other)
  127.     {
  128.         A_functions.called[FN_OPERATOR] = true;
  129.         return new A(name + " + " + other.name);
  130.     }
  131. };
  132.  
  133. int A::testStaticProp = 47;
  134.  
  135. class B : public A
  136. {
  137. public:
  138.     explicit B(string const& name_) : A(name_) { B_functions.called[FN_CTOR] = true; }
  139.  
  140.     virtual ~B() { B_functions.called[FN_DTOR] = true; }
  141.  
  142.     virtual void testVirtual() { B_functions.called[FN_VIRTUAL] = true; }
  143.  
  144.     static void testStatic2() { B_functions.called[FN_STATIC] = true; }
  145. };
  146.  
  147. /*
  148.  * Test functions
  149.  */
  150.  
  151. int testRetInt()
  152. {
  153.     return 47;
  154. }
  155.  
  156. float testRetFloat()
  157. {
  158.     return 47.0f;
  159. }
  160.  
  161. char const* testRetConstCharPtr()
  162. {
  163.     return "Hello, world";
  164. }
  165.  
  166. string testRetStdString()
  167. {
  168.     static string ret("Hello, world");
  169.     return ret;
  170. }
  171.  
  172. void testParamInt(int a)
  173. {
  174.     g_success = (a == 47);
  175. }
  176.  
  177. void testParamBool(bool b)
  178. {
  179.     g_success = b;
  180. }
  181.  
  182. void testParamFloat(float f)
  183. {
  184.     g_success = (f == 47.0f);
  185. }
  186.  
  187. void testParamConstCharPtr(char const* str)
  188. {
  189.     g_success = !strcmp(str, "Hello, world");
  190. }
  191.  
  192. void testParamStdString(string str)
  193. {
  194.     g_success = !strcmp(str.c_str(), "Hello, world");
  195. }
  196.  
  197. void testParamStdStringRef(const string& str)
  198. {
  199.     g_success = !strcmp(str.c_str(), "Hello, world");
  200. }
  201.  
  202. void testParamAPtr(A* a)
  203. {
  204.     a->setSuccess();
  205. }
  206.  
  207. void testParamAPtrConst(A* const a)
  208. {
  209.     a->setSuccess();
  210. }
  211.  
  212. void testParamConstAPtr(const A* a)
  213. {
  214.     a->setSuccess();
  215. }
  216.  
  217. void testParamSharedPtrA(RefCountedPtr<A> a)
  218. {
  219.     a->setSuccess();
  220. }
  221.  
  222. RefCountedPtr<A> testRetSharedPtrA()
  223. {
  224.     /*static*/ RefCountedPtr<A> sp_A(new A("from C"));
  225.     return sp_A;
  226. }
  227.  
  228. RefCountedPtr<A const> testRetSharedPtrConstA()
  229. {
  230.     /*static*/ RefCountedPtr<A> sp_A(new A("const A"));
  231.     return sp_A;
  232. }
  233.  
  234. // add our own functions and classes to a Lua environment
  235. void addToState(lua_State* L)
  236. {
  237.     getGlobalNamespace(L)
  238.         .addFunction("testSucceeded", &testSucceeded)
  239.         .addFunction("testAFnCalled", &testAFnCalled)
  240.         .addFunction("testBFnCalled", &testBFnCalled)
  241.         .addFunction("testRetInt", &testRetInt)
  242.         .addFunction("testRetFloat", &testRetFloat)
  243.         .addFunction("testRetConstCharPtr", &testRetConstCharPtr)
  244.         .addFunction("testRetStdString", &testRetStdString)
  245.         .addFunction("testParamInt", &testParamInt)
  246.         .addFunction("testParamBool", &testParamBool)
  247.         .addFunction("testParamFloat", &testParamFloat)
  248.         .addFunction("testParamConstCharPtr", &testParamConstCharPtr)
  249.         .addFunction("testParamStdString", &testParamStdString)
  250.         .addFunction("testParamStdStringRef", &testParamStdStringRef)
  251.         .beginClass<A>("A")
  252.         .addConstructor<void (*)(const string&), RefCountedPtr<A>>()
  253.         .addFunction("testVirtual", &A::testVirtual)
  254.         .addFunction("getName", &A::getName)
  255.         .addFunction("testSucceeded", &A::testSucceeded)
  256.         .addFunction("__add", &A::operator+)
  257.         .addData("testProp", &A::testProp)
  258.         .addProperty("testProp2", &A::testPropGet, &A::testPropSet)
  259.         .addStaticFunction("testStatic", &A::testStatic)
  260.         .addStaticData("testStaticProp", &A::testStaticProp)
  261.         .addStaticProperty("testStaticProp2", &A::testStaticPropGet, &A::testStaticPropSet)
  262.         .endClass()
  263.         .deriveClass<B, A>("B")
  264.         .addConstructor<void (*)(const string&), RefCountedPtr<B>>()
  265.         .addStaticFunction("testStatic2", &B::testStatic2)
  266.         .endClass()
  267.         .addFunction("testParamAPtr", &testParamAPtr)
  268.         .addFunction("testParamAPtrConst", &testParamAPtrConst)
  269.         .addFunction("testParamConstAPtr", &testParamConstAPtr)
  270.         .addFunction("testParamSharedPtrA", &testParamSharedPtrA)
  271.         .addFunction("testRetSharedPtrA", &testRetSharedPtrA)
  272.         .addFunction("testRetSharedPtrConstA", &testRetSharedPtrConstA);
  273. }
  274.  
  275. void resetTests()
  276. {
  277.     g_success = true;
  278.     A::testStaticProp = 47;
  279. }
  280.  
  281. void printValue(lua_State* L, int index)
  282. {
  283.     int type = lua_type(L, index);
  284.     switch (type)
  285.     {
  286.     case LUA_TBOOLEAN:
  287.         std::cerr << std::boolalpha << (lua_toboolean(L, index) != 0);
  288.         break;
  289.     case LUA_TSTRING:
  290.         std::cerr << lua_tostring(L, index);
  291.         break;
  292.     case LUA_TNUMBER:
  293.         std::cerr << lua_tonumber(L, index);
  294.         break;
  295.     case LUA_TTABLE:
  296.     case LUA_TTHREAD:
  297.     case LUA_TFUNCTION:
  298.         std::cerr << lua_topointer(L, index);
  299.         break;
  300.     }
  301.     std::cerr << ": " << lua_typename(L, type) << " (" << type << ")" << std::endl;
  302. }
  303.  
  304. } // namespace LuaBridgeTests
  305.  
  306. struct LegacyTests : TestBase
  307. {
  308. };
  309.  
  310. const char* const SCRIPT = R"(
  311. -- test lua script to be run with the luabridge test program
  312.  
  313. print('Running LuaBridge tests:');
  314.  
  315. -- enum from C++
  316. FN_CTOR = 0
  317. FN_DTOR = 1
  318. FN_STATIC = 2
  319. FN_VIRTUAL = 3
  320. FN_PROPGET = 4
  321. FN_PROPSET = 5
  322. FN_STATIC_PROPGET = 6
  323. FN_STATIC_PROPSET = 7
  324. FN_OPERATOR = 8
  325. NUM_FN_TYPES = 9
  326.  
  327. -- function to print contents of a table
  328. function printtable (t)
  329.   for k, v in pairs(t) do
  330.     if (type(v) == 'table') then
  331.       print(k .. ' =>', '(table)');
  332.     elseif (type(v) == 'function') then
  333.       print(k .. ' =>', '(function)');
  334.     elseif (type(v) == 'userdata') then
  335.       print(k .. ' =>', '(userdata)');
  336.     else
  337.       print(k .. ' =>', v);
  338.     end
  339.   end
  340. end
  341.  
  342. function assert (expr)
  343.   if (not expr) then error('assert failed', 2) end
  344. end
  345.  
  346. -- test functions registered from C++
  347.  
  348. assert(testSucceeded());
  349. assert(testRetInt() == 47);
  350. assert(testRetFloat() == 47.0);
  351. assert(testRetConstCharPtr() == 'Hello, world');
  352. assert(testRetStdString() == 'Hello, world');
  353.  
  354. testParamInt(47);                       assert(testSucceeded());
  355. testParamBool(true);                    assert(testSucceeded());
  356. testParamFloat(47.0);                   assert(testSucceeded());
  357. testParamConstCharPtr('Hello, world');  assert(testSucceeded());
  358. testParamStdString('Hello, world');     assert(testSucceeded());
  359. testParamStdStringRef('Hello, world');  assert(testSucceeded());
  360.  
  361. -- test static methods of classes registered from C++
  362.  
  363. A.testStatic();             assert(testAFnCalled(FN_STATIC));
  364. B.testStatic();             assert(testAFnCalled(FN_STATIC));
  365. B.testStatic2();            assert(testBFnCalled(FN_STATIC));
  366.  
  367. -- test static properties of classes registered from C++
  368.  
  369. assert(A.testStaticProp == 47);
  370. assert(A.testStaticProp2 == 47);assert(testAFnCalled(FN_STATIC_PROPGET));
  371. A.testStaticProp = 48;          assert(A.testStaticProp == 48);
  372. A.testStaticProp2 = 49;         assert(testAFnCalled(FN_STATIC_PROPSET) and A.testStaticProp2 == 49);
  373.  
  374. -- test classes registered from C++
  375.  
  376. object1 = A('object1');          assert(testAFnCalled(FN_CTOR));
  377. object1:testVirtual();           assert(testAFnCalled(FN_VIRTUAL));
  378.  
  379. object2 = B('object2');         assert(testAFnCalled(FN_CTOR) and testBFnCalled(FN_CTOR));
  380. object2:testVirtual();          assert(testBFnCalled(FN_VIRTUAL) and not testAFnCalled(FN_VIRTUAL));
  381.  
  382. -- test functions taking and returning objects
  383.  
  384. testParamAPtr(object1);          assert(object1:testSucceeded());
  385. testParamAPtrConst(object1);     assert(object1:testSucceeded());
  386. testParamConstAPtr(object1);     assert(object1:testSucceeded());
  387. testParamSharedPtrA(object1);    assert(object1:testSucceeded());
  388.  
  389. testParamAPtr(object2);          assert(object2:testSucceeded());
  390. testParamAPtrConst(object2);     assert(object2:testSucceeded());
  391. testParamConstAPtr(object2);     assert(object2:testSucceeded());
  392. testParamSharedPtrA(object2);    assert(object2:testSucceeded());
  393.  
  394. result = testRetSharedPtrA();    assert(result:getName() == 'from C');
  395.  
  396. -- test constness
  397.  
  398. constA = testRetSharedPtrConstA();    assert(constA:getName() == 'const A');
  399. assert(constA.testVirtual == nil);
  400. testParamConstAPtr(constA);        assert(constA:testSucceeded());
  401. assert(pcall(testParamAPtr, constA) == false, 'attempt to call nil value');
  402.  
  403. -- test properties
  404.  
  405. assert(object1.testProp == 47);
  406. assert(object1.testProp2 == 47);    assert(testAFnCalled(FN_PROPGET));
  407. assert(object2.testProp == 47);
  408. assert(object2.testProp2 == 47);    assert(testAFnCalled(FN_PROPGET));
  409.  
  410. object1.testProp = 48;          assert(object1.testProp == 48);
  411. object1.testProp2 = 49;          assert(testAFnCalled(FN_PROPSET) and object1.testProp2 == 49);
  412.  
  413. -- test operator overload
  414. object1a = object1 + object1;      assert(testAFnCalled(FN_OPERATOR));
  415. assert(object1a:getName() == 'object1 + object1');
  416.  
  417. print('All tests succeeded.');
  418. )";
  419.  
  420. TEST_F(LegacyTests, AllTests)
  421. {
  422.     LuaBridgeTests::addToState(L);
  423.  
  424.     // Execute lua files in order
  425.     if (luaL_loadstring(L, SCRIPT) != 0)
  426.     {
  427.         // compile-time error
  428.         FAIL() << lua_tostring(L, -1);
  429.     }
  430.     if (lua_pcall(L, 0, 0, -2) != 0)
  431.     {
  432.         // runtime error
  433.         FAIL() << lua_tostring(L, -1);
  434.     }
  435. }
  436.