usertypes.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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(state.runString("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(state.runString("return value:n()") == 0);
  51. REQUIRE(luwra::read<int>(state, -1) == value.n);
  52. // Unqualified set
  53. REQUIRE(state.runString("value:n(42)") == 0);
  54. REQUIRE(value.n == 42);
  55. // 'const'-qualified get
  56. REQUIRE(state.runString("return value:cn()") == 0);
  57. REQUIRE(luwra::read<int>(state, -1) == value.cn);
  58. // 'const'-qualified set
  59. REQUIRE(state.runString("value:cn(42)") == 0);
  60. REQUIRE(value.cn == 1338);
  61. // 'volatile' get
  62. REQUIRE(state.runString("return value:vn()") == 0);
  63. REQUIRE(luwra::read<int>(state, -1) == value.vn);
  64. // 'volatile' set
  65. REQUIRE(state.runString("value:vn(42)") == 0);
  66. REQUIRE(value.vn == 42);
  67. // 'const volatile'-qualified get
  68. REQUIRE(state.runString("return value:cvn()") == 0);
  69. REQUIRE(luwra::read<int>(state, -1) == value.cvn);
  70. // 'const volatile'-qualified set
  71. REQUIRE(state.runString("value:cvn(42)") == 0);
  72. REQUIRE(value.cvn == 1338);
  73. }
  74. struct C {
  75. int prop;
  76. C(int val):
  77. prop(val)
  78. {}
  79. int foo1(int x) {
  80. return prop += x;
  81. }
  82. int foo2(int x) const {
  83. return prop + x;
  84. }
  85. int foo3(int x) volatile {
  86. return prop -= x;
  87. }
  88. int foo4(int x) const volatile {
  89. return prop - x;
  90. }
  91. };
  92. TEST_CASE("UserTypeMethods") {
  93. luwra::StateWrapper state;
  94. // Registration
  95. luwra::registerUserType<C>(
  96. state,
  97. {
  98. LUWRA_MEMBER(C, foo1),
  99. LUWRA_MEMBER(C, foo2),
  100. LUWRA_MEMBER(C, foo3),
  101. LUWRA_MEMBER(C, foo4)
  102. }
  103. );
  104. // Instantiation
  105. C& value = luwra::construct<C>(state, 1337);
  106. lua_setglobal(state, "value");
  107. // Unqualified method
  108. REQUIRE(state.runString("return value:foo1(63)") == 0);
  109. REQUIRE(value.prop == 1400);
  110. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  111. // 'const'-qualified method
  112. REQUIRE(state.runString("return value:foo2(44)") == 0);
  113. REQUIRE(value.prop == 1400);
  114. REQUIRE(luwra::read<int>(state, -1) == 1444);
  115. // 'volatile'-qualified method
  116. REQUIRE(state.runString("return value:foo3(400)") == 0);
  117. REQUIRE(value.prop == 1000);
  118. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  119. // 'const volatile'-qualified method
  120. REQUIRE(state.runString("return value:foo4(334)") == 0);
  121. REQUIRE(value.prop == 1000);
  122. REQUIRE(luwra::read<int>(state, -1) == 666);
  123. }
  124. TEST_CASE("UserTypeGarbageCollectionRef") {
  125. lua_State* state = luaL_newstate();
  126. // Registration
  127. luwra::registerUserType<std::shared_ptr<int>>(state);
  128. // Instantiation
  129. std::shared_ptr<int> shared_var = std::make_shared<int>(1337);
  130. REQUIRE(shared_var.use_count() == 1);
  131. // Copy construction
  132. luwra::push(state, shared_var);
  133. REQUIRE(shared_var.use_count() == 2);
  134. // Garbage collection
  135. lua_close(state);
  136. REQUIRE(shared_var.use_count() == 1);
  137. }