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  }