usertypes.cpp 4.6 KB

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