ilist_test.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. // Copyright (c) 2017 Google Inc.
  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. // http://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 <utility>
  15. #include <vector>
  16. #include "gmock/gmock.h"
  17. #include "source/util/ilist.h"
  18. namespace spvtools {
  19. namespace utils {
  20. namespace {
  21. using ::testing::ElementsAre;
  22. using IListTest = ::testing::Test;
  23. class TestNode : public IntrusiveNodeBase<TestNode> {
  24. public:
  25. TestNode() : IntrusiveNodeBase<TestNode>() {}
  26. int data_;
  27. };
  28. class TestList : public IntrusiveList<TestNode> {
  29. public:
  30. TestList() = default;
  31. TestList(TestList&& that) : IntrusiveList<TestNode>(std::move(that)) {}
  32. TestList& operator=(TestList&& that) {
  33. static_cast<IntrusiveList<TestNode>&>(*this) =
  34. static_cast<IntrusiveList<TestNode>&&>(that);
  35. return *this;
  36. }
  37. };
  38. // This test checks the push_back method, as well as using an iterator to
  39. // traverse the list from begin() to end(). This implicitly test the
  40. // PreviousNode and NextNode functions.
  41. TEST(IListTest, PushBack) {
  42. TestNode nodes[10];
  43. TestList list;
  44. for (int i = 0; i < 10; i++) {
  45. nodes[i].data_ = i;
  46. list.push_back(&nodes[i]);
  47. }
  48. std::vector<int> output;
  49. for (auto& i : list) output.push_back(i.data_);
  50. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
  51. }
  52. // Returns a list containing the values 0 to n-1 using the first n elements of
  53. // nodes to build the list.
  54. TestList BuildList(TestNode nodes[], int n) {
  55. TestList list;
  56. for (int i = 0; i < n; i++) {
  57. nodes[i].data_ = i;
  58. list.push_back(&nodes[i]);
  59. }
  60. return list;
  61. }
  62. // Test decrementing begin()
  63. TEST(IListTest, DecrementingBegin) {
  64. TestNode nodes[10];
  65. TestList list = BuildList(nodes, 10);
  66. EXPECT_EQ(--list.begin(), list.end());
  67. }
  68. // Test incrementing end()
  69. TEST(IListTest, IncrementingEnd1) {
  70. TestNode nodes[10];
  71. TestList list = BuildList(nodes, 10);
  72. EXPECT_EQ((++list.end())->data_, 0);
  73. }
  74. // Test incrementing end() should equal begin()
  75. TEST(IListTest, IncrementingEnd2) {
  76. TestNode nodes[10];
  77. TestList list = BuildList(nodes, 10);
  78. EXPECT_EQ(++list.end(), list.begin());
  79. }
  80. // Test decrementing end()
  81. TEST(IListTest, DecrementingEnd) {
  82. TestNode nodes[10];
  83. TestList list = BuildList(nodes, 10);
  84. EXPECT_EQ((--list.end())->data_, 9);
  85. }
  86. // Test the move constructor for the list class.
  87. TEST(IListTest, MoveConstructor) {
  88. TestNode nodes[10];
  89. TestList list = BuildList(nodes, 10);
  90. std::vector<int> output;
  91. for (auto& i : list) output.push_back(i.data_);
  92. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
  93. }
  94. // Using a const list so we can test the const_iterator.
  95. TEST(IListTest, ConstIterator) {
  96. TestNode nodes[10];
  97. const TestList list = BuildList(nodes, 10);
  98. std::vector<int> output;
  99. for (auto& i : list) output.push_back(i.data_);
  100. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
  101. }
  102. // Uses the move assignement instead of the move constructor.
  103. TEST(IListTest, MoveAssignment) {
  104. TestNode nodes[10];
  105. TestList list;
  106. list = BuildList(nodes, 10);
  107. std::vector<int> output;
  108. for (auto& i : list) output.push_back(i.data_);
  109. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
  110. }
  111. // Test inserting a new element at the end of a list using the IntrusiveNodeBase
  112. // "InsertAfter" function.
  113. TEST(IListTest, InsertAfter1) {
  114. TestNode nodes[10];
  115. TestList list = BuildList(nodes, 5);
  116. nodes[5].data_ = 5;
  117. nodes[5].InsertAfter(&nodes[4]);
  118. std::vector<int> output;
  119. for (auto& i : list) output.push_back(i.data_);
  120. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5));
  121. }
  122. // Test inserting a new element in the middle of a list using the
  123. // IntrusiveNodeBase "InsertAfter" function.
  124. TEST(IListTest, InsertAfter2) {
  125. TestNode nodes[10];
  126. TestList list = BuildList(nodes, 5);
  127. nodes[5].data_ = 5;
  128. nodes[5].InsertAfter(&nodes[2]);
  129. std::vector<int> output;
  130. for (auto& i : list) output.push_back(i.data_);
  131. EXPECT_THAT(output, ElementsAre(0, 1, 2, 5, 3, 4));
  132. }
  133. // Test moving an element already in the list in the middle of a list using the
  134. // IntrusiveNodeBase "InsertAfter" function.
  135. TEST(IListTest, MoveUsingInsertAfter1) {
  136. TestNode nodes[10];
  137. TestList list = BuildList(nodes, 6);
  138. nodes[5].InsertAfter(&nodes[2]);
  139. std::vector<int> output;
  140. for (auto& i : list) output.push_back(i.data_);
  141. EXPECT_THAT(output, ElementsAre(0, 1, 2, 5, 3, 4));
  142. }
  143. // Move the element at the start of the list into the middle.
  144. TEST(IListTest, MoveUsingInsertAfter2) {
  145. TestNode nodes[10];
  146. TestList list = BuildList(nodes, 6);
  147. nodes[0].InsertAfter(&nodes[2]);
  148. std::vector<int> output;
  149. for (auto& i : list) output.push_back(i.data_);
  150. EXPECT_THAT(output, ElementsAre(1, 2, 0, 3, 4, 5));
  151. }
  152. // Move an element in the middle of the list to the end.
  153. TEST(IListTest, MoveUsingInsertAfter3) {
  154. TestNode nodes[10];
  155. TestList list = BuildList(nodes, 6);
  156. nodes[2].InsertAfter(&nodes[5]);
  157. std::vector<int> output;
  158. for (auto& i : list) output.push_back(i.data_);
  159. EXPECT_THAT(output, ElementsAre(0, 1, 3, 4, 5, 2));
  160. }
  161. // Removing an element from the middle of a list.
  162. TEST(IListTest, Remove1) {
  163. TestNode nodes[10];
  164. TestList list = BuildList(nodes, 6);
  165. nodes[2].RemoveFromList();
  166. std::vector<int> output;
  167. for (auto& i : list) output.push_back(i.data_);
  168. EXPECT_THAT(output, ElementsAre(0, 1, 3, 4, 5));
  169. }
  170. // Removing an element from the beginning of the list.
  171. TEST(IListTest, Remove2) {
  172. TestNode nodes[10];
  173. TestList list = BuildList(nodes, 6);
  174. nodes[0].RemoveFromList();
  175. std::vector<int> output;
  176. for (auto& i : list) output.push_back(i.data_);
  177. EXPECT_THAT(output, ElementsAre(1, 2, 3, 4, 5));
  178. }
  179. // Removing the last element of a list.
  180. TEST(IListTest, Remove3) {
  181. TestNode nodes[10];
  182. TestList list = BuildList(nodes, 6);
  183. nodes[5].RemoveFromList();
  184. std::vector<int> output;
  185. for (auto& i : list) output.push_back(i.data_);
  186. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4));
  187. }
  188. // Test that operator== and operator!= work properly for the iterator class.
  189. TEST(IListTest, IteratorEqual) {
  190. TestNode nodes[10];
  191. TestList list = BuildList(nodes, 6);
  192. std::vector<int> output;
  193. for (auto i = list.begin(); i != list.end(); ++i)
  194. for (auto j = list.begin(); j != list.end(); ++j)
  195. if (i == j) output.push_back(i->data_);
  196. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5));
  197. }
  198. // Test MoveBefore. Moving into middle of a list.
  199. TEST(IListTest, MoveBefore1) {
  200. TestNode nodes[10];
  201. TestList list1 = BuildList(nodes, 6);
  202. TestList list2 = BuildList(nodes + 6, 3);
  203. TestList::iterator insertion_point = list1.begin();
  204. ++insertion_point;
  205. insertion_point.MoveBefore(&list2);
  206. std::vector<int> output;
  207. for (auto i = list1.begin(); i != list1.end(); ++i) {
  208. output.push_back(i->data_);
  209. }
  210. EXPECT_THAT(output, ElementsAre(0, 0, 1, 2, 1, 2, 3, 4, 5));
  211. }
  212. // Test MoveBefore. Moving to the start of a list.
  213. TEST(IListTest, MoveBefore2) {
  214. TestNode nodes[10];
  215. TestList list1 = BuildList(nodes, 6);
  216. TestList list2 = BuildList(nodes + 6, 3);
  217. TestList::iterator insertion_point = list1.begin();
  218. insertion_point.MoveBefore(&list2);
  219. std::vector<int> output;
  220. for (auto i = list1.begin(); i != list1.end(); ++i) {
  221. output.push_back(i->data_);
  222. }
  223. EXPECT_THAT(output, ElementsAre(0, 1, 2, 0, 1, 2, 3, 4, 5));
  224. }
  225. // Test MoveBefore. Moving to the end of a list.
  226. TEST(IListTest, MoveBefore3) {
  227. TestNode nodes[10];
  228. TestList list1 = BuildList(nodes, 6);
  229. TestList list2 = BuildList(nodes + 6, 3);
  230. TestList::iterator insertion_point = list1.end();
  231. insertion_point.MoveBefore(&list2);
  232. std::vector<int> output;
  233. for (auto i = list1.begin(); i != list1.end(); ++i) {
  234. output.push_back(i->data_);
  235. }
  236. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5, 0, 1, 2));
  237. }
  238. // Test MoveBefore. Moving an empty list.
  239. TEST(IListTest, MoveBefore4) {
  240. TestNode nodes[10];
  241. TestList list1 = BuildList(nodes, 6);
  242. TestList list2;
  243. TestList::iterator insertion_point = list1.end();
  244. insertion_point.MoveBefore(&list2);
  245. std::vector<int> output;
  246. for (auto i = list1.begin(); i != list1.end(); ++i) {
  247. output.push_back(i->data_);
  248. }
  249. EXPECT_THAT(output, ElementsAre(0, 1, 2, 3, 4, 5));
  250. }
  251. } // namespace
  252. } // namespace utils
  253. } // namespace spvtools