github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/list/list_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package list 6 7 import "testing" 8 9 func checkListLen(t *testing.T, l *List[int], len int) bool { 10 if n := l.Len(); n != len { 11 t.Errorf("l.Len() = %d, want %d", n, len) 12 return false 13 } 14 return true 15 } 16 17 func checkListPointers(t *testing.T, l *List[int], es []*Element[int]) { 18 root := &l.root 19 20 if !checkListLen(t, l, len(es)) { 21 return 22 } 23 24 // zero length lists must be the zero value or properly initialized (sentinel circle) 25 if len(es) == 0 { 26 if l.root.next != nil && l.root.next != root || l.root.prev != nil && l.root.prev != root { 27 t.Errorf("l.root.next = %p, l.root.prev = %p; both should both be nil or %p", l.root.next, l.root.prev, root) 28 } 29 return 30 } 31 // len(es) > 0 32 33 // check internal and external prev/next connections 34 for i, e := range es { 35 prev := root 36 Prev := (*Element[int])(nil) 37 if i > 0 { 38 prev = es[i-1] 39 Prev = prev 40 } 41 if p := e.prev; p != prev { 42 t.Errorf("elt[%d](%p).prev = %p, want %p", i, e, p, prev) 43 } 44 if p := e.Prev(); p != Prev { 45 t.Errorf("elt[%d](%p).Prev() = %p, want %p", i, e, p, Prev) 46 } 47 48 next := root 49 Next := (*Element[int])(nil) 50 if i < len(es)-1 { 51 next = es[i+1] 52 Next = next 53 } 54 if n := e.next; n != next { 55 t.Errorf("elt[%d](%p).next = %p, want %p", i, e, n, next) 56 } 57 if n := e.Next(); n != Next { 58 t.Errorf("elt[%d](%p).Next() = %p, want %p", i, e, n, Next) 59 } 60 } 61 } 62 63 func TestList(t *testing.T) { 64 l := New[int]() 65 checkListPointers(t, l, []*Element[int]{}) 66 67 // Single element list 68 e := l.PushFront(0) 69 checkListPointers(t, l, []*Element[int]{e}) 70 l.MoveToFront(e) 71 checkListPointers(t, l, []*Element[int]{e}) 72 l.MoveToBack(e) 73 checkListPointers(t, l, []*Element[int]{e}) 74 l.Remove(e) 75 checkListPointers(t, l, []*Element[int]{}) 76 77 // Bigger list 78 e2 := l.PushFront(2) 79 e1 := l.PushFront(1) 80 e3 := l.PushBack(3) 81 e4 := l.PushBack(4) 82 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 83 84 l.Remove(e2) 85 checkListPointers(t, l, []*Element[int]{e1, e3, e4}) 86 87 l.MoveToFront(e3) // move from middle 88 checkListPointers(t, l, []*Element[int]{e3, e1, e4}) 89 90 l.MoveToFront(e1) 91 l.MoveToBack(e3) // move from middle 92 checkListPointers(t, l, []*Element[int]{e1, e4, e3}) 93 94 l.MoveToFront(e3) // move from back 95 checkListPointers(t, l, []*Element[int]{e3, e1, e4}) 96 l.MoveToFront(e3) // should be no-op 97 checkListPointers(t, l, []*Element[int]{e3, e1, e4}) 98 99 l.MoveToBack(e3) // move from front 100 checkListPointers(t, l, []*Element[int]{e1, e4, e3}) 101 l.MoveToBack(e3) // should be no-op 102 checkListPointers(t, l, []*Element[int]{e1, e4, e3}) 103 104 e2 = l.InsertBefore(2, e1) // insert before front 105 checkListPointers(t, l, []*Element[int]{e2, e1, e4, e3}) 106 l.Remove(e2) 107 e2 = l.InsertBefore(2, e4) // insert before middle 108 checkListPointers(t, l, []*Element[int]{e1, e2, e4, e3}) 109 l.Remove(e2) 110 e2 = l.InsertBefore(2, e3) // insert before back 111 checkListPointers(t, l, []*Element[int]{e1, e4, e2, e3}) 112 l.Remove(e2) 113 114 e2 = l.InsertAfter(2, e1) // insert after front 115 checkListPointers(t, l, []*Element[int]{e1, e2, e4, e3}) 116 l.Remove(e2) 117 e2 = l.InsertAfter(2, e4) // insert after middle 118 checkListPointers(t, l, []*Element[int]{e1, e4, e2, e3}) 119 l.Remove(e2) 120 e2 = l.InsertAfter(2, e3) // insert after back 121 checkListPointers(t, l, []*Element[int]{e1, e4, e3, e2}) 122 l.Remove(e2) 123 124 // Check standard iteration. 125 sum := 0 126 for e := l.Front(); e != nil; e = e.Next() { 127 sum += e.Value 128 } 129 if sum != 8 { 130 t.Errorf("sum over l = %d, want 8", sum) 131 } 132 133 // Clear all elements by iterating 134 var next *Element[int] 135 for e := l.Front(); e != nil; e = next { 136 next = e.Next() 137 l.Remove(e) 138 } 139 checkListPointers(t, l, []*Element[int]{}) 140 } 141 142 func checkList(t *testing.T, l *List[int], es []int) { 143 if !checkListLen(t, l, len(es)) { 144 return 145 } 146 147 i := 0 148 for e := l.Front(); e != nil; e = e.Next() { 149 le := e.Value 150 if le != es[i] { 151 t.Errorf("elt[%d].Value = %v, want %v", i, le, es[i]) 152 } 153 i++ 154 } 155 } 156 157 func TestExtending(t *testing.T) { 158 l1 := New[int]() 159 l2 := New[int]() 160 161 l1.PushBack(1) 162 l1.PushBack(2) 163 l1.PushBack(3) 164 165 l2.PushBack(4) 166 l2.PushBack(5) 167 168 l3 := New[int]() 169 l3.PushBackList(l1) 170 checkList(t, l3, []int{1, 2, 3}) 171 l3.PushBackList(l2) 172 checkList(t, l3, []int{1, 2, 3, 4, 5}) 173 174 l3 = New[int]() 175 l3.PushFrontList(l2) 176 checkList(t, l3, []int{4, 5}) 177 l3.PushFrontList(l1) 178 checkList(t, l3, []int{1, 2, 3, 4, 5}) 179 180 checkList(t, l1, []int{1, 2, 3}) 181 checkList(t, l2, []int{4, 5}) 182 183 l3 = New[int]() 184 l3.PushBackList(l1) 185 checkList(t, l3, []int{1, 2, 3}) 186 l3.PushBackList(l3) 187 checkList(t, l3, []int{1, 2, 3, 1, 2, 3}) 188 189 l3 = New[int]() 190 l3.PushFrontList(l1) 191 checkList(t, l3, []int{1, 2, 3}) 192 l3.PushFrontList(l3) 193 checkList(t, l3, []int{1, 2, 3, 1, 2, 3}) 194 195 l3 = New[int]() 196 l1.PushBackList(l3) 197 checkList(t, l1, []int{1, 2, 3}) 198 l1.PushFrontList(l3) 199 checkList(t, l1, []int{1, 2, 3}) 200 } 201 202 func TestRemove(t *testing.T) { 203 l := New[int]() 204 e1 := l.PushBack(1) 205 e2 := l.PushBack(2) 206 checkListPointers(t, l, []*Element[int]{e1, e2}) 207 e := l.Front() 208 l.Remove(e) 209 checkListPointers(t, l, []*Element[int]{e2}) 210 l.Remove(e) 211 checkListPointers(t, l, []*Element[int]{e2}) 212 } 213 214 func TestIssue4103(t *testing.T) { 215 l1 := New[int]() 216 l1.PushBack(1) 217 l1.PushBack(2) 218 219 l2 := New[int]() 220 l2.PushBack(3) 221 l2.PushBack(4) 222 223 e := l1.Front() 224 l2.Remove(e) // l2 should not change because e is not an element of l2 225 if n := l2.Len(); n != 2 { 226 t.Errorf("l2.Len() = %d, want 2", n) 227 } 228 229 l1.InsertBefore(8, e) 230 if n := l1.Len(); n != 3 { 231 t.Errorf("l1.Len() = %d, want 3", n) 232 } 233 } 234 235 func TestIssue6349(t *testing.T) { 236 l := New[int]() 237 l.PushBack(1) 238 l.PushBack(2) 239 240 e := l.Front() 241 l.Remove(e) 242 if e.Value != 1 { 243 t.Errorf("e.value = %d, want 1", e.Value) 244 } 245 if e.Next() != nil { 246 t.Errorf("e.Next() != nil") 247 } 248 if e.Prev() != nil { 249 t.Errorf("e.Prev() != nil") 250 } 251 } 252 253 func TestMove(t *testing.T) { 254 l := New[int]() 255 e1 := l.PushBack(1) 256 e2 := l.PushBack(2) 257 e3 := l.PushBack(3) 258 e4 := l.PushBack(4) 259 260 l.MoveAfter(e3, e3) 261 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 262 l.MoveBefore(e2, e2) 263 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 264 265 l.MoveAfter(e3, e2) 266 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 267 l.MoveBefore(e2, e3) 268 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 269 270 l.MoveBefore(e2, e4) 271 checkListPointers(t, l, []*Element[int]{e1, e3, e2, e4}) 272 e2, e3 = e3, e2 273 274 l.MoveBefore(e4, e1) 275 checkListPointers(t, l, []*Element[int]{e4, e1, e2, e3}) 276 e1, e2, e3, e4 = e4, e1, e2, e3 277 278 l.MoveAfter(e4, e1) 279 checkListPointers(t, l, []*Element[int]{e1, e4, e2, e3}) 280 e2, e3, e4 = e4, e2, e3 281 282 l.MoveAfter(e2, e3) 283 checkListPointers(t, l, []*Element[int]{e1, e3, e2, e4}) 284 e2, e3 = e3, e2 285 } 286 287 // Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List 288 func TestZeroList(t *testing.T) { 289 var l1 = new(List[int]) 290 l1.PushFront(1) 291 checkList(t, l1, []int{1}) 292 293 var l2 = new(List[int]) 294 l2.PushBack(1) 295 checkList(t, l2, []int{1}) 296 297 var l3 = new(List[int]) 298 l3.PushFrontList(l1) 299 checkList(t, l3, []int{1}) 300 301 var l4 = new(List[int]) 302 l4.PushBackList(l2) 303 checkList(t, l4, []int{1}) 304 } 305 306 // Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l. 307 func TestInsertBeforeUnknownMark(t *testing.T) { 308 var l List[int] 309 l.PushBack(1) 310 l.PushBack(2) 311 l.PushBack(3) 312 l.InsertBefore(1, new(Element[int])) 313 checkList(t, &l, []int{1, 2, 3}) 314 } 315 316 // Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l. 317 func TestInsertAfterUnknownMark(t *testing.T) { 318 var l List[int] 319 l.PushBack(1) 320 l.PushBack(2) 321 l.PushBack(3) 322 l.InsertAfter(1, new(Element[int])) 323 checkList(t, &l, []int{1, 2, 3}) 324 } 325 326 // Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l. 327 func TestMoveUnknownMark(t *testing.T) { 328 var l1 List[int] 329 e1 := l1.PushBack(1) 330 331 var l2 List[int] 332 e2 := l2.PushBack(2) 333 334 l1.MoveAfter(e1, e2) 335 checkList(t, &l1, []int{1}) 336 checkList(t, &l2, []int{2}) 337 338 l1.MoveBefore(e1, e2) 339 checkList(t, &l1, []int{1}) 340 checkList(t, &l2, []int{2}) 341 }