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