usertypes.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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("UserTypeRegistration") {
  9. luwra::StateWrapper state;
  10. luwra::registerUserType<A>(state);
  11. }
  12. TEST_CASE("UserTypeConstruction") {
  13. luwra::StateWrapper state;
  14. luwra::registerUserType<A(int)>(state, "A");
  15. // Construction
  16. REQUIRE(luaL_dostring(state, "return A(73)") == 0);
  17. // Check
  18. A* instance = luwra::read<A*>(state, -1);
  19. REQUIRE(instance != nullptr);
  20. REQUIRE(instance->a == 73);
  21. }
  22. struct B {
  23. int n;
  24. const int cn;
  25. volatile int vn;
  26. const volatile int cvn;
  27. B(int val):
  28. n(val),
  29. cn(val),
  30. vn(val),
  31. cvn(val)
  32. {}
  33. };
  34. TEST_CASE("UserTypeFields") {
  35. luwra::StateWrapper state;
  36. // Registration
  37. luwra::registerUserType<B>(
  38. state,
  39. {
  40. LUWRA_MEMBER(B, n),
  41. LUWRA_MEMBER(B, cn),
  42. LUWRA_MEMBER(B, vn),
  43. LUWRA_MEMBER(B, cvn)
  44. }
  45. );
  46. // Instantiation
  47. B& value = luwra::construct<B>(state, 1338);
  48. lua_setglobal(state, "value");
  49. // Unqualified get
  50. REQUIRE(luaL_dostring(state, "return value:n()") == 0);
  51. puts(lua_tostring(state, -1));
  52. REQUIRE(luwra::read<int>(state, -1) == value.n);
  53. // Unqualified set
  54. REQUIRE(luaL_dostring(state, "value:n(42)") == 0);
  55. REQUIRE(value.n == 42);
  56. // 'const'-qualified get
  57. REQUIRE(luaL_dostring(state, "return value:cn()") == 0);
  58. REQUIRE(luwra::read<int>(state, -1) == value.cn);
  59. // 'const'-qualified set
  60. REQUIRE(luaL_dostring(state, "value:cn(42)") == 0);
  61. REQUIRE(value.cn == 1338);
  62. // 'volatile' get
  63. REQUIRE(luaL_dostring(state, "return value:vn()") == 0);
  64. REQUIRE(luwra::read<int>(state, -1) == value.vn);
  65. // 'volatile' set
  66. REQUIRE(luaL_dostring(state, "value:vn(42)") == 0);
  67. REQUIRE(value.vn == 42);
  68. // 'const volatile'-qualified get
  69. REQUIRE(luaL_dostring(state, "return value:cvn()") == 0);
  70. REQUIRE(luwra::read<int>(state, -1) == value.cvn);
  71. // 'const volatile'-qualified set
  72. REQUIRE(luaL_dostring(state, "value:cvn(42)") == 0);
  73. REQUIRE(value.cvn == 1338);
  74. }
  75. struct C {
  76. int prop;
  77. C(int val):
  78. prop(val)
  79. {}
  80. int foo1(int x) {
  81. return prop += x;
  82. }
  83. int foo2(int x) const {
  84. return prop + x;
  85. }
  86. int foo3(int x) volatile {
  87. return prop -= x;
  88. }
  89. int foo4(int x) const volatile {
  90. return prop - x;
  91. }
  92. };
  93. TEST_CASE("UserTypeMethods") {
  94. luwra::StateWrapper state;
  95. // Registration
  96. luwra::registerUserType<C>(
  97. state,
  98. {
  99. LUWRA_MEMBER(C, foo1),
  100. LUWRA_MEMBER(C, foo2),
  101. LUWRA_MEMBER(C, foo3),
  102. LUWRA_MEMBER(C, foo4)
  103. }
  104. );
  105. // Instantiation
  106. C& value = luwra::construct<C>(state, 1337);
  107. lua_setglobal(state, "value");
  108. // Unqualified method
  109. REQUIRE(luaL_dostring(state, "return value:foo1(63)") == 0);
  110. REQUIRE(value.prop == 1400);
  111. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  112. // 'const'-qualified method
  113. REQUIRE(luaL_dostring(state, "return value:foo2(44)") == 0);
  114. REQUIRE(value.prop == 1400);
  115. REQUIRE(luwra::read<int>(state, -1) == 1444);
  116. // 'volatile'-qualified method
  117. REQUIRE(luaL_dostring(state, "return value:foo3(400)") == 0);
  118. REQUIRE(value.prop == 1000);
  119. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  120. // 'const volatile'-qualified method
  121. REQUIRE(luaL_dostring(state, "return value:foo4(334)") == 0);
  122. REQUIRE(value.prop == 1000);
  123. REQUIRE(luwra::read<int>(state, -1) == 666);
  124. }
  125. TEST_CASE("UserTypeGarbageCollectionRef") {
  126. lua_State* state = luaL_newstate();
  127. // Registration
  128. luwra::registerUserType<std::shared_ptr<int>>(state);
  129. // Instantiation
  130. std::shared_ptr<int> shared_var = std::make_shared<int>(1337);
  131. REQUIRE(shared_var.use_count() == 1);
  132. // Copy construction
  133. luwra::push(state, shared_var);
  134. REQUIRE(shared_var.use_count() == 2);
  135. // Garbage collection
  136. lua_close(state);
  137. REQUIRE(shared_var.use_count() == 1);
  138. }