?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. // https://github.com/vinniefalco/LuaBridge
  2. // Copyright 2021, Stefan Frings
  3. // SPDX-License-Identifier: MIT
  4.  
  5. #include "TestBase.h"
  6. #include "TestTypes.h"
  7.  
  8. #include "LuaBridge/Optional.h"
  9.  
  10. #include <optional>
  11.  
  12. template<class T>
  13. struct OptionalTest : TestBase
  14. {
  15. };
  16.  
  17. TYPED_TEST_CASE_P(OptionalTest);
  18.  
  19. template<typename T>
  20. std::string toLuaSrcString(T const& value)
  21. {
  22.     return std::to_string(value);
  23. }
  24.  
  25. template<>
  26. std::string toLuaSrcString(bool const& value)
  27. {
  28.     return value ? "true" : "false";
  29. }
  30.  
  31. template<>
  32. std::string toLuaSrcString(char const& value)
  33. {
  34.     return "'" + std::string(&value, 1) + "'";
  35. }
  36.  
  37. template<>
  38. std::string toLuaSrcString(std::string const& value)
  39. {
  40.     return "'" + value + "'";
  41. }
  42.  
  43. #ifdef LUABRIDGE_CXX17
  44.  
  45. template<>
  46. std::string toLuaSrcString<std::string_view>(const std::string_view& value)
  47. {
  48.     return toLuaSrcString(std::string(value));
  49. }
  50.  
  51. #endif // LUABRIDGE_CXX17
  52.  
  53. template<typename T>
  54. std::optional<T> optCast(luabridge::LuaRef const& ref)
  55. {
  56.     // NOTE cast to std::optional: https://stackoverflow.com/a/45865802
  57.     return ref.cast<std::optional<T>>();
  58. }
  59.  
  60. TYPED_TEST_P(OptionalTest, LuaRefPresent)
  61. {
  62.     using Traits = TypeTraits<TypeParam>;
  63.  
  64.     for (TypeParam const& value : Traits::values())
  65.     {
  66.         std::string const luaSrc = "result = " + toLuaSrcString(value);
  67.  
  68.         SCOPED_TRACE(luaSrc);
  69.         this->runLua(luaSrc);
  70.  
  71.         std::optional<TypeParam> const actual = optCast<TypeParam>(this->result());
  72.         ASSERT_TRUE(actual.has_value());
  73.         ASSERT_EQ(value, actual.value());
  74.     }
  75. }
  76.  
  77. TYPED_TEST_P(OptionalTest, LuaRefNotPresent)
  78. {
  79.     this->runLua("result = nil");
  80.  
  81.     std::optional<TypeParam> const actual = optCast<TypeParam>(this->result());
  82.     ASSERT_FALSE(actual.has_value());
  83. }
  84.  
  85. TYPED_TEST_P(OptionalTest, LuaRefIsInstancePresent)
  86. {
  87.     using Traits = TypeTraits<TypeParam>;
  88.  
  89.     for (TypeParam const& value : Traits::values())
  90.     {
  91.         std::string const luaSrc = "result = " + toLuaSrcString(value);
  92.  
  93.         SCOPED_TRACE(luaSrc);
  94.         this->runLua(luaSrc);
  95.  
  96.         luabridge::LuaRef const actualRef = this->result();
  97.         ASSERT_TRUE(actualRef.isInstance<std::optional<TypeParam>>());
  98.  
  99.         // if isInstance returns true a cast without issues is possible
  100.         std::optional<TypeParam> const actual = optCast<TypeParam>(actualRef);
  101.     }
  102. }
  103.  
  104. TYPED_TEST_P(OptionalTest, LuaRefIsInstancePresentWrongType)
  105. {
  106.     this->runLua("function func() end; result = func");
  107.  
  108.     luabridge::LuaRef const actualRef = this->result();
  109.     ASSERT_FALSE(actualRef.isInstance<std::optional<TypeParam>>());
  110. }
  111.  
  112. TYPED_TEST_P(OptionalTest, LuaRefIsInstanceNotPresent)
  113. {
  114.     this->runLua("result = nil");
  115.  
  116.     luabridge::LuaRef const actualRef = this->result();
  117.     ASSERT_TRUE(actualRef.isInstance<std::optional<TypeParam>>());
  118.  
  119.     // if isInstance returns true a cast without issues is possible
  120.     std::optional<TypeParam> const actual = optCast<TypeParam>(actualRef);
  121. }
  122.  
  123. REGISTER_TYPED_TEST_CASE_P(OptionalTest,
  124.                            LuaRefPresent,
  125.                            LuaRefNotPresent,
  126.                            LuaRefIsInstancePresent,
  127.                            LuaRefIsInstancePresentWrongType,
  128.                            LuaRefIsInstanceNotPresent);
  129.  
  130. INSTANTIATE_TYPED_TEST_CASE_P(OptionalTest, OptionalTest, TestTypes);
  131.  
  132. namespace {
  133.  
  134. struct Data
  135. {
  136.     explicit Data(int i) : i(i) {}
  137.  
  138.     int i;
  139. };
  140.  
  141. bool operator==(Data const& lhs, Data const& rhs)
  142. {
  143.     return lhs.i == rhs.i;
  144. }
  145.  
  146. template<typename T>
  147. bool operator==(std::optional<T> const& lhs, std::optional<T> const& rhs)
  148. {
  149.     if (lhs.has_value() != rhs.has_value())
  150.     {
  151.         return false;
  152.     }
  153.  
  154.     if (lhs.has_value())
  155.     {
  156.         assert(rhs.has_value());
  157.         return lhs.value() == rhs.value();
  158.     }
  159.  
  160.     assert(!lhs.has_value());
  161.     assert(!rhs.has_value());
  162.     return true;
  163. }
  164.  
  165. std::optional<Data> processValue(std::optional<Data> const& data)
  166. {
  167.     return data;
  168. }
  169.  
  170. std::optional<Data> processPointer(std::optional<const Data*> const& data)
  171. {
  172.     std::optional<Data> result;
  173.     if (data)
  174.     {
  175.         result = **data;
  176.     }
  177.     return result;
  178. }
  179.  
  180. } // namespace
  181.  
  182. struct OptionalTests : TestBase
  183. {
  184. };
  185.  
  186. template<typename T>
  187. void testPassFromLua(OptionalTests const& fixture,
  188.                      std::string const& functionName,
  189.                      std::string const& valueString,
  190.                      std::optional<T> const expected)
  191. {
  192.     fixture.resetResult();
  193.  
  194.     std::string const luaSrc = "result = " + functionName + "(" + valueString + ")";
  195.  
  196.     SCOPED_TRACE(luaSrc);
  197.     fixture.runLua(luaSrc);
  198.  
  199.     std::optional<T> const actual = optCast<T>(fixture.result());
  200.     ASSERT_EQ(expected, actual);
  201. }
  202.  
  203. TEST_F(OptionalTests, PassFromLua)
  204. {
  205.     luabridge::getGlobalNamespace(L)
  206.         .beginClass<Data>("Data")
  207.         .addConstructor<void (*)(int)>()
  208.         .endClass()
  209.         .addFunction("processValue", &processValue)
  210.         .addFunction("processPointer", &processPointer);
  211.  
  212.     testPassFromLua<Data>(*this, "processValue", "Data(-1)", Data(-1));
  213.     testPassFromLua<Data>(*this, "processValue", "Data(2)", Data(2));
  214.     testPassFromLua<Data>(*this, "processValue", "nil", std::nullopt);
  215.  
  216.     testPassFromLua<Data>(*this, "processPointer", "Data(-1)", Data(-1));
  217.     testPassFromLua<Data>(*this, "processPointer", "Data(2)", Data(2));
  218.     testPassFromLua<Data>(*this, "processPointer", "nil", std::nullopt);
  219. }
  220.