github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/linkedlistqueue/linkedlistqueue_test.go (about)

     1  package linkedlistqueue
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  )
     9  
    10  func TestQueueEnqueue(t *testing.T) {
    11  	queue := New[int]()
    12  	if actualValue := queue.Empty(); actualValue != true {
    13  		t.Errorf("Got %v expected %v", actualValue, true)
    14  	}
    15  	queue.Enqueue(1)
    16  	queue.Enqueue(2)
    17  	queue.Enqueue(3)
    18  
    19  	if actualValue := queue.Values(); actualValue[0] != 1 || actualValue[1] != 2 || actualValue[2] != 3 {
    20  		t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
    21  	}
    22  	if actualValue := queue.Empty(); actualValue != false {
    23  		t.Errorf("Got %v expected %v", actualValue, false)
    24  	}
    25  	if actualValue := queue.Size(); actualValue != 3 {
    26  		t.Errorf("Got %v expected %v", actualValue, 3)
    27  	}
    28  	if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
    29  		t.Errorf("Got %v expected %v", actualValue, 1)
    30  	}
    31  }
    32  
    33  func TestQueuePeek(t *testing.T) {
    34  	queue := New[int]()
    35  	if actualValue, ok := queue.Peek(); actualValue != 0 || ok {
    36  		t.Errorf("Got %v expected %v", actualValue, nil)
    37  	}
    38  	queue.Enqueue(1)
    39  	queue.Enqueue(2)
    40  	queue.Enqueue(3)
    41  	if actualValue, ok := queue.Peek(); actualValue != 1 || !ok {
    42  		t.Errorf("Got %v expected %v", actualValue, 1)
    43  	}
    44  }
    45  
    46  func TestQueueDequeue(t *testing.T) {
    47  	queue := New[int]()
    48  	queue.Enqueue(1)
    49  	queue.Enqueue(2)
    50  	queue.Enqueue(3)
    51  	queue.Dequeue()
    52  	if actualValue, ok := queue.Peek(); actualValue != 2 || !ok {
    53  		t.Errorf("Got %v expected %v", actualValue, 2)
    54  	}
    55  	if actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {
    56  		t.Errorf("Got %v expected %v", actualValue, 2)
    57  	}
    58  	if actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {
    59  		t.Errorf("Got %v expected %v", actualValue, 3)
    60  	}
    61  	if actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {
    62  		t.Errorf("Got %v expected %v", actualValue, nil)
    63  	}
    64  	if actualValue := queue.Empty(); actualValue != true {
    65  		t.Errorf("Got %v expected %v", actualValue, true)
    66  	}
    67  	if actualValue := queue.Values(); len(actualValue) != 0 {
    68  		t.Errorf("Got %v expected %v", actualValue, "[]")
    69  	}
    70  }
    71  
    72  func TestQueueIteratorOnEmpty(t *testing.T) {
    73  	queue := New[int]()
    74  	it := queue.Iterator()
    75  	for it.Next() {
    76  		t.Errorf("Shouldn't iterate on empty queue")
    77  	}
    78  }
    79  
    80  func TestQueueIteratorNext(t *testing.T) {
    81  	queue := New[string]()
    82  	queue.Enqueue("a")
    83  	queue.Enqueue("b")
    84  	queue.Enqueue("c")
    85  
    86  	it := queue.Iterator()
    87  	count := 0
    88  	for it.Next() {
    89  		count++
    90  		index := it.Index()
    91  		value := it.Value()
    92  		switch index {
    93  		case 0:
    94  			if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
    95  				t.Errorf("Got %v expected %v", actualValue, expectedValue)
    96  			}
    97  		case 1:
    98  			if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
    99  				t.Errorf("Got %v expected %v", actualValue, expectedValue)
   100  			}
   101  		case 2:
   102  			if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
   103  				t.Errorf("Got %v expected %v", actualValue, expectedValue)
   104  			}
   105  		default:
   106  			t.Errorf("Too many")
   107  		}
   108  		if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
   109  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   110  		}
   111  	}
   112  	if actualValue, expectedValue := count, 3; actualValue != expectedValue {
   113  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
   114  	}
   115  
   116  	queue.Clear()
   117  	it = queue.Iterator()
   118  	for it.Next() {
   119  		t.Errorf("Shouldn't iterate on empty queue")
   120  	}
   121  }
   122  
   123  func TestQueueIteratorBegin(t *testing.T) {
   124  	queue := New[string]()
   125  	it := queue.Iterator()
   126  	it.Begin()
   127  	queue.Enqueue("a")
   128  	queue.Enqueue("b")
   129  	queue.Enqueue("c")
   130  	for it.Next() {
   131  	}
   132  	it.Begin()
   133  	it.Next()
   134  	if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
   135  		t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
   136  	}
   137  }
   138  
   139  func TestQueueIteratorFirst(t *testing.T) {
   140  	queue := New[string]()
   141  	it := queue.Iterator()
   142  	if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
   143  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
   144  	}
   145  	queue.Enqueue("a")
   146  	queue.Enqueue("b")
   147  	queue.Enqueue("c")
   148  	if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
   149  		t.Errorf("Got %v expected %v", actualValue, expectedValue)
   150  	}
   151  	if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
   152  		t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
   153  	}
   154  }
   155  
   156  func TestQueueIteratorNextTo(t *testing.T) {
   157  	// Sample seek function, i.e. string starting with "b"
   158  	seek := func(index int, value string) bool {
   159  		return strings.HasSuffix(value, "b")
   160  	}
   161  
   162  	// NextTo (empty)
   163  	{
   164  		queue := New[string]()
   165  		it := queue.Iterator()
   166  		for it.NextTo(seek) {
   167  			t.Errorf("Shouldn't iterate on empty queue")
   168  		}
   169  	}
   170  
   171  	// NextTo (not found)
   172  	{
   173  		queue := New[string]()
   174  		queue.Enqueue("xx")
   175  		queue.Enqueue("yy")
   176  		it := queue.Iterator()
   177  		for it.NextTo(seek) {
   178  			t.Errorf("Shouldn't iterate on empty queue")
   179  		}
   180  	}
   181  
   182  	// NextTo (found)
   183  	{
   184  		queue := New[string]()
   185  		queue.Enqueue("aa")
   186  		queue.Enqueue("bb")
   187  		queue.Enqueue("cc")
   188  		it := queue.Iterator()
   189  		it.Begin()
   190  		if !it.NextTo(seek) {
   191  			t.Errorf("Shouldn't iterate on empty queue")
   192  		}
   193  		if index, value := it.Index(), it.Value(); index != 1 || value != "bb" {
   194  			t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
   195  		}
   196  		if !it.Next() {
   197  			t.Errorf("Should go to first element")
   198  		}
   199  		if index, value := it.Index(), it.Value(); index != 2 || value != "cc" {
   200  			t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
   201  		}
   202  		if it.Next() {
   203  			t.Errorf("Should not go past last element")
   204  		}
   205  	}
   206  }
   207  
   208  func TestQueueSerialization(t *testing.T) {
   209  	queue := New[string]()
   210  	queue.Enqueue("a")
   211  	queue.Enqueue("b")
   212  	queue.Enqueue("c")
   213  
   214  	var err error
   215  	assert := func() {
   216  		if actualValue, expectedValue := queue.Values(), []string{"a", "b", "c"}; !reflect.DeepEqual(actualValue, expectedValue) {
   217  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   218  		}
   219  		if actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {
   220  			t.Errorf("Got %v expected %v", actualValue, expectedValue)
   221  		}
   222  		if err != nil {
   223  			t.Errorf("Got error %v", err)
   224  		}
   225  	}
   226  
   227  	assert()
   228  
   229  	bytes, err := queue.MarshalJSON()
   230  	assert()
   231  
   232  	err = queue.UnmarshalJSON(bytes)
   233  	assert()
   234  
   235  	bytes, err = json.Marshal([]interface{}{"a", "b", "c", queue})
   236  	if err != nil {
   237  		t.Errorf("Got error %v", err)
   238  	}
   239  
   240  	err = json.Unmarshal([]byte(`["1","2","3"]`), &queue)
   241  	if err != nil {
   242  		t.Errorf("Got error %v", err)
   243  	}
   244  }
   245  
   246  func TestQueueString(t *testing.T) {
   247  	c := New[int]()
   248  	c.Enqueue(1)
   249  	if !strings.HasPrefix(c.String(), "LinkedListQueue") {
   250  		t.Errorf("String should start with container name")
   251  	}
   252  }
   253  
   254  func benchmarkEnqueue[E int](b *testing.B, queue *Queue[E], size int) {
   255  	for i := 0; i < b.N; i++ {
   256  		for n := 0; n < size; n++ {
   257  			queue.Enqueue(E(n))
   258  		}
   259  	}
   260  }
   261  
   262  func benchmarkDequeue[E int](b *testing.B, queue *Queue[E], size int) {
   263  	for i := 0; i < b.N; i++ {
   264  		for n := 0; n < size; n++ {
   265  			queue.Dequeue()
   266  		}
   267  	}
   268  }
   269  
   270  func BenchmarkArrayQueueDequeue100(b *testing.B) {
   271  	b.StopTimer()
   272  	size := 100
   273  	queue := New[int]()
   274  	for n := 0; n < size; n++ {
   275  		queue.Enqueue(n)
   276  	}
   277  	b.StartTimer()
   278  	benchmarkDequeue(b, queue, size)
   279  }
   280  
   281  func BenchmarkArrayQueueDequeue1000(b *testing.B) {
   282  	b.StopTimer()
   283  	size := 1000
   284  	queue := New[int]()
   285  	for n := 0; n < size; n++ {
   286  		queue.Enqueue(n)
   287  	}
   288  	b.StartTimer()
   289  	benchmarkDequeue(b, queue, size)
   290  }
   291  
   292  func BenchmarkArrayQueueDequeue10000(b *testing.B) {
   293  	b.StopTimer()
   294  	size := 10000
   295  	queue := New[int]()
   296  	for n := 0; n < size; n++ {
   297  		queue.Enqueue(n)
   298  	}
   299  	b.StartTimer()
   300  	benchmarkDequeue(b, queue, size)
   301  }
   302  
   303  func BenchmarkArrayQueueDequeue100000(b *testing.B) {
   304  	b.StopTimer()
   305  	size := 100000
   306  	queue := New[int]()
   307  	for n := 0; n < size; n++ {
   308  		queue.Enqueue(n)
   309  	}
   310  	b.StartTimer()
   311  	benchmarkDequeue(b, queue, size)
   312  }
   313  
   314  func BenchmarkArrayQueueEnqueue100(b *testing.B) {
   315  	b.StopTimer()
   316  	size := 100
   317  	queue := New[int]()
   318  	b.StartTimer()
   319  	benchmarkEnqueue(b, queue, size)
   320  }
   321  
   322  func BenchmarkArrayQueueEnqueue1000(b *testing.B) {
   323  	b.StopTimer()
   324  	size := 1000
   325  	queue := New[int]()
   326  	for n := 0; n < size; n++ {
   327  		queue.Enqueue(n)
   328  	}
   329  	b.StartTimer()
   330  	benchmarkEnqueue(b, queue, size)
   331  }
   332  
   333  func BenchmarkArrayQueueEnqueue10000(b *testing.B) {
   334  	b.StopTimer()
   335  	size := 10000
   336  	queue := New[int]()
   337  	for n := 0; n < size; n++ {
   338  		queue.Enqueue(n)
   339  	}
   340  	b.StartTimer()
   341  	benchmarkEnqueue(b, queue, size)
   342  }
   343  
   344  func BenchmarkArrayQueueEnqueue100000(b *testing.B) {
   345  	b.StopTimer()
   346  	size := 100000
   347  	queue := New[int]()
   348  	for n := 0; n < size; n++ {
   349  		queue.Enqueue(n)
   350  	}
   351  	b.StartTimer()
   352  	benchmarkEnqueue(b, queue, size)
   353  }