usertypes.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <catch.hpp>
  2. #include <luwra.hpp>
  3. #include <memory>
  4. struct A {
  5. int a;
  6. A(int x = 1338): a(x) {}
  7. };
  8. TEST_CASE("usertypes_registration") {
  9. lua_State* state = luaL_newstate();
  10. // Registration
  11. luwra::registerUserType<A>(state);
  12. // Reference
  13. A* instance = new A;
  14. luwra::Value<A*>::push(state, instance);
  15. // Type checks
  16. REQUIRE(luwra::internal::check_user_type<A>(state, -1) == instance);
  17. REQUIRE(luwra::Value<A*>::read(state, -1) == instance);
  18. lua_close(state);
  19. delete instance;
  20. }
  21. TEST_CASE("usertypes_ctor") {
  22. lua_State* state = luaL_newstate();
  23. // Registration
  24. luwra::registerUserType<A>(state);
  25. luwra::setGlobal(state, "A", LUWRA_WRAP_CONSTRUCTOR(A, int));
  26. // Construction
  27. REQUIRE(luaL_dostring(state, "return A(73)") == 0);
  28. // Check
  29. A* instance = luwra::read<A*>(state, -1);
  30. REQUIRE(instance != nullptr);
  31. REQUIRE(instance->a == 73);
  32. lua_close(state);
  33. }
  34. struct B {
  35. int n;
  36. const int cn;
  37. volatile int vn;
  38. const volatile int cvn;
  39. B(int val):
  40. n(val),
  41. cn(val),
  42. vn(val),
  43. cvn(val)
  44. {}
  45. };
  46. TEST_CASE("usertypes_wrap_fields") {
  47. lua_State* state = luaL_newstate();
  48. // Registration
  49. luwra::registerUserType<B>(
  50. state,
  51. {
  52. LUWRA_MEMBER(B, n),
  53. LUWRA_MEMBER(B, cn),
  54. LUWRA_MEMBER(B, vn),
  55. LUWRA_MEMBER(B, cvn)
  56. }
  57. );
  58. // Instantiation
  59. B value(1338);
  60. luwra::setGlobal(state, "val", &value);
  61. // Unqualified get
  62. REQUIRE(luaL_dostring(state, "return val:n()") == 0);
  63. REQUIRE(luwra::read<int>(state, -1) == value.n);
  64. // Unqualified set
  65. REQUIRE(luaL_dostring(state, "val:n(42)") == 0);
  66. REQUIRE(value.n == 42);
  67. // 'const'-qualified get
  68. REQUIRE(luaL_dostring(state, "return val:cn()") == 0);
  69. REQUIRE(luwra::read<int>(state, -1) == value.cn);
  70. // 'const'-qualified set
  71. REQUIRE(luaL_dostring(state, "val:cn(42)") == 0);
  72. REQUIRE(value.cn == 1338);
  73. // 'volatile' get
  74. REQUIRE(luaL_dostring(state, "return val:vn()") == 0);
  75. REQUIRE(luwra::read<int>(state, -1) == value.vn);
  76. // 'volatile' set
  77. REQUIRE(luaL_dostring(state, "val:vn(42)") == 0);
  78. REQUIRE(value.vn == 42);
  79. // 'const volatile'-qualified get
  80. REQUIRE(luaL_dostring(state, "return val:cvn()") == 0);
  81. REQUIRE(luwra::read<int>(state, -1) == value.cvn);
  82. // 'const volatile'-qualified set
  83. REQUIRE(luaL_dostring(state, "val:cvn(42)") == 0);
  84. REQUIRE(value.cvn == 1338);
  85. lua_close(state);
  86. }
  87. struct C {
  88. int prop;
  89. C(int val):
  90. prop(val)
  91. {}
  92. int foo1(int x) {
  93. return prop += x;
  94. }
  95. int foo2(int x) const {
  96. return prop + x;
  97. }
  98. int foo3(int x) volatile {
  99. return prop -= x;
  100. }
  101. int foo4(int x) const volatile {
  102. return prop - x;
  103. }
  104. };
  105. TEST_CASE("usertypes_wrap_methods") {
  106. lua_State* state = luaL_newstate();
  107. // Registration
  108. luwra::registerUserType<C>(
  109. state,
  110. {
  111. LUWRA_MEMBER(C, foo1),
  112. LUWRA_MEMBER(C, foo2),
  113. LUWRA_MEMBER(C, foo3),
  114. LUWRA_MEMBER(C, foo4)
  115. }
  116. );
  117. // Instantiation
  118. C value(1337);
  119. luwra::setGlobal(state, "value", &value);
  120. // Unqualified method
  121. REQUIRE(luaL_dostring(state, "return value:foo1(63)") == 0);
  122. REQUIRE(value.prop == 1400);
  123. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  124. // 'const'-qualified method
  125. REQUIRE(luaL_dostring(state, "return value:foo2(44)") == 0);
  126. REQUIRE(value.prop == 1400);
  127. REQUIRE(luwra::read<int>(state, -1) == 1444);
  128. // 'volatile'-qualified method
  129. REQUIRE(luaL_dostring(state, "return value:foo3(400)") == 0);
  130. REQUIRE(value.prop == 1000);
  131. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  132. // 'const volatile'-qualified method
  133. REQUIRE(luaL_dostring(state, "return value:foo4(334)") == 0);
  134. REQUIRE(value.prop == 1000);
  135. REQUIRE(luwra::read<int>(state, -1) == 666);
  136. lua_close(state);
  137. }
  138. TEST_CASE("usertypes_gchook_tref") {
  139. lua_State* state = luaL_newstate();
  140. // Registration
  141. luwra::registerUserType<std::shared_ptr<int>>(state);
  142. // Instantiation
  143. std::shared_ptr<int> shared_var = std::make_shared<int>(1337);
  144. REQUIRE(shared_var.use_count() == 1);
  145. // Copy construction
  146. luwra::push<std::shared_ptr<int>&>(state, shared_var);
  147. REQUIRE(shared_var.use_count() == 2);
  148. // Garbage collection
  149. lua_close(state);
  150. REQUIRE(shared_var.use_count() == 1);
  151. }
  152. TEST_CASE("usertypes_gchook_tptr") {
  153. lua_State* state = luaL_newstate();
  154. // Registration
  155. luwra::registerUserType<std::shared_ptr<int>>(state);
  156. // Instantiation
  157. std::shared_ptr<int> shared_var = std::make_shared<int>(1337);
  158. REQUIRE(shared_var.use_count() == 1);
  159. // Reference
  160. luwra::push(state, &shared_var);
  161. REQUIRE(shared_var.use_count() == 1);
  162. // Garbage collection
  163. lua_close(state);
  164. REQUIRE(shared_var.use_count() == 1);
  165. }