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 }