test_collection.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*************************************************************************
  2. * Copyright (C) [2021] by Cambricon, Inc. All rights reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. * THE SOFTWARE.
  19. *************************************************************************/
  20. #include <gtest/gtest.h>
  21. #include <string>
  22. #include <utility>
  23. #include "cnstream_collection.hpp"
  24. namespace collection_test {
  25. struct TestStructA {
  26. std::string member_a;
  27. float member_b;
  28. TestStructA() = default;
  29. TestStructA(const std::string ma, float mb) : member_a(ma), member_b(mb) {}
  30. TestStructA(TestStructA&& other) {
  31. member_a = std::move(other.member_a);
  32. std::swap(member_b, other.member_b);
  33. }
  34. TestStructA(const TestStructA& other) {
  35. member_a = other.member_a;
  36. member_b = other.member_b;
  37. }
  38. TestStructA& operator=(const TestStructA& other) {
  39. member_a = other.member_a;
  40. member_b = other.member_b;
  41. return *this;
  42. }
  43. TestStructA& operator=(TestStructA&& other) {
  44. member_a = std::move(other.member_a);
  45. std::swap(member_b, other.member_b);
  46. return *this;
  47. }
  48. }; // struct TestStructA
  49. struct TestStructB {
  50. std::string member_a;
  51. int member_b;
  52. TestStructB() = default;
  53. TestStructB(const std::string ma, int mb) : member_a(ma), member_b(mb) {}
  54. TestStructB(TestStructB&& other) {
  55. member_a = std::move(other.member_a);
  56. std::swap(member_b, other.member_b);
  57. }
  58. TestStructB(const TestStructB& other) {
  59. member_a = other.member_a;
  60. member_b = other.member_b;
  61. }
  62. TestStructB& operator=(const TestStructB& other) {
  63. member_a = other.member_a;
  64. member_b = other.member_b;
  65. return *this;
  66. }
  67. TestStructB& operator=(TestStructB&& other) {
  68. member_a = std::move(other.member_a);
  69. std::swap(member_b, other.member_b);
  70. return *this;
  71. }
  72. }; // struct TestStructB
  73. bool operator==(const TestStructA& a, const TestStructA& b) {
  74. return a.member_a == b.member_a && a.member_b == b.member_b;
  75. }
  76. bool operator==(const TestStructB& a, const TestStructB& b) {
  77. return a.member_a == b.member_a && a.member_b == b.member_b;
  78. }
  79. } // namespace collection_test
  80. static const char test_tag0[] = "test_tag0";
  81. static const char test_tag1[] = "test_tag1";
  82. static const collection_test::TestStructA value_a { "structa_member_a", 1.2 };
  83. static const collection_test::TestStructB value_b { "structb_member_b", 1 };
  84. TEST(CoreCollection, Add) {
  85. {
  86. // const lvalue version
  87. cnstream::Collection collection;
  88. collection_test::TestStructA& ret = collection.Add(test_tag0, value_a);
  89. EXPECT_EQ(ret, value_a);
  90. }
  91. {
  92. // rvalue version
  93. cnstream::Collection collection;
  94. collection_test::TestStructA value_moved = value_a;
  95. collection_test::TestStructA& ret = collection.Add(test_tag0, std::move(value_moved));
  96. EXPECT_EQ(ret, value_a);
  97. }
  98. {
  99. // add two tag
  100. cnstream::Collection collection;
  101. collection_test::TestStructA& ret_a = collection.Add(test_tag0, value_a);
  102. collection_test::TestStructB& ret_b = collection.Add(test_tag1, value_b);
  103. EXPECT_EQ(ret_a, value_a);
  104. EXPECT_EQ(ret_b, value_b);
  105. }
  106. {
  107. // add the same tag twice
  108. cnstream::Collection collection;
  109. collection.Add(test_tag0, value_a);
  110. EXPECT_DEATH(collection.Add(test_tag0, value_a), "");
  111. }
  112. }
  113. TEST(CoreCollection, AddIfNotExist) {
  114. {
  115. // const lvalue version
  116. cnstream::Collection collection;
  117. bool ret = collection.AddIfNotExists(test_tag0, value_a);
  118. EXPECT_TRUE(ret);
  119. EXPECT_EQ(value_a, collection.Get<collection_test::TestStructA>(test_tag0));
  120. ret = collection.AddIfNotExists(test_tag0, value_b);
  121. EXPECT_FALSE(ret);
  122. EXPECT_EQ(value_a, collection.Get<collection_test::TestStructA>(test_tag0));
  123. ret = collection.AddIfNotExists(test_tag1, value_b);
  124. EXPECT_TRUE(ret);
  125. EXPECT_EQ(value_b, collection.Get<collection_test::TestStructB>(test_tag1));
  126. }
  127. {
  128. // rvalue version
  129. cnstream::Collection collection;
  130. collection_test::TestStructA value_moved = value_a;
  131. bool ret = collection.AddIfNotExists(test_tag0, std::move(value_moved));
  132. EXPECT_TRUE(ret);
  133. EXPECT_EQ(value_a, collection.Get<collection_test::TestStructA>(test_tag0));
  134. collection_test::TestStructB value_b_moved = value_b;
  135. ret = collection.AddIfNotExists(test_tag0, std::move(value_b));
  136. EXPECT_FALSE(ret);
  137. EXPECT_EQ(value_a, collection.Get<collection_test::TestStructA>(test_tag0));
  138. ret = collection.AddIfNotExists(test_tag1, std::move(value_b));
  139. EXPECT_TRUE(ret);
  140. EXPECT_EQ(value_b, collection.Get<collection_test::TestStructB>(test_tag1));
  141. }
  142. }
  143. TEST(CoreCollection, Get) {
  144. {
  145. // normal
  146. cnstream::Collection collection;
  147. collection.Add(test_tag0, value_a);
  148. collection_test::TestStructA& ret = collection.Get<collection_test::TestStructA>(test_tag0);
  149. EXPECT_EQ(ret, value_a);
  150. // modify value
  151. ret.member_a = "modified_member_a";
  152. EXPECT_EQ(collection.Get<collection_test::TestStructA>(test_tag0), ret);
  153. }
  154. {
  155. // never added
  156. cnstream::Collection collection;
  157. EXPECT_DEATH(collection.Get<collection_test::TestStructB>(test_tag0), "");
  158. }
  159. {
  160. // not match type
  161. cnstream::Collection collection;
  162. collection.Add(test_tag0, value_a);
  163. EXPECT_DEATH(collection.Get<collection_test::TestStructB>(test_tag0), "");
  164. }
  165. {
  166. // two tag
  167. cnstream::Collection collection;
  168. collection_test::TestStructA& ret = collection.Add(test_tag0, value_a);
  169. collection.Add(test_tag1, value_b);
  170. EXPECT_EQ(ret, value_a);
  171. EXPECT_EQ(ret, collection.Get<collection_test::TestStructA>(test_tag0));
  172. }
  173. }
  174. TEST(CoreCollection, MapRealloc) {
  175. // test map realloc
  176. cnstream::Collection collection;
  177. collection_test::TestStructA& ret = collection.Add(test_tag0, value_a);
  178. ret.member_a = "modified_member_a";
  179. for (int i = 0; i < 2048; ++i)
  180. collection.Add(std::to_string(i), value_a);
  181. EXPECT_EQ(collection.Get<collection_test::TestStructA>(test_tag0), ret);
  182. }
  183. TEST(CoreCollection, HasValue) {
  184. cnstream::Collection collection;
  185. collection.Add(test_tag0, value_a);
  186. EXPECT_TRUE(collection.HasValue(test_tag0));
  187. EXPECT_FALSE(collection.HasValue(test_tag1));
  188. }
  189. #if !defined(_LIBCPP_NO_RTTI)
  190. TEST(CoreCollection, Type) {
  191. cnstream::Collection collection;
  192. collection.Add(test_tag0, value_a);
  193. EXPECT_EQ(typeid(collection_test::TestStructA), collection.Type(test_tag0));
  194. EXPECT_NE(typeid(collection_test::TestStructB), collection.Type(test_tag0));
  195. // tag not added
  196. EXPECT_DEATH(collection.Get<collection_test::TestStructB>(test_tag1), "");
  197. }
  198. TEST(CoreCollection, TaggedIsOfType) {
  199. cnstream::Collection collection;
  200. collection.Add(test_tag0, value_a);
  201. EXPECT_TRUE(collection.TaggedIsOfType<collection_test::TestStructA>(test_tag0));
  202. EXPECT_FALSE(collection.TaggedIsOfType<collection_test::TestStructB>(test_tag0));
  203. }
  204. #endif