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  }