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