github.com/MeteorsLiu/simpleMQ@v1.0.3/generic/list_test.go (about) 1 package generic 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 import "testing" 8 9 func checkListLen[T any](t *testing.T, l *List[T], 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 any](t *testing.T, l *List[T], es []*Element[T]) { 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[T])(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[T])(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(5) 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 checkListPointers(t, l, []*Element[int]{e1, e2, e3}) 82 83 l.Remove(e2) 84 checkListPointers(t, l, []*Element[int]{e1, e3}) 85 86 l.MoveToFront(e3) // move from middle 87 checkListPointers(t, l, []*Element[int]{e3, e1}) 88 89 l.MoveToFront(e1) 90 l.MoveToBack(e3) // move from middle 91 checkListPointers(t, l, []*Element[int]{e1, e3}) 92 93 l.MoveToFront(e3) // move from back 94 checkListPointers(t, l, []*Element[int]{e3, e1}) 95 l.MoveToFront(e3) // should be no-op 96 checkListPointers(t, l, []*Element[int]{e3, e1}) 97 98 l.MoveToBack(e3) // move from front 99 checkListPointers(t, l, []*Element[int]{e1, e3}) 100 l.MoveToBack(e3) // should be no-op 101 checkListPointers(t, l, []*Element[int]{e1, e3}) 102 103 e2 = l.InsertBefore(2, e1) // insert before front 104 checkListPointers(t, l, []*Element[int]{e2, e1, e3}) 105 l.Remove(e2) 106 e2 = l.InsertBefore(2, e3) // insert before back 107 checkListPointers(t, l, []*Element[int]{e1, e2, e3}) 108 l.Remove(e2) 109 110 e2 = l.InsertAfter(2, e1) // insert after front 111 checkListPointers(t, l, []*Element[int]{e1, e2, e3}) 112 l.Remove(e2) 113 e2 = l.InsertAfter(2, e3) // insert after back 114 checkListPointers(t, l, []*Element[int]{e1, e3, e2}) 115 l.Remove(e2) 116 117 // Check standard iteration. 118 sum := 0 119 for e := l.Front(); e != nil; e = e.Next() { 120 sum += e.Value 121 122 } 123 if sum != 4 { 124 t.Errorf("sum over l = %d, want 4", sum) 125 } 126 127 // Clear all elements by iterating 128 var next *Element[int] 129 for e := l.Front(); e != nil; e = next { 130 next = e.Next() 131 l.Remove(e) 132 } 133 checkListPointers(t, l, []*Element[int]{}) 134 } 135 136 func checkList[T comparable](t *testing.T, l *List[T], es []T) { 137 if !checkListLen(t, l, len(es)) { 138 return 139 } 140 141 i := 0 142 for e := l.Front(); e != nil; e = e.Next() { 143 le := e.Value 144 if le != es[i] { 145 t.Errorf("elt[%d].Value = %v, want %v", i, le, es[i]) 146 } 147 i++ 148 } 149 } 150 151 func TestExtending(t *testing.T) { 152 l1 := New[int]() 153 l2 := New[int]() 154 155 l1.PushBack(1) 156 l1.PushBack(2) 157 l1.PushBack(3) 158 159 l2.PushBack(4) 160 l2.PushBack(5) 161 162 l3 := New[int]() 163 l3.PushBackList(l1) 164 checkList(t, l3, []int{1, 2, 3}) 165 l3.PushBackList(l2) 166 checkList(t, l3, []int{1, 2, 3, 4, 5}) 167 168 l3 = New[int]() 169 l3.PushFrontList(l2) 170 checkList(t, l3, []int{4, 5}) 171 l3.PushFrontList(l1) 172 checkList(t, l3, []int{1, 2, 3, 4, 5}) 173 174 checkList(t, l1, []int{1, 2, 3}) 175 checkList(t, l2, []int{4, 5}) 176 177 l3 = New[int]() 178 l3.PushBackList(l1) 179 checkList(t, l3, []int{1, 2, 3}) 180 l3.PushBackList(l3) 181 checkList(t, l3, []int{1, 2, 3, 1, 2, 3}) 182 183 l3 = New[int]() 184 l3.PushFrontList(l1) 185 checkList(t, l3, []int{1, 2, 3}) 186 l3.PushFrontList(l3) 187 checkList(t, l3, []int{1, 2, 3, 1, 2, 3}) 188 189 l3 = New[int]() 190 l1.PushBackList(l3) 191 checkList(t, l1, []int{1, 2, 3}) 192 l1.PushFrontList(l3) 193 checkList(t, l1, []int{1, 2, 3}) 194 } 195 196 func TestRemove(t *testing.T) { 197 l := New[int]() 198 e1 := l.PushBack(1) 199 e2 := l.PushBack(2) 200 checkListPointers(t, l, []*Element[int]{e1, e2}) 201 e := l.Front() 202 l.Remove(e) 203 checkListPointers(t, l, []*Element[int]{e2}) 204 l.Remove(e) 205 checkListPointers(t, l, []*Element[int]{e2}) 206 } 207 208 func TestIssue4103(t *testing.T) { 209 l1 := New[int]() 210 l1.PushBack(1) 211 l1.PushBack(2) 212 213 l2 := New[int]() 214 l2.PushBack(3) 215 l2.PushBack(4) 216 217 e := l1.Front() 218 l2.Remove(e) // l2 should not change because e is not an element of l2 219 if n := l2.Len(); n != 2 { 220 t.Errorf("l2.Len() = %d, want 2", n) 221 } 222 223 l1.InsertBefore(8, e) 224 if n := l1.Len(); n != 3 { 225 t.Errorf("l1.Len() = %d, want 3", n) 226 } 227 } 228 229 func TestIssue6349(t *testing.T) { 230 l := New[int]() 231 l.PushBack(1) 232 l.PushBack(2) 233 234 e := l.Front() 235 l.Remove(e) 236 if e.Value != 1 { 237 t.Errorf("e.value = %d, want 1", e.Value) 238 } 239 if e.Next() != nil { 240 t.Errorf("e.Next() != nil") 241 } 242 if e.Prev() != nil { 243 t.Errorf("e.Prev() != nil") 244 } 245 } 246 247 func TestMove(t *testing.T) { 248 l := New[int]() 249 e1 := l.PushBack(1) 250 e2 := l.PushBack(2) 251 e3 := l.PushBack(3) 252 e4 := l.PushBack(4) 253 254 l.MoveAfter(e3, e3) 255 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 256 l.MoveBefore(e2, e2) 257 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 258 259 l.MoveAfter(e3, e2) 260 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 261 l.MoveBefore(e2, e3) 262 checkListPointers(t, l, []*Element[int]{e1, e2, e3, e4}) 263 264 l.MoveBefore(e2, e4) 265 checkListPointers(t, l, []*Element[int]{e1, e3, e2, e4}) 266 e2, e3 = e3, e2 267 268 l.MoveBefore(e4, e1) 269 checkListPointers(t, l, []*Element[int]{e4, e1, e2, e3}) 270 e1, e2, e3, e4 = e4, e1, e2, e3 271 272 l.MoveAfter(e4, e1) 273 checkListPointers(t, l, []*Element[int]{e1, e4, e2, e3}) 274 e2, e3, e4 = e4, e2, e3 275 276 l.MoveAfter(e2, e3) 277 checkListPointers(t, l, []*Element[int]{e1, e3, e2, e4}) 278 } 279 280 // Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List 281 func TestZeroList(t *testing.T) { 282 var l1 = new(List[int]) 283 l1.PushFront(1) 284 checkList(t, l1, []int{1}) 285 286 var l2 = new(List[int]) 287 l2.PushBack(1) 288 checkList(t, l2, []int{1}) 289 290 var l3 = new(List[int]) 291 l3.PushFrontList(l1) 292 checkList(t, l3, []int{1}) 293 294 var l4 = new(List[int]) 295 l4.PushBackList(l2) 296 checkList(t, l4, []int{1}) 297 } 298 299 // Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l. 300 func TestInsertBeforeUnknownMark(t *testing.T) { 301 var l List[int] 302 l.PushBack(1) 303 l.PushBack(2) 304 l.PushBack(3) 305 l.InsertBefore(1, new(Element[int])) 306 checkList(t, &l, []int{1, 2, 3}) 307 } 308 309 // Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l. 310 func TestInsertAfterUnknownMark(t *testing.T) { 311 var l List[int] 312 l.PushBack(1) 313 l.PushBack(2) 314 l.PushBack(3) 315 l.InsertAfter(1, new(Element[int])) 316 checkList(t, &l, []int{1, 2, 3}) 317 } 318 319 // Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l. 320 func TestMoveUnknownMark(t *testing.T) { 321 var l1 List[int] 322 e1 := l1.PushBack(1) 323 324 var l2 List[int] 325 e2 := l2.PushBack(2) 326 327 l1.MoveAfter(e1, e2) 328 checkList(t, &l1, []int{1}) 329 checkList(t, &l2, []int{2}) 330 331 l1.MoveBefore(e1, e2) 332 checkList(t, &l1, []int{1}) 333 checkList(t, &l2, []int{2}) 334 }