any_test.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // Copyright 2019 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "dap/any.h"
  15. #include "dap/typeof.h"
  16. #include "dap/types.h"
  17. #include "gmock/gmock.h"
  18. #include "gtest/gtest.h"
  19. namespace dap {
  20. struct AnyTestObject {
  21. dap::integer i;
  22. dap::number n;
  23. };
  24. DAP_STRUCT_TYPEINFO(AnyTestObject,
  25. "AnyTestObject",
  26. DAP_FIELD(i, "i"),
  27. DAP_FIELD(n, "n"));
  28. inline bool operator==(const AnyTestObject& a, const AnyTestObject& b) {
  29. return a.i == b.i && a.n == b.n;
  30. }
  31. } // namespace dap
  32. namespace {
  33. template <typename T>
  34. struct TestValue {};
  35. template <>
  36. struct TestValue<dap::null> {
  37. static const dap::null value;
  38. };
  39. template <>
  40. struct TestValue<dap::integer> {
  41. static const dap::integer value;
  42. };
  43. template <>
  44. struct TestValue<dap::boolean> {
  45. static const dap::boolean value;
  46. };
  47. template <>
  48. struct TestValue<dap::number> {
  49. static const dap::number value;
  50. };
  51. template <>
  52. struct TestValue<dap::string> {
  53. static const dap::string value;
  54. };
  55. template <>
  56. struct TestValue<dap::array<dap::string>> {
  57. static const dap::array<dap::string> value;
  58. };
  59. template <>
  60. struct TestValue<dap::AnyTestObject> {
  61. static const dap::AnyTestObject value;
  62. };
  63. const dap::null TestValue<dap::null>::value = nullptr;
  64. const dap::integer TestValue<dap::integer>::value = 20;
  65. const dap::boolean TestValue<dap::boolean>::value = true;
  66. const dap::number TestValue<dap::number>::value = 123.45;
  67. const dap::string TestValue<dap::string>::value = "hello world";
  68. const dap::array<dap::string> TestValue<dap::array<dap::string>>::value = {
  69. "one", "two", "three"};
  70. const dap::AnyTestObject TestValue<dap::AnyTestObject>::value = {10, 20.30};
  71. } // namespace
  72. TEST(Any, EmptyConstruct) {
  73. dap::any any;
  74. ASSERT_TRUE(any.is<dap::null>());
  75. ASSERT_FALSE(any.is<dap::boolean>());
  76. ASSERT_FALSE(any.is<dap::integer>());
  77. ASSERT_FALSE(any.is<dap::number>());
  78. ASSERT_FALSE(any.is<dap::object>());
  79. ASSERT_FALSE(any.is<dap::string>());
  80. ASSERT_FALSE(any.is<dap::array<dap::integer>>());
  81. ASSERT_FALSE(any.is<dap::AnyTestObject>());
  82. }
  83. TEST(Any, Boolean) {
  84. dap::any any(dap::boolean(true));
  85. ASSERT_TRUE(any.is<dap::boolean>());
  86. ASSERT_EQ(any.get<dap::boolean>(), dap::boolean(true));
  87. }
  88. TEST(Any, Integer) {
  89. dap::any any(dap::integer(10));
  90. ASSERT_TRUE(any.is<dap::integer>());
  91. ASSERT_EQ(any.get<dap::integer>(), dap::integer(10));
  92. }
  93. TEST(Any, Number) {
  94. dap::any any(dap::number(123.0f));
  95. ASSERT_TRUE(any.is<dap::number>());
  96. ASSERT_EQ(any.get<dap::number>(), dap::number(123.0f));
  97. }
  98. TEST(Any, String) {
  99. dap::any any(dap::string("hello world"));
  100. ASSERT_TRUE(any.is<dap::string>());
  101. ASSERT_EQ(any.get<dap::string>(), dap::string("hello world"));
  102. }
  103. TEST(Any, Array) {
  104. using array = dap::array<dap::integer>;
  105. dap::any any(array({10, 20, 30}));
  106. ASSERT_TRUE(any.is<array>());
  107. ASSERT_EQ(any.get<array>(), array({10, 20, 30}));
  108. }
  109. TEST(Any, Object) {
  110. dap::object o;
  111. o["one"] = dap::integer(1);
  112. o["two"] = dap::integer(2);
  113. o["three"] = dap::integer(3);
  114. dap::any any(o);
  115. ASSERT_TRUE(any.is<dap::object>());
  116. if (any.is<dap::object>()) {
  117. auto got = any.get<dap::object>();
  118. ASSERT_EQ(got.size(), 3U);
  119. ASSERT_EQ(got.count("one"), 1U);
  120. ASSERT_EQ(got.count("two"), 1U);
  121. ASSERT_EQ(got.count("three"), 1U);
  122. ASSERT_TRUE(got["one"].is<dap::integer>());
  123. ASSERT_TRUE(got["two"].is<dap::integer>());
  124. ASSERT_TRUE(got["three"].is<dap::integer>());
  125. ASSERT_EQ(got["one"].get<dap::integer>(), dap::integer(1));
  126. ASSERT_EQ(got["two"].get<dap::integer>(), dap::integer(2));
  127. ASSERT_EQ(got["three"].get<dap::integer>(), dap::integer(3));
  128. }
  129. }
  130. TEST(Any, TestObject) {
  131. dap::any any(dap::AnyTestObject{5, 3.0});
  132. ASSERT_TRUE(any.is<dap::AnyTestObject>());
  133. ASSERT_EQ(any.get<dap::AnyTestObject>().i, 5);
  134. ASSERT_EQ(any.get<dap::AnyTestObject>().n, 3.0);
  135. }
  136. template <typename T>
  137. class AnyT : public ::testing::Test {
  138. protected:
  139. template <typename T0,
  140. typename = std::enable_if<std::is_same<T, T0>::value &&
  141. !std::is_same<T0, dap::null>::value>>
  142. void check_val(const dap::any& any, const T0& expect) {
  143. ASSERT_EQ(any.is<T>(), any.is<T0>());
  144. ASSERT_EQ(any.get<T>(), expect);
  145. }
  146. // Special case for Null assignment, as we can assign nullptr_t to any but
  147. // can't `get()` it
  148. template <typename = dap::null>
  149. void check_val(const dap::any& any, const dap::null& expect) {
  150. ASSERT_EQ(nullptr, expect);
  151. ASSERT_TRUE(any.is<dap::null>());
  152. }
  153. void check_type(const dap::any& any) {
  154. ASSERT_EQ(any.is<dap::null>(), (std::is_same<T, dap::null>::value));
  155. ASSERT_EQ(any.is<dap::integer>(), (std::is_same<T, dap::integer>::value));
  156. ASSERT_EQ(any.is<dap::boolean>(), (std::is_same<T, dap::boolean>::value));
  157. ASSERT_EQ(any.is<dap::number>(), (std::is_same<T, dap::number>::value));
  158. ASSERT_EQ(any.is<dap::string>(), (std::is_same<T, dap::string>::value));
  159. ASSERT_EQ(any.is<dap::array<dap::string>>(),
  160. (std::is_same<T, dap::array<dap::string>>::value));
  161. ASSERT_EQ(any.is<dap::AnyTestObject>(),
  162. (std::is_same<T, dap::AnyTestObject>::value));
  163. }
  164. };
  165. TYPED_TEST_SUITE_P(AnyT);
  166. TYPED_TEST_P(AnyT, CopyConstruct) {
  167. auto val = TestValue<TypeParam>::value;
  168. dap::any any(val);
  169. this->check_type(any);
  170. this->check_val(any, val);
  171. }
  172. TYPED_TEST_P(AnyT, MoveConstruct) {
  173. auto val = TestValue<TypeParam>::value;
  174. dap::any any(std::move(val));
  175. this->check_type(any);
  176. this->check_val(any, val);
  177. }
  178. TYPED_TEST_P(AnyT, Assign) {
  179. auto val = TestValue<TypeParam>::value;
  180. dap::any any;
  181. any = val;
  182. this->check_type(any);
  183. this->check_val(any, val);
  184. }
  185. TYPED_TEST_P(AnyT, MoveAssign) {
  186. auto val = TestValue<TypeParam>::value;
  187. dap::any any;
  188. any = std::move(val);
  189. this->check_type(any);
  190. this->check_val(any, val);
  191. }
  192. TYPED_TEST_P(AnyT, RepeatedAssign) {
  193. dap::string str = "hello world";
  194. auto val = TestValue<TypeParam>::value;
  195. dap::any any;
  196. any = str;
  197. any = val;
  198. this->check_type(any);
  199. this->check_val(any, val);
  200. }
  201. TYPED_TEST_P(AnyT, RepeatedMoveAssign) {
  202. dap::string str = "hello world";
  203. auto val = TestValue<TypeParam>::value;
  204. dap::any any;
  205. any = std::move(str);
  206. any = std::move(val);
  207. this->check_type(any);
  208. this->check_val(any, val);
  209. }
  210. REGISTER_TYPED_TEST_SUITE_P(AnyT,
  211. CopyConstruct,
  212. MoveConstruct,
  213. Assign,
  214. MoveAssign,
  215. RepeatedAssign,
  216. RepeatedMoveAssign);
  217. using AnyTypes = ::testing::Types<dap::null,
  218. dap::integer,
  219. dap::boolean,
  220. dap::number,
  221. dap::string,
  222. dap::array<dap::string>,
  223. dap::AnyTestObject>;
  224. INSTANTIATE_TYPED_TEST_SUITE_P(T, AnyT, AnyTypes);
  225. TEST(Any, Reset) {
  226. dap::any any(dap::integer(10));
  227. ASSERT_TRUE(any.is<dap::integer>());
  228. any.reset();
  229. ASSERT_FALSE(any.is<dap::integer>());
  230. }