go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/collections/queue_test.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package collections
     9  
    10  import (
    11  	"testing"
    12  
    13  	. "go.charczuk.com/sdk/assert"
    14  )
    15  
    16  func okValue[K any](v K, _ bool) K {
    17  	return v
    18  }
    19  
    20  func ok[K any](_ K, ok bool) bool {
    21  	return ok
    22  }
    23  
    24  func Test_Queue(t *testing.T) {
    25  	buffer := new(Queue[int])
    26  
    27  	buffer.Push(1)
    28  	ItsEqual(t, 1, buffer.array[0], "the 0 index should hold the head value of 1")
    29  	ItsEqual(t, 1, buffer.Len())
    30  	ItsEqual(t, 1, okValue(buffer.Peek()))
    31  	ItsEqual(t, 1, okValue(buffer.PeekBack()))
    32  
    33  	buffer.Push(2)
    34  	ItsEqual(t, 2, buffer.Len())
    35  	ItsEqual(t, 1, okValue(buffer.Peek()))
    36  	ItsEqual(t, 2, okValue(buffer.PeekBack()))
    37  
    38  	buffer.Push(3)
    39  	ItsEqual(t, 3, buffer.Len())
    40  	ItsEqual(t, 1, okValue(buffer.Peek()))
    41  	ItsEqual(t, 3, okValue(buffer.PeekBack()))
    42  
    43  	buffer.Push(4)
    44  	ItsEqual(t, 4, buffer.Len())
    45  	ItsEqual(t, 1, okValue(buffer.Peek()))
    46  	ItsEqual(t, 4, okValue(buffer.PeekBack()))
    47  
    48  	buffer.Push(5)
    49  	ItsEqual(t, 5, buffer.Len())
    50  	ItsEqual(t, 1, okValue(buffer.Peek()))
    51  	ItsEqual(t, 5, okValue(buffer.PeekBack()))
    52  
    53  	buffer.Push(6)
    54  	ItsEqual(t, 6, buffer.Len())
    55  	ItsEqual(t, 1, okValue(buffer.Peek()))
    56  	ItsEqual(t, 6, okValue(buffer.PeekBack()))
    57  
    58  	buffer.Push(7)
    59  	ItsEqual(t, 7, buffer.Len())
    60  	ItsEqual(t, 1, okValue(buffer.Peek()))
    61  	ItsEqual(t, 7, okValue(buffer.PeekBack()))
    62  
    63  	buffer.Push(8)
    64  	ItsEqual(t, 8, buffer.Len())
    65  	ItsEqual(t, 1, okValue(buffer.Peek()))
    66  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
    67  
    68  	value, ok := buffer.Pop()
    69  	ItsEqual(t, 0, buffer.array[0], "we should zero elements that we pop")
    70  	ItsEqual(t, true, ok)
    71  	ItsEqual(t, 1, value)
    72  	ItsEqual(t, 7, buffer.Len())
    73  	ItsEqual(t, 2, okValue(buffer.Peek()))
    74  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
    75  
    76  	value, ok = buffer.Pop()
    77  	ItsEqual(t, true, ok)
    78  	ItsEqual(t, 2, value)
    79  	ItsEqual(t, 6, buffer.Len())
    80  	ItsEqual(t, 3, okValue(buffer.Peek()))
    81  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
    82  
    83  	value, ok = buffer.Pop()
    84  	ItsEqual(t, true, ok)
    85  	ItsEqual(t, 3, value)
    86  	ItsEqual(t, 5, buffer.Len())
    87  	ItsEqual(t, 4, okValue(buffer.Peek()))
    88  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
    89  
    90  	value, ok = buffer.Pop()
    91  	ItsEqual(t, true, ok)
    92  	ItsEqual(t, 4, value)
    93  	ItsEqual(t, 4, buffer.Len())
    94  	ItsEqual(t, 5, okValue(buffer.Peek()))
    95  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
    96  
    97  	value, ok = buffer.Pop()
    98  	ItsEqual(t, true, ok)
    99  	ItsEqual(t, 5, value)
   100  	ItsEqual(t, 3, buffer.Len())
   101  	ItsEqual(t, 6, okValue(buffer.Peek()))
   102  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
   103  
   104  	value, ok = buffer.Pop()
   105  	ItsEqual(t, true, ok)
   106  	ItsEqual(t, 6, value)
   107  	ItsEqual(t, 2, buffer.Len())
   108  	ItsEqual(t, 7, okValue(buffer.Peek()))
   109  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
   110  
   111  	value, ok = buffer.Pop()
   112  	ItsEqual(t, true, ok)
   113  	ItsEqual(t, 7, value)
   114  	ItsEqual(t, 1, buffer.Len())
   115  	ItsEqual(t, 8, okValue(buffer.Peek()))
   116  	ItsEqual(t, 8, okValue(buffer.PeekBack()))
   117  
   118  	value, ok = buffer.Pop()
   119  	ItsEqual(t, true, ok)
   120  	ItsEqual(t, 8, value)
   121  	ItsEqual(t, 0, buffer.Len())
   122  	ItsEqual(t, 0, okValue(buffer.Peek()))
   123  	ItsEqual(t, 0, okValue(buffer.PeekBack()))
   124  }
   125  
   126  func Test_Queue_Push(t *testing.T) {
   127  	q := new(Queue[int])
   128  
   129  	ItsEqual(t, 0, len(q.array))
   130  	ItsEqual(t, 0, q.Len())
   131  
   132  	q.Push(314)
   133  
   134  	ItsEqual(t, true, ok(q.Peek()))
   135  	ItsEqual(t, 314, okValue(q.Peek()))
   136  	ItsEqual(t, true, ok(q.PeekBack()))
   137  	ItsEqual(t, 314, okValue(q.PeekBack()))
   138  
   139  	ItsEqual(t, 0, q.head)
   140  	ItsEqual(t, 1, q.tail)
   141  	ItsEqual(t, 1, q.size)
   142  	ItsEqual(t, 4, len(q.array))
   143  	ItsEqual(t, 1, q.Len())
   144  
   145  	q.Push(1)
   146  	q.Push(2)
   147  	q.Push(3)
   148  
   149  	ItsEqual(t, 0, q.head)
   150  	ItsEqual(t, 0, q.tail)
   151  	ItsEqual(t, 4, q.size)
   152  	ItsEqual(t, 4, len(q.array))
   153  
   154  	ItsEqual(t, true, ok(q.Peek()))
   155  	ItsEqual(t, 314, okValue(q.Peek()))
   156  	ItsEqual(t, true, ok(q.PeekBack()))
   157  	ItsEqual(t, 3, okValue(q.PeekBack()))
   158  
   159  	ItsEqual(t, 0, q.head)
   160  	ItsEqual(t, 0, q.tail)
   161  	ItsEqual(t, 4, q.size)
   162  	ItsEqual(t, 4, len(q.array))
   163  }
   164  
   165  func Test_Queue_Pop_afterGrow(t *testing.T) {
   166  	q := new(Queue[int])
   167  	for x := 0; x < queueDefaultCapacity+1; x++ {
   168  		q.Push(x)
   169  	}
   170  	ItsEqual(t, queueDefaultCapacity+1, q.Len())
   171  
   172  	for x := 0; x < queueDefaultCapacity+1; x++ {
   173  		value, ok := q.Pop()
   174  		ItsEqual(t, true, ok)
   175  		ItsEqual(t, x, value)
   176  	}
   177  
   178  	value, ok := q.Pop()
   179  	ItsEqual(t, false, ok)
   180  	ItsEqual(t, 0, value)
   181  }
   182  
   183  func Test_Queue_PopBack(t *testing.T) {
   184  	buffer := new(Queue[int])
   185  
   186  	value, ok := buffer.PopBack()
   187  	ItsEqual(t, false, ok)
   188  	ItsEqual(t, 0, value)
   189  
   190  	buffer.Push(1)
   191  	buffer.Push(2)
   192  	buffer.Push(3)
   193  
   194  	value, ok = buffer.PopBack()
   195  	ItsEqual(t, true, ok)
   196  	ItsEqual(t, 0, buffer.array[2], "PopBack should zero the tail before returning")
   197  	ItsEqual(t, 3, value)
   198  	ItsEqual(t, 2, buffer.Len())
   199  
   200  	value, ok = buffer.PopBack()
   201  	ItsEqual(t, true, ok)
   202  	ItsEqual(t, 2, value)
   203  	ItsEqual(t, 1, buffer.Len())
   204  
   205  	value, ok = buffer.PopBack()
   206  	ItsEqual(t, true, ok)
   207  	ItsEqual(t, 1, value)
   208  	ItsEqual(t, 0, buffer.Len())
   209  
   210  	value, ok = buffer.PopBack()
   211  	ItsEqual(t, false, ok)
   212  	ItsEqual(t, 0, value)
   213  
   214  	// do a popback with tail == 0
   215  	q := new(Queue[int])
   216  
   217  	for x := 0; x < queueDefaultCapacity; x++ {
   218  		q.Push(x)
   219  	}
   220  	value, ok = q.PopBack()
   221  	ItsEqual(t, true, ok)
   222  	ItsEqual(t, queueDefaultCapacity-1, value)
   223  }
   224  
   225  func Test_Queue_Cap(t *testing.T) {
   226  	buffer := new(Queue[int])
   227  	for x := 0; x <= queueDefaultCapacity+1; x++ {
   228  		buffer.Push(x)
   229  	}
   230  
   231  	ItsEqual(t, 8, buffer.Cap())
   232  }
   233  
   234  func Test_Queue_Clear(t *testing.T) {
   235  	buffer := new(Queue[int])
   236  
   237  	// establish situation where head < tail
   238  	// but there are valid elements
   239  	for x := 0; x < 7; x++ {
   240  		buffer.Push(x)
   241  	}
   242  	ItsEqual(t, 7, buffer.Len())
   243  	buffer.Clear()
   244  
   245  	ItsEqual(t, 0, buffer.Len())
   246  	ItsEqual(t, 0, okValue(buffer.Peek()))
   247  	ItsEqual(t, 0, okValue(buffer.PeekBack()))
   248  
   249  	// get into situation where head > tail
   250  
   251  	// grow the buffer to 8 cap
   252  	for x := 0; x < 8; x++ {
   253  		buffer.Push(x)
   254  	}
   255  	// remove 5 elements
   256  	for x := 0; x < 5; x++ {
   257  		_, _ = buffer.Pop()
   258  	}
   259  	// push another 4 elements
   260  	// causing tail to wrap around
   261  	for x := 0; x < 4; x++ {
   262  		buffer.Push(x)
   263  	}
   264  	ItsEqual(t, 7, buffer.Len())
   265  	buffer.Clear()
   266  
   267  	ItsEqual(t, 0, buffer.Len())
   268  	ItsEqual(t, 0, okValue(buffer.Peek()))
   269  	ItsEqual(t, 0, okValue(buffer.PeekBack()))
   270  }
   271  
   272  func Test_Queue_Trim(t *testing.T) {
   273  	buffer := new(Queue[int])
   274  
   275  	for x := 0; x < 7; x++ {
   276  		buffer.Push(x)
   277  	}
   278  	ItsEqual(t, 7, buffer.Len())
   279  
   280  	buffer.Trim(5)
   281  	ItsEqual(t, 5, buffer.Len())
   282  
   283  	value, ok := buffer.PopBack()
   284  	ItsEqual(t, true, ok)
   285  	ItsEqual(t, 4, value)
   286  
   287  	value, ok = buffer.Pop()
   288  	ItsEqual(t, true, ok)
   289  	ItsEqual(t, 0, value)
   290  
   291  	ItsEqual(t, 3, buffer.Len())
   292  }
   293  
   294  func Test_Queue_Each(t *testing.T) {
   295  	buffer := new(Queue[int])
   296  
   297  	// each empty
   298  	var values []int
   299  	buffer.Each(func(v int) {
   300  		values = append(values, v)
   301  	})
   302  	ItsEqual(t, nil, values)
   303  	buffer.Clear()
   304  
   305  	// each where head < tail
   306  	for x := 1; x < queueDefaultCapacity; x++ {
   307  		buffer.Push(x)
   308  	}
   309  	values = nil
   310  	buffer.Each(func(v int) {
   311  		values = append(values, v)
   312  	})
   313  	ItsEqual(t, []int{1, 2, 3}, values)
   314  
   315  	buffer.Clear()
   316  
   317  	// each where head > tail
   318  
   319  	// 0, 1, 2, 3, 4, 5, 6, 7
   320  	// _, _, _, 3, 4, 5, 6, 7
   321  	// 8, 9, _, 3
   322  	for x := 0; x < 8; x++ {
   323  		buffer.Push(x)
   324  	}
   325  	for x := 0; x < 5; x++ {
   326  		_, _ = buffer.Pop()
   327  	}
   328  	for x := 0; x < 3; x++ {
   329  		buffer.Push(8 + x)
   330  	}
   331  
   332  	values = nil
   333  	buffer.Each(func(v int) {
   334  		values = append(values, v)
   335  	})
   336  	ItsEqual(t, []int{5, 6, 7, 8, 9, 10}, values)
   337  }
   338  
   339  func Test_Queue_ReverseEach(t *testing.T) {
   340  	buffer := new(Queue[int])
   341  
   342  	// reverseEach empty
   343  	var values []int
   344  	buffer.ReverseEach(func(v int) {
   345  		values = append(values, v)
   346  	})
   347  	ItsEqual(t, nil, values)
   348  	buffer.Clear()
   349  
   350  	// each where head < tail
   351  	for x := 1; x < queueDefaultCapacity; x++ {
   352  		buffer.Push(x)
   353  	}
   354  	values = nil
   355  	buffer.ReverseEach(func(v int) {
   356  		values = append(values, v)
   357  	})
   358  	ItsEqual(t, []int{3, 2, 1}, values)
   359  	buffer.Clear()
   360  
   361  	// 0, 1, 2, 3, 4, 5, 6, 7
   362  	// _, _, _, 3, 4, 5, 6, 7
   363  	// 8, 9, _, 3
   364  	for x := 0; x < 8; x++ {
   365  		buffer.Push(x)
   366  	}
   367  	for x := 0; x < 5; x++ {
   368  		_, _ = buffer.Pop()
   369  	}
   370  	for x := 0; x < 3; x++ {
   371  		buffer.Push(8 + x)
   372  	}
   373  
   374  	values = nil
   375  	buffer.ReverseEach(func(v int) {
   376  		values = append(values, v)
   377  	})
   378  	ItsEqual(t, []int{10, 9, 8, 7, 6, 5}, values)
   379  }
   380  
   381  func Test_Queue_setCapacity_empty(t *testing.T) {
   382  	q := new(Queue[int])
   383  
   384  	newCapacity := 8
   385  	q.setCapacity(newCapacity)
   386  	ItsEqual(t, 0, q.head)
   387  	ItsEqual(t, 0, q.tail)
   388  }
   389  
   390  func Test_Queue_setCapacity_default(t *testing.T) {
   391  	q := new(Queue[int])
   392  
   393  	for x := 0; x < queueDefaultCapacity-1; x++ {
   394  		q.Push(x)
   395  	}
   396  
   397  	newCapacity := 8
   398  	q.setCapacity(newCapacity)
   399  	ItsEqual(t, 0, q.head)
   400  	ItsEqual(t, queueDefaultCapacity-1, q.tail)
   401  	ItsEqual(t, 3, q.size)
   402  
   403  	ItsEqual(t, 0, q.array[0])
   404  	ItsEqual(t, 1, q.array[1])
   405  	ItsEqual(t, 2, q.array[2])
   406  	ItsEqual(t, 0, q.array[3])
   407  	ItsEqual(t, 0, q.array[4])
   408  	ItsEqual(t, 0, q.array[5])
   409  	ItsEqual(t, 0, q.array[6])
   410  	ItsEqual(t, 0, q.array[7])
   411  }
   412  
   413  func Test_Queue_setCapacity_wrap(t *testing.T) {
   414  	q := new(Queue[int])
   415  
   416  	for x := 0; x < queueDefaultCapacity+1; x++ {
   417  		q.Push(x)
   418  	}
   419  
   420  	newCapacity := 8
   421  	q.setCapacity(newCapacity)
   422  	ItsEqual(t, 0, q.head)
   423  	ItsEqual(t, 5, q.tail)
   424  	ItsEqual(t, 5, q.size)
   425  	ItsEqual(t, newCapacity, len(q.array))
   426  
   427  	ItsEqual(t, 0, q.array[0])
   428  	ItsEqual(t, 1, q.array[1])
   429  	ItsEqual(t, 2, q.array[2])
   430  	ItsEqual(t, 3, q.array[3])
   431  	ItsEqual(t, 4, q.array[4])
   432  	ItsEqual(t, 0, q.array[5])
   433  	ItsEqual(t, 0, q.array[6])
   434  	ItsEqual(t, 0, q.array[7])
   435  }
   436  
   437  func Test_Queue_setCapacity_trim(t *testing.T) {
   438  	q := new(Queue[int])
   439  
   440  	for x := 0; x < queueDefaultCapacity+1; x++ {
   441  		q.Push(x)
   442  	}
   443  
   444  	q.setCapacity(queueDefaultCapacity + 1)
   445  	ItsEqual(t, 0, q.head)
   446  	ItsEqual(t, 0, q.tail)
   447  	ItsEqual(t, 5, q.size)
   448  
   449  	ItsEqual(t, queueDefaultCapacity+1, len(q.array))
   450  	ItsEqual(t, 0, q.array[0])
   451  	ItsEqual(t, 1, q.array[1])
   452  	ItsEqual(t, 2, q.array[2])
   453  	ItsEqual(t, 3, q.array[3])
   454  	ItsEqual(t, 4, q.array[4])
   455  }