github.com/zhongdalu/gf@v1.0.0/g/container/glist/glist_z_unit_test.go (about) 1 // Copyright 2019 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package glist 8 9 import ( 10 "container/list" 11 12 "github.com/zhongdalu/gf/g/test/gtest" 13 "github.com/zhongdalu/gf/g/util/gconv" 14 15 "testing" 16 ) 17 18 // 检查链表长度 19 func checkListLen(t *testing.T, l *List, len int) bool { 20 if n := l.Len(); n != len { 21 t.Errorf("l.Len() = %d, want %d", n, len) 22 return false 23 } 24 return true 25 } 26 27 // 检查指针地址 28 func checkListPointers(t *testing.T, l *List, es []*Element) { 29 if !checkListLen(t, l, len(es)) { 30 return 31 } 32 l.RLockFunc(func(list *list.List) { 33 for i, e := 0, l.list.Front(); i < list.Len(); i, e = i+1, e.Next() { 34 if e.Prev() != es[i].Prev() { 35 t.Errorf("list[%d].Prev = %p, want %p", i, e.Prev(), es[i].Prev()) 36 } 37 if e.Next() != es[i].Next() { 38 t.Errorf("list[%d].Next = %p, want %p", i, e.Next(), es[i].Next()) 39 } 40 } 41 }) 42 } 43 44 func TestBasic(t *testing.T) { 45 l := New() 46 l.PushFront(1) 47 l.PushFront(2) 48 if v := l.PopBack(); v != 1 { 49 t.Errorf("EXPECT %v, GOT %v", 1, v) 50 } else { 51 //fmt.Println(v) 52 } 53 if v := l.PopBack(); v != 2 { 54 t.Errorf("EXPECT %v, GOT %v", 2, v) 55 } else { 56 //fmt.Println(v) 57 } 58 if v := l.PopBack(); v != nil { 59 t.Errorf("EXPECT %v, GOT %v", nil, v) 60 } else { 61 //fmt.Println(v) 62 } 63 l.PushBack(1) 64 l.PushBack(2) 65 if v := l.PopFront(); v != 1 { 66 t.Errorf("EXPECT %v, GOT %v", 1, v) 67 } else { 68 //fmt.Println(v) 69 } 70 if v := l.PopFront(); v != 2 { 71 t.Errorf("EXPECT %v, GOT %v", 2, v) 72 } else { 73 //fmt.Println(v) 74 } 75 if v := l.PopFront(); v != nil { 76 t.Errorf("EXPECT %v, GOT %v", nil, v) 77 } else { 78 //fmt.Println(v) 79 } 80 } 81 82 func TestList(t *testing.T) { 83 l := New() 84 checkListPointers(t, l, []*Element{}) 85 86 // Single element list 87 e := l.PushFront("a") 88 checkListPointers(t, l, []*Element{e}) 89 l.MoveToFront(e) 90 checkListPointers(t, l, []*Element{e}) 91 l.MoveToBack(e) 92 checkListPointers(t, l, []*Element{e}) 93 l.Remove(e) 94 checkListPointers(t, l, []*Element{}) 95 96 // Bigger list 97 e2 := l.PushFront(2) 98 e1 := l.PushFront(1) 99 e3 := l.PushBack(3) 100 e4 := l.PushBack("banana") 101 checkListPointers(t, l, []*Element{e1, e2, e3, e4}) 102 103 l.Remove(e2) 104 checkListPointers(t, l, []*Element{e1, e3, e4}) 105 106 l.MoveToFront(e3) // move from middle 107 checkListPointers(t, l, []*Element{e3, e1, e4}) 108 109 l.MoveToFront(e1) 110 l.MoveToBack(e3) // move from middle 111 checkListPointers(t, l, []*Element{e1, e4, e3}) 112 113 l.MoveToFront(e3) // move from back 114 checkListPointers(t, l, []*Element{e3, e1, e4}) 115 l.MoveToFront(e3) // should be no-op 116 checkListPointers(t, l, []*Element{e3, e1, e4}) 117 118 l.MoveToBack(e3) // move from front 119 checkListPointers(t, l, []*Element{e1, e4, e3}) 120 l.MoveToBack(e3) // should be no-op 121 checkListPointers(t, l, []*Element{e1, e4, e3}) 122 123 e2 = l.InsertBefore(2, e1) // insert before front 124 checkListPointers(t, l, []*Element{e2, e1, e4, e3}) 125 l.Remove(e2) 126 e2 = l.InsertBefore(2, e4) // insert before middle 127 checkListPointers(t, l, []*Element{e1, e2, e4, e3}) 128 l.Remove(e2) 129 e2 = l.InsertBefore(2, e3) // insert before back 130 checkListPointers(t, l, []*Element{e1, e4, e2, e3}) 131 l.Remove(e2) 132 133 e2 = l.InsertAfter(2, e1) // insert after front 134 checkListPointers(t, l, []*Element{e1, e2, e4, e3}) 135 l.Remove(e2) 136 e2 = l.InsertAfter(2, e4) // insert after middle 137 checkListPointers(t, l, []*Element{e1, e4, e2, e3}) 138 l.Remove(e2) 139 e2 = l.InsertAfter(2, e3) // insert after back 140 checkListPointers(t, l, []*Element{e1, e4, e3, e2}) 141 l.Remove(e2) 142 143 // Check standard iteration. 144 sum := 0 145 for e := l.Front(); e != nil; e = e.Next() { 146 if i, ok := e.Value.(int); ok { 147 sum += i 148 } 149 } 150 if sum != 4 { 151 t.Errorf("sum over l = %d, want 4", sum) 152 } 153 154 // Clear all elements by iterating 155 var next *Element 156 for e := l.Front(); e != nil; e = next { 157 next = e.Next() 158 l.Remove(e) 159 } 160 checkListPointers(t, l, []*Element{}) 161 } 162 163 func checkList(t *testing.T, l *List, es []interface{}) { 164 if !checkListLen(t, l, len(es)) { 165 return 166 } 167 168 i := 0 169 for e := l.Front(); e != nil; e = e.Next() { 170 171 switch e.Value.(type) { 172 case int: 173 if le := e.Value.(int); le != es[i] { 174 t.Errorf("elt[%d].Value() = %v, want %v", i, le, es[i]) 175 } 176 // default string 177 default: 178 if le := e.Value.(string); le != es[i] { 179 t.Errorf("elt[%v].Value() = %v, want %v", i, le, es[i]) 180 } 181 } 182 183 i++ 184 } 185 186 //for e := l.Front(); e != nil; e = e.Next() { 187 // le := e.Value.(int) 188 // if le != es[i] { 189 // t.Errorf("elt[%d].Value() = %v, want %v", i, le, es[i]) 190 // } 191 // i++ 192 //} 193 } 194 195 func TestExtending(t *testing.T) { 196 l1 := New() 197 l2 := New() 198 199 l1.PushBack(1) 200 l1.PushBack(2) 201 l1.PushBack(3) 202 203 l2.PushBack(4) 204 l2.PushBack(5) 205 206 l3 := New() 207 l3.PushBackList(l1) 208 checkList(t, l3, []interface{}{1, 2, 3}) 209 l3.PushBackList(l2) 210 checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) 211 212 l3 = New() 213 l3.PushFrontList(l2) 214 checkList(t, l3, []interface{}{4, 5}) 215 l3.PushFrontList(l1) 216 checkList(t, l3, []interface{}{1, 2, 3, 4, 5}) 217 218 checkList(t, l1, []interface{}{1, 2, 3}) 219 checkList(t, l2, []interface{}{4, 5}) 220 221 l3 = New() 222 l3.PushBackList(l1) 223 checkList(t, l3, []interface{}{1, 2, 3}) 224 l3.PushBackList(l3) 225 checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) 226 227 l3 = New() 228 l3.PushFrontList(l1) 229 checkList(t, l3, []interface{}{1, 2, 3}) 230 l3.PushFrontList(l3) 231 checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3}) 232 233 l3 = New() 234 l1.PushBackList(l3) 235 checkList(t, l1, []interface{}{1, 2, 3}) 236 l1.PushFrontList(l3) 237 checkList(t, l1, []interface{}{1, 2, 3}) 238 } 239 240 func TestRemove(t *testing.T) { 241 l := New() 242 e1 := l.PushBack(1) 243 e2 := l.PushBack(2) 244 checkListPointers(t, l, []*Element{e1, e2}) 245 //e := l.Front() 246 //l.Remove(e) 247 //checkListPointers(t, l, []*Element{e2}) 248 //l.Remove(e) 249 //checkListPointers(t, l, []*Element{e2}) 250 } 251 252 func TestIssue4103(t *testing.T) { 253 l1 := New() 254 l1.PushBack(1) 255 l1.PushBack(2) 256 257 l2 := New() 258 l2.PushBack(3) 259 l2.PushBack(4) 260 261 e := l1.Front() 262 l2.Remove(e) // l2 should not change because e is not an element of l2 263 if n := l2.Len(); n != 2 { 264 t.Errorf("l2.Len() = %d, want 2", n) 265 } 266 267 l1.InsertBefore(8, e) 268 if n := l1.Len(); n != 3 { 269 t.Errorf("l1.Len() = %d, want 3", n) 270 } 271 } 272 273 func TestIssue6349(t *testing.T) { 274 l := New() 275 l.PushBack(1) 276 l.PushBack(2) 277 278 e := l.Front() 279 l.Remove(e) 280 if e.Value != 1 { 281 t.Errorf("e.value = %d, want 1", e.Value) 282 } 283 //if e.Next() != nil { 284 // t.Errorf("e.Next() != nil") 285 //} 286 //if e.Prev() != nil { 287 // t.Errorf("e.Prev() != nil") 288 //} 289 } 290 291 func TestMove(t *testing.T) { 292 l := New() 293 e1 := l.PushBack(1) 294 e2 := l.PushBack(2) 295 e3 := l.PushBack(3) 296 e4 := l.PushBack(4) 297 298 l.MoveAfter(e3, e3) 299 checkListPointers(t, l, []*Element{e1, e2, e3, e4}) 300 l.MoveBefore(e2, e2) 301 checkListPointers(t, l, []*Element{e1, e2, e3, e4}) 302 303 l.MoveAfter(e3, e2) 304 checkListPointers(t, l, []*Element{e1, e2, e3, e4}) 305 l.MoveBefore(e2, e3) 306 checkListPointers(t, l, []*Element{e1, e2, e3, e4}) 307 308 l.MoveBefore(e2, e4) 309 checkListPointers(t, l, []*Element{e1, e3, e2, e4}) 310 e2, e3 = e3, e2 311 312 l.MoveBefore(e4, e1) 313 checkListPointers(t, l, []*Element{e4, e1, e2, e3}) 314 e1, e2, e3, e4 = e4, e1, e2, e3 315 316 l.MoveAfter(e4, e1) 317 checkListPointers(t, l, []*Element{e1, e4, e2, e3}) 318 e2, e3, e4 = e4, e2, e3 319 320 l.MoveAfter(e2, e3) 321 checkListPointers(t, l, []*Element{e1, e3, e2, e4}) 322 e2, e3 = e3, e2 323 } 324 325 // Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List 326 func TestZeroList(t *testing.T) { 327 var l1 = New() 328 l1.PushFront(1) 329 checkList(t, l1, []interface{}{1}) 330 331 var l2 = New() 332 l2.PushBack(1) 333 checkList(t, l2, []interface{}{1}) 334 335 var l3 = New() 336 l3.PushFrontList(l1) 337 checkList(t, l3, []interface{}{1}) 338 339 var l4 = New() 340 l4.PushBackList(l2) 341 checkList(t, l4, []interface{}{1}) 342 } 343 344 // Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l. 345 func TestInsertBeforeUnknownMark(t *testing.T) { 346 l := New() 347 l.PushBack(1) 348 l.PushBack(2) 349 l.PushBack(3) 350 l.InsertBefore(1, new(Element)) 351 checkList(t, l, []interface{}{1, 2, 3}) 352 } 353 354 // Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l. 355 func TestInsertAfterUnknownMark(t *testing.T) { 356 l := New() 357 l.PushBack(1) 358 l.PushBack(2) 359 l.PushBack(3) 360 l.InsertAfter(1, new(Element)) 361 checkList(t, l, []interface{}{1, 2, 3}) 362 } 363 364 // Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l. 365 func TestMoveUnknownMark(t *testing.T) { 366 l1 := New() 367 e1 := l1.PushBack(1) 368 369 l2 := New() 370 e2 := l2.PushBack(2) 371 372 l1.MoveAfter(e1, e2) 373 checkList(t, l1, []interface{}{1}) 374 checkList(t, l2, []interface{}{2}) 375 376 l1.MoveBefore(e1, e2) 377 checkList(t, l1, []interface{}{1}) 378 checkList(t, l2, []interface{}{2}) 379 } 380 381 func TestList_RemoveAll(t *testing.T) { 382 l := New() 383 l.PushBack(1) 384 l.RemoveAll() 385 checkList(t, l, []interface{}{}) 386 l.PushBack(2) 387 checkList(t, l, []interface{}{2}) 388 } 389 390 func TestList_PushFronts(t *testing.T) { 391 l := New() 392 a1 := []interface{}{1, 2} 393 l.PushFronts(a1) 394 checkList(t, l, []interface{}{2, 1}) 395 a1 = []interface{}{3, 4, 5} 396 l.PushFronts(a1) 397 checkList(t, l, []interface{}{5, 4, 3, 2, 1}) 398 } 399 400 func TestList_PushBacks(t *testing.T) { 401 l := New() 402 a1 := []interface{}{1, 2} 403 l.PushBacks(a1) 404 checkList(t, l, []interface{}{1, 2}) 405 a1 = []interface{}{3, 4, 5} 406 l.PushBacks(a1) 407 checkList(t, l, []interface{}{1, 2, 3, 4, 5}) 408 } 409 410 func TestList_PopBacks(t *testing.T) { 411 gtest.Case(t, func() { 412 l := New() 413 a1 := []interface{}{1, 2, 3, 4} 414 a2 := []interface{}{"a", "c", "b", "e"} 415 l.PushFronts(a1) 416 i1 := l.PopBacks(2) 417 gtest.Assert(i1, []interface{}{1, 2}) 418 419 l.PushBacks(a2) //4.3,a,c,b,e 420 i1 = l.PopBacks(3) 421 gtest.Assert(i1, []interface{}{"e", "b", "c"}) 422 }) 423 } 424 425 func TestList_PopFronts(t *testing.T) { 426 l := New() 427 a1 := []interface{}{1, 2, 3, 4} 428 l.PushFronts(a1) 429 i1 := l.PopFronts(2) 430 gtest.Assert(i1, []interface{}{4, 3}) 431 gtest.Assert(l.Len(), 2) 432 } 433 434 func TestList_PopBackAll(t *testing.T) { 435 l := New() 436 a1 := []interface{}{1, 2, 3, 4} 437 l.PushFronts(a1) 438 i1 := l.PopBackAll() 439 gtest.Assert(i1, []interface{}{1, 2, 3, 4}) 440 gtest.Assert(l.Len(), 0) 441 442 } 443 444 func TestList_PopFrontAll(t *testing.T) { 445 l := New() 446 a1 := []interface{}{1, 2, 3, 4} 447 l.PushFronts(a1) 448 i1 := l.PopFrontAll() 449 gtest.Assert(i1, []interface{}{4, 3, 2, 1}) 450 gtest.Assert(l.Len(), 0) 451 } 452 453 func TestList_FrontAll(t *testing.T) { 454 l := New() 455 a1 := []interface{}{1, 2, 3, 4} 456 l.PushFronts(a1) 457 i1 := l.FrontAll() 458 gtest.Assert(i1, []interface{}{4, 3, 2, 1}) 459 gtest.Assert(l.Len(), 4) 460 } 461 462 func TestList_BackAll(t *testing.T) { 463 l := New() 464 a1 := []interface{}{1, 2, 3, 4} 465 l.PushFronts(a1) 466 i1 := l.BackAll() 467 gtest.Assert(i1, []interface{}{1, 2, 3, 4}) 468 gtest.Assert(l.Len(), 4) 469 } 470 471 func TestList_FrontValue(t *testing.T) { 472 l := New() 473 l2 := New() 474 a1 := []interface{}{1, 2, 3, 4} 475 l.PushFronts(a1) 476 i1 := l.FrontValue() 477 gtest.Assert(gconv.Int(i1), 4) 478 gtest.Assert(l.Len(), 4) 479 480 i1 = l2.FrontValue() 481 gtest.Assert(i1, nil) 482 } 483 484 func TestList_BackValue(t *testing.T) { 485 l := New() 486 l2 := New() 487 a1 := []interface{}{1, 2, 3, 4} 488 l.PushFronts(a1) 489 i1 := l.BackValue() 490 gtest.Assert(gconv.Int(i1), 1) 491 gtest.Assert(l.Len(), 4) 492 493 i1 = l2.FrontValue() 494 gtest.Assert(i1, nil) 495 496 } 497 498 func TestList_Back(t *testing.T) { 499 l := New() 500 a1 := []interface{}{1, 2, 3, 4} 501 l.PushFronts(a1) 502 e1 := l.Back() 503 gtest.Assert(e1.Value, 1) 504 gtest.Assert(l.Len(), 4) 505 } 506 507 func TestList_Size(t *testing.T) { 508 l := New() 509 a1 := []interface{}{1, 2, 3, 4} 510 l.PushFronts(a1) 511 gtest.Assert(l.Size(), 4) 512 l.PopFront() 513 gtest.Assert(l.Size(), 3) 514 } 515 516 func TestList_Removes(t *testing.T) { 517 l := New() 518 a1 := []interface{}{1, 2, 3, 4} 519 l.PushFronts(a1) 520 e1 := l.Back() 521 l.Removes([]*Element{e1}) 522 gtest.Assert(l.Len(), 3) 523 524 e2 := l.Back() 525 l.Removes([]*Element{e2}) 526 gtest.Assert(l.Len(), 2) 527 checkList(t, l, []interface{}{4, 3}) 528 529 } 530 531 func TestList_Clear(t *testing.T) { 532 l := New() 533 a1 := []interface{}{1, 2, 3, 4} 534 l.PushFronts(a1) 535 l.Clear() 536 gtest.Assert(l.Len(), 0) 537 } 538 539 func TestList_IteratorAsc(t *testing.T) { 540 l := New() 541 a1 := []interface{}{1, 2, 5, 6, 3, 4} 542 l.PushFronts(a1) 543 e1 := l.Back() 544 fun1 := func(e *Element) bool { 545 if gconv.Int(e1.Value) > 2 { 546 return true 547 } 548 return false 549 } 550 checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1}) 551 l.IteratorAsc(fun1) 552 checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1}) 553 } 554 555 func TestList_IteratorDesc(t *testing.T) { 556 l := New() 557 a1 := []interface{}{1, 2, 3, 4} 558 l.PushFronts(a1) 559 e1 := l.Back() 560 fun1 := func(e *Element) bool { 561 if gconv.Int(e1.Value) > 6 { 562 return true 563 } 564 return false 565 } 566 l.IteratorDesc(fun1) 567 gtest.Assert(l.Len(), 4) 568 checkList(t, l, []interface{}{4, 3, 2, 1}) 569 } 570 571 func TestList_Iterator(t *testing.T) { 572 l := New() 573 a1 := []interface{}{"a", "b", "c", "d", "e"} 574 l.PushFronts(a1) 575 e1 := l.Back() 576 fun1 := func(e *Element) bool { 577 if gconv.String(e1.Value) > "c" { 578 return true 579 } 580 return false 581 } 582 checkList(t, l, []interface{}{"e", "d", "c", "b", "a"}) 583 l.Iterator(fun1) 584 checkList(t, l, []interface{}{"e", "d", "c", "b", "a"}) 585 }