linked_list_unittest.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright (c) 2009 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "butil/basictypes.h"
  5. #include "butil/containers/linked_list.h"
  6. #include <gtest/gtest.h>
  7. namespace butil {
  8. namespace {
  9. class Node : public LinkNode<Node> {
  10. public:
  11. explicit Node(int id) : id_(id) {}
  12. int id() const { return id_; }
  13. private:
  14. int id_;
  15. };
  16. class MultipleInheritanceNodeBase {
  17. public:
  18. MultipleInheritanceNodeBase() : field_taking_up_space_(0) {}
  19. int field_taking_up_space_;
  20. };
  21. class MultipleInheritanceNode : public MultipleInheritanceNodeBase,
  22. public LinkNode<MultipleInheritanceNode> {
  23. public:
  24. MultipleInheritanceNode() {}
  25. };
  26. // Checks that when iterating |list| (either from head to tail, or from
  27. // tail to head, as determined by |forward|), we get back |node_ids|,
  28. // which is an array of size |num_nodes|.
  29. void ExpectListContentsForDirection(const LinkedList<Node>& list,
  30. int num_nodes, const int* node_ids, bool forward) {
  31. int i = 0;
  32. for (const LinkNode<Node>* node = (forward ? list.head() : list.tail());
  33. node != list.end();
  34. node = (forward ? node->next() : node->previous())) {
  35. ASSERT_LT(i, num_nodes);
  36. int index_of_id = forward ? i : num_nodes - i - 1;
  37. EXPECT_EQ(node_ids[index_of_id], node->value()->id());
  38. ++i;
  39. }
  40. EXPECT_EQ(num_nodes, i);
  41. }
  42. void ExpectListContents(const LinkedList<Node>& list,
  43. int num_nodes,
  44. const int* node_ids) {
  45. {
  46. SCOPED_TRACE("Iterating forward (from head to tail)");
  47. ExpectListContentsForDirection(list, num_nodes, node_ids, true);
  48. }
  49. {
  50. SCOPED_TRACE("Iterating backward (from tail to head)");
  51. ExpectListContentsForDirection(list, num_nodes, node_ids, false);
  52. }
  53. }
  54. TEST(LinkedList, Empty) {
  55. LinkedList<Node> list;
  56. EXPECT_EQ(list.end(), list.head());
  57. EXPECT_EQ(list.end(), list.tail());
  58. ExpectListContents(list, 0, NULL);
  59. }
  60. TEST(LinkedList, Append) {
  61. LinkedList<Node> list;
  62. ExpectListContents(list, 0, NULL);
  63. Node n1(1);
  64. list.Append(&n1);
  65. EXPECT_EQ(&n1, list.head());
  66. EXPECT_EQ(&n1, list.tail());
  67. {
  68. const int expected[] = {1};
  69. ExpectListContents(list, arraysize(expected), expected);
  70. }
  71. Node n2(2);
  72. list.Append(&n2);
  73. EXPECT_EQ(&n1, list.head());
  74. EXPECT_EQ(&n2, list.tail());
  75. {
  76. const int expected[] = {1, 2};
  77. ExpectListContents(list, arraysize(expected), expected);
  78. }
  79. Node n3(3);
  80. list.Append(&n3);
  81. EXPECT_EQ(&n1, list.head());
  82. EXPECT_EQ(&n3, list.tail());
  83. {
  84. const int expected[] = {1, 2, 3};
  85. ExpectListContents(list, arraysize(expected), expected);
  86. }
  87. }
  88. TEST(LinkedList, RemoveFromList) {
  89. LinkedList<Node> list;
  90. Node n1(1);
  91. Node n2(2);
  92. Node n3(3);
  93. Node n4(4);
  94. Node n5(5);
  95. list.Append(&n1);
  96. list.Append(&n2);
  97. list.Append(&n3);
  98. list.Append(&n4);
  99. list.Append(&n5);
  100. EXPECT_EQ(&n1, list.head());
  101. EXPECT_EQ(&n5, list.tail());
  102. {
  103. const int expected[] = {1, 2, 3, 4, 5};
  104. ExpectListContents(list, arraysize(expected), expected);
  105. }
  106. // Remove from the middle.
  107. n3.RemoveFromList();
  108. EXPECT_EQ(&n1, list.head());
  109. EXPECT_EQ(&n5, list.tail());
  110. {
  111. const int expected[] = {1, 2, 4, 5};
  112. ExpectListContents(list, arraysize(expected), expected);
  113. }
  114. // Remove from the tail.
  115. n5.RemoveFromList();
  116. EXPECT_EQ(&n1, list.head());
  117. EXPECT_EQ(&n4, list.tail());
  118. {
  119. const int expected[] = {1, 2, 4};
  120. ExpectListContents(list, arraysize(expected), expected);
  121. }
  122. // Remove from the head.
  123. n1.RemoveFromList();
  124. EXPECT_EQ(&n2, list.head());
  125. EXPECT_EQ(&n4, list.tail());
  126. {
  127. const int expected[] = {2, 4};
  128. ExpectListContents(list, arraysize(expected), expected);
  129. }
  130. // Empty the list.
  131. n2.RemoveFromList();
  132. n4.RemoveFromList();
  133. ExpectListContents(list, 0, NULL);
  134. EXPECT_EQ(list.end(), list.head());
  135. EXPECT_EQ(list.end(), list.tail());
  136. // Fill the list once again.
  137. list.Append(&n1);
  138. list.Append(&n2);
  139. list.Append(&n3);
  140. list.Append(&n4);
  141. list.Append(&n5);
  142. EXPECT_EQ(&n1, list.head());
  143. EXPECT_EQ(&n5, list.tail());
  144. {
  145. const int expected[] = {1, 2, 3, 4, 5};
  146. ExpectListContents(list, arraysize(expected), expected);
  147. }
  148. }
  149. TEST(LinkedList, InsertBefore) {
  150. LinkedList<Node> list;
  151. Node n1(1);
  152. Node n2(2);
  153. Node n3(3);
  154. Node n4(4);
  155. list.Append(&n1);
  156. list.Append(&n2);
  157. EXPECT_EQ(&n1, list.head());
  158. EXPECT_EQ(&n2, list.tail());
  159. {
  160. const int expected[] = {1, 2};
  161. ExpectListContents(list, arraysize(expected), expected);
  162. }
  163. n3.InsertBefore(&n2);
  164. EXPECT_EQ(&n1, list.head());
  165. EXPECT_EQ(&n2, list.tail());
  166. {
  167. const int expected[] = {1, 3, 2};
  168. ExpectListContents(list, arraysize(expected), expected);
  169. }
  170. n4.InsertBefore(&n1);
  171. EXPECT_EQ(&n4, list.head());
  172. EXPECT_EQ(&n2, list.tail());
  173. {
  174. const int expected[] = {4, 1, 3, 2};
  175. ExpectListContents(list, arraysize(expected), expected);
  176. }
  177. }
  178. TEST(LinkedList, InsertAfter) {
  179. LinkedList<Node> list;
  180. Node n1(1);
  181. Node n2(2);
  182. Node n3(3);
  183. Node n4(4);
  184. list.Append(&n1);
  185. list.Append(&n2);
  186. EXPECT_EQ(&n1, list.head());
  187. EXPECT_EQ(&n2, list.tail());
  188. {
  189. const int expected[] = {1, 2};
  190. ExpectListContents(list, arraysize(expected), expected);
  191. }
  192. n3.InsertAfter(&n2);
  193. EXPECT_EQ(&n1, list.head());
  194. EXPECT_EQ(&n3, list.tail());
  195. {
  196. const int expected[] = {1, 2, 3};
  197. ExpectListContents(list, arraysize(expected), expected);
  198. }
  199. n4.InsertAfter(&n1);
  200. EXPECT_EQ(&n1, list.head());
  201. EXPECT_EQ(&n3, list.tail());
  202. {
  203. const int expected[] = {1, 4, 2, 3};
  204. ExpectListContents(list, arraysize(expected), expected);
  205. }
  206. }
  207. TEST(LinkedList, MultipleInheritanceNode) {
  208. MultipleInheritanceNode node;
  209. EXPECT_EQ(&node, node.value());
  210. }
  211. TEST(LinkedList, EmptyListIsEmpty) {
  212. LinkedList<Node> list;
  213. EXPECT_TRUE(list.empty());
  214. }
  215. TEST(LinkedList, NonEmptyListIsNotEmpty) {
  216. LinkedList<Node> list;
  217. Node n(1);
  218. list.Append(&n);
  219. EXPECT_FALSE(list.empty());
  220. }
  221. TEST(LinkedList, EmptiedListIsEmptyAgain) {
  222. LinkedList<Node> list;
  223. Node n(1);
  224. list.Append(&n);
  225. n.RemoveFromList();
  226. EXPECT_TRUE(list.empty());
  227. }
  228. TEST(LinkedList, NodesCanBeReused) {
  229. LinkedList<Node> list1;
  230. LinkedList<Node> list2;
  231. Node n(1);
  232. list1.Append(&n);
  233. n.RemoveFromList();
  234. list2.Append(&n);
  235. EXPECT_EQ(list2.head()->value(), &n);
  236. }
  237. TEST(LinkedList, RemovedNodeHasNullNextPrevious) {
  238. LinkedList<Node> list;
  239. Node n(1);
  240. list.Append(&n);
  241. n.RemoveFromList();
  242. EXPECT_EQ(&n, n.next());
  243. EXPECT_EQ(&n, n.previous());
  244. }
  245. } // namespace
  246. } // namespace butil