usertypes.cpp 5.0 KB

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