github.com/prysmaticlabs/prysm@v1.4.4/shared/sliceutil/slice_test.go (about) 1 package sliceutil_test 2 3 import ( 4 "reflect" 5 "sort" 6 "testing" 7 8 types "github.com/prysmaticlabs/eth2-types" 9 "github.com/prysmaticlabs/prysm/shared/sliceutil" 10 ) 11 12 func TestSubsetUint64(t *testing.T) { 13 testCases := []struct { 14 setA []uint64 15 setB []uint64 16 out bool 17 }{ 18 {[]uint64{1}, []uint64{1, 2, 3, 4}, true}, 19 {[]uint64{1, 2, 3, 4}, []uint64{1, 2, 3, 4}, true}, 20 {[]uint64{1, 1}, []uint64{1, 2, 3, 4}, false}, 21 {[]uint64{}, []uint64{1}, true}, 22 {[]uint64{1}, []uint64{}, false}, 23 {[]uint64{1, 2, 3, 4, 5}, []uint64{1, 2, 3, 4}, false}, 24 } 25 for _, tt := range testCases { 26 result := sliceutil.SubsetUint64(tt.setA, tt.setB) 27 if result != tt.out { 28 t.Errorf("%v, got %v, want %v", tt.setA, result, tt.out) 29 } 30 } 31 } 32 33 func TestIntersectionUint64(t *testing.T) { 34 testCases := []struct { 35 setA []uint64 36 setB []uint64 37 setC []uint64 38 out []uint64 39 }{ 40 {[]uint64{2, 3, 5}, []uint64{3}, []uint64{3}, []uint64{3}}, 41 {[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{5}, []uint64{5}}, 42 {[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{3, 5}, []uint64{3, 5}}, 43 {[]uint64{2, 3, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{2, 3, 5}}, 44 {[]uint64{3, 2, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{2, 3, 5}}, 45 {[]uint64{3, 3, 5}, []uint64{5, 3, 2}, []uint64{3, 2, 5}, []uint64{3, 5}}, 46 {[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}}, 47 {[]uint64{2, 3, 5}, []uint64{}, []uint64{}, []uint64{}}, 48 {[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{}, []uint64{}}, 49 {[]uint64{2, 3}, []uint64{2, 3, 5}, []uint64{5}, []uint64{}}, 50 {[]uint64{2, 2, 2}, []uint64{2, 2, 2}, []uint64{}, []uint64{}}, 51 {[]uint64{}, []uint64{2, 3, 5}, []uint64{}, []uint64{}}, 52 {[]uint64{}, []uint64{}, []uint64{}, []uint64{}}, 53 {[]uint64{1}, []uint64{1}, []uint64{}, []uint64{}}, 54 {[]uint64{1, 1, 1}, []uint64{1, 1}, []uint64{1, 2, 3}, []uint64{1}}, 55 } 56 for _, tt := range testCases { 57 setA := append([]uint64{}, tt.setA...) 58 setB := append([]uint64{}, tt.setB...) 59 setC := append([]uint64{}, tt.setC...) 60 result := sliceutil.IntersectionUint64(setA, setB, setC) 61 sort.Slice(result, func(i, j int) bool { 62 return result[i] < result[j] 63 }) 64 if !reflect.DeepEqual(result, tt.out) { 65 t.Errorf("got %d, want %d", result, tt.out) 66 } 67 if !reflect.DeepEqual(setA, tt.setA) { 68 t.Errorf("slice modified, got %v, want %v", setA, tt.setA) 69 } 70 if !reflect.DeepEqual(setB, tt.setB) { 71 t.Errorf("slice modified, got %v, want %v", setB, tt.setB) 72 } 73 if !reflect.DeepEqual(setC, tt.setC) { 74 t.Errorf("slice modified, got %v, want %v", setC, tt.setC) 75 } 76 } 77 } 78 79 func TestIsSortedUint64(t *testing.T) { 80 testCases := []struct { 81 setA []uint64 82 out bool 83 }{ 84 {[]uint64{1, 2, 3}, true}, 85 {[]uint64{3, 1, 3}, false}, 86 {[]uint64{1}, true}, 87 {[]uint64{}, true}, 88 } 89 for _, tt := range testCases { 90 result := sliceutil.IsUint64Sorted(tt.setA) 91 if result != tt.out { 92 t.Errorf("got %v, want %v", result, tt.out) 93 } 94 } 95 } 96 97 func TestIntersectionInt64(t *testing.T) { 98 testCases := []struct { 99 setA []int64 100 setB []int64 101 setC []int64 102 out []int64 103 }{ 104 {[]int64{2, 3, 5}, []int64{3}, []int64{3}, []int64{3}}, 105 {[]int64{2, 3, 5}, []int64{3, 5}, []int64{5}, []int64{5}}, 106 {[]int64{2, 3, 5}, []int64{3, 5}, []int64{3, 5}, []int64{3, 5}}, 107 {[]int64{2, 3, 5}, []int64{5, 3, 2}, []int64{3, 2, 5}, []int64{2, 3, 5}}, 108 {[]int64{3, 2, 5}, []int64{5, 3, 2}, []int64{3, 2, 5}, []int64{2, 3, 5}}, 109 {[]int64{3, 3, 5}, []int64{5, 3, 2}, []int64{3, 2, 5}, []int64{3, 5}}, 110 {[]int64{2, 3, 5}, []int64{2, 3, 5}, []int64{2, 3, 5}, []int64{2, 3, 5}}, 111 {[]int64{2, 3, 5}, []int64{}, []int64{}, []int64{}}, 112 {[]int64{2, 3, 5}, []int64{2, 3, 5}, []int64{}, []int64{}}, 113 {[]int64{2, 3}, []int64{2, 3, 5}, []int64{5}, []int64{}}, 114 {[]int64{2, 2, 2}, []int64{2, 2, 2}, []int64{}, []int64{}}, 115 {[]int64{}, []int64{2, 3, 5}, []int64{}, []int64{}}, 116 {[]int64{}, []int64{}, []int64{}, []int64{}}, 117 {[]int64{1}, []int64{1}, []int64{}, []int64{}}, 118 {[]int64{1, 1, 1}, []int64{1, 1}, []int64{1, 2, 3}, []int64{1}}, 119 } 120 for _, tt := range testCases { 121 setA := append([]int64{}, tt.setA...) 122 setB := append([]int64{}, tt.setB...) 123 setC := append([]int64{}, tt.setC...) 124 result := sliceutil.IntersectionInt64(setA, setB, setC) 125 sort.Slice(result, func(i, j int) bool { 126 return result[i] < result[j] 127 }) 128 if !reflect.DeepEqual(result, tt.out) { 129 t.Errorf("got %d, want %d", result, tt.out) 130 } 131 if !reflect.DeepEqual(setA, tt.setA) { 132 t.Errorf("slice modified, got %v, want %v", setA, tt.setA) 133 } 134 if !reflect.DeepEqual(setB, tt.setB) { 135 t.Errorf("slice modified, got %v, want %v", setB, tt.setB) 136 } 137 if !reflect.DeepEqual(setC, tt.setC) { 138 t.Errorf("slice modified, got %v, want %v", setC, tt.setC) 139 } 140 } 141 } 142 143 func TestUnionUint64(t *testing.T) { 144 testCases := []struct { 145 setA []uint64 146 setB []uint64 147 out []uint64 148 }{ 149 {[]uint64{2, 3, 5}, []uint64{4, 6}, []uint64{2, 3, 5, 4, 6}}, 150 {[]uint64{2, 3, 5}, []uint64{3, 5}, []uint64{2, 3, 5}}, 151 {[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{2, 3, 5}}, 152 {[]uint64{2, 3, 5}, []uint64{}, []uint64{2, 3, 5}}, 153 {[]uint64{}, []uint64{2, 3, 5}, []uint64{2, 3, 5}}, 154 {[]uint64{}, []uint64{}, []uint64{}}, 155 {[]uint64{1}, []uint64{1}, []uint64{1}}, 156 } 157 for _, tt := range testCases { 158 result := sliceutil.UnionUint64(tt.setA, tt.setB) 159 if !reflect.DeepEqual(result, tt.out) { 160 t.Errorf("got %d, want %d", result, tt.out) 161 } 162 163 } 164 items := [][]uint64{ 165 {3, 4, 5}, 166 {6, 7, 8}, 167 {9, 10, 11}, 168 } 169 variadicResult := sliceutil.UnionUint64(items...) 170 want := []uint64{3, 4, 5, 6, 7, 8, 9, 10, 11} 171 if !reflect.DeepEqual(want, variadicResult) { 172 t.Errorf("Received %v, wanted %v", variadicResult, want) 173 } 174 } 175 176 func TestUnionInt64(t *testing.T) { 177 testCases := []struct { 178 setA []int64 179 setB []int64 180 out []int64 181 }{ 182 {[]int64{2, 3, 5}, []int64{4, 6}, []int64{2, 3, 5, 4, 6}}, 183 {[]int64{2, 3, 5}, []int64{3, 5}, []int64{2, 3, 5}}, 184 {[]int64{2, 3, 5}, []int64{2, 3, 5}, []int64{2, 3, 5}}, 185 {[]int64{2, 3, 5}, []int64{}, []int64{2, 3, 5}}, 186 {[]int64{}, []int64{2, 3, 5}, []int64{2, 3, 5}}, 187 {[]int64{}, []int64{}, []int64{}}, 188 {[]int64{1}, []int64{1}, []int64{1}}, 189 } 190 for _, tt := range testCases { 191 result := sliceutil.UnionInt64(tt.setA, tt.setB) 192 if !reflect.DeepEqual(result, tt.out) { 193 t.Errorf("got %d, want %d", result, tt.out) 194 } 195 } 196 items := [][]int64{ 197 {3, 4, 5}, 198 {6, 7, 8}, 199 {9, 10, 11}, 200 } 201 variadicResult := sliceutil.UnionInt64(items...) 202 want := []int64{3, 4, 5, 6, 7, 8, 9, 10, 11} 203 if !reflect.DeepEqual(want, variadicResult) { 204 t.Errorf("Received %v, wanted %v", variadicResult, want) 205 } 206 } 207 208 func TestCleanUint64(t *testing.T) { 209 testCases := []struct { 210 in []uint64 211 out []uint64 212 }{ 213 {[]uint64{2, 4, 4, 6, 6}, []uint64{2, 4, 6}}, 214 {[]uint64{3, 5, 5}, []uint64{3, 5}}, 215 {[]uint64{2, 2, 2}, []uint64{2}}, 216 {[]uint64{1, 4, 5, 9, 9}, []uint64{1, 4, 5, 9}}, 217 {[]uint64{}, []uint64{}}, 218 {[]uint64{1}, []uint64{1}}, 219 } 220 for _, tt := range testCases { 221 result := sliceutil.SetUint64(tt.in) 222 if !reflect.DeepEqual(result, tt.out) { 223 t.Errorf("got %d, want %d", result, tt.out) 224 } 225 } 226 } 227 228 func TestNotUint64(t *testing.T) { 229 testCases := []struct { 230 setA []uint64 231 setB []uint64 232 out []uint64 233 }{ 234 {[]uint64{4, 6}, []uint64{2, 3, 5, 4, 6}, []uint64{2, 3, 5}}, 235 {[]uint64{3, 5}, []uint64{2, 3, 5}, []uint64{2}}, 236 {[]uint64{2, 3, 5}, []uint64{2, 3, 5}, []uint64{}}, 237 {[]uint64{2}, []uint64{2, 3, 5}, []uint64{3, 5}}, 238 {[]uint64{}, []uint64{2, 3, 5}, []uint64{2, 3, 5}}, 239 {[]uint64{}, []uint64{}, []uint64{}}, 240 {[]uint64{1}, []uint64{1}, []uint64{}}, 241 } 242 for _, tt := range testCases { 243 result := sliceutil.NotUint64(tt.setA, tt.setB) 244 if !reflect.DeepEqual(result, tt.out) { 245 t.Errorf("got %d, want %d", result, tt.out) 246 } 247 } 248 } 249 250 func TestNotInt64(t *testing.T) { 251 testCases := []struct { 252 setA []int64 253 setB []int64 254 out []int64 255 }{ 256 {[]int64{4, 6}, []int64{2, 3, 5, 4, 6}, []int64{2, 3, 5}}, 257 {[]int64{3, 5}, []int64{2, 3, 5}, []int64{2}}, 258 {[]int64{2, 3, 5}, []int64{2, 3, 5}, []int64{}}, 259 {[]int64{2}, []int64{2, 3, 5}, []int64{3, 5}}, 260 {[]int64{}, []int64{2, 3, 5}, []int64{2, 3, 5}}, 261 {[]int64{}, []int64{}, []int64{}}, 262 {[]int64{1}, []int64{1}, []int64{}}, 263 } 264 for _, tt := range testCases { 265 result := sliceutil.NotInt64(tt.setA, tt.setB) 266 if !reflect.DeepEqual(result, tt.out) { 267 t.Errorf("got %d, want %d", result, tt.out) 268 } 269 } 270 } 271 272 func TestIsInUint64(t *testing.T) { 273 testCases := []struct { 274 a uint64 275 b []uint64 276 result bool 277 }{ 278 {0, []uint64{}, false}, 279 {0, []uint64{0}, true}, 280 {4, []uint64{2, 3, 5, 4, 6}, true}, 281 {100, []uint64{2, 3, 5, 4, 6}, false}, 282 } 283 for _, tt := range testCases { 284 result := sliceutil.IsInUint64(tt.a, tt.b) 285 if result != tt.result { 286 t.Errorf("IsIn(%d, %v)=%v, wanted: %v", 287 tt.a, tt.b, result, tt.result) 288 } 289 } 290 } 291 292 func TestIsInInt64(t *testing.T) { 293 testCases := []struct { 294 a int64 295 b []int64 296 result bool 297 }{ 298 {0, []int64{}, false}, 299 {0, []int64{0}, true}, 300 {4, []int64{2, 3, 5, 4, 6}, true}, 301 {100, []int64{2, 3, 5, 4, 6}, false}, 302 } 303 for _, tt := range testCases { 304 result := sliceutil.IsInInt64(tt.a, tt.b) 305 if result != tt.result { 306 t.Errorf("IsIn(%d, %v)=%v, wanted: %v", 307 tt.a, tt.b, result, tt.result) 308 } 309 } 310 } 311 312 func TestUnionByteSlices(t *testing.T) { 313 testCases := []struct { 314 setA [][]byte 315 setB [][]byte 316 out [][]byte 317 }{ 318 { 319 [][]byte{[]byte("hello"), []byte("world")}, 320 [][]byte{[]byte("world"), {}}, 321 [][]byte{[]byte("hello"), []byte("world"), {}}, 322 }, 323 { 324 [][]byte{[]byte("hello")}, 325 [][]byte{[]byte("hello")}, 326 [][]byte{[]byte("hello")}, 327 }, 328 } 329 for _, tt := range testCases { 330 result := sliceutil.UnionByteSlices(tt.setA, tt.setB) 331 if !reflect.DeepEqual(result, tt.out) { 332 t.Errorf("got %d, want %d", result, tt.out) 333 } 334 } 335 items := [][][]byte{ 336 { 337 {1, 2, 3}, 338 }, 339 { 340 {4, 5, 6}, 341 }, 342 { 343 {7, 8, 9}, 344 }, 345 } 346 variadicResult := sliceutil.UnionByteSlices(items...) 347 want := [][]byte{ 348 {1, 2, 3}, 349 {4, 5, 6}, 350 {7, 8, 9}, 351 } 352 if !reflect.DeepEqual(want, variadicResult) { 353 t.Errorf("Received %v, wanted %v", variadicResult, want) 354 } 355 } 356 357 func TestIntersectionByteSlices(t *testing.T) { 358 testCases := []struct { 359 name string 360 input [][][]byte 361 result [][]byte 362 }{ 363 { 364 name: "intersect with empty set", 365 input: [][][]byte{ 366 { 367 {1, 2, 3}, 368 {4, 5}, 369 }, 370 { 371 {1, 2}, 372 {4, 5}, 373 }, 374 {}, 375 }, 376 result: [][]byte{}, 377 }, 378 { 379 name: "ensure duplicate elements are removed in the resulting set", 380 input: [][][]byte{ 381 { 382 {1, 2, 3}, 383 {4, 5}, 384 {4, 5}, 385 }, 386 { 387 {1, 2}, 388 {4, 5}, 389 {4, 5}, 390 }, 391 { 392 {4, 5}, 393 {4, 5}, 394 }, 395 }, 396 result: [][]byte{{4, 5}}, 397 }, 398 { 399 name: "ensure no intersection returns an empty set", 400 input: [][][]byte{ 401 { 402 {1, 2, 3}, 403 {4, 5}, 404 }, 405 { 406 {1, 2}, 407 }, 408 { 409 {1, 2}, 410 }, 411 }, 412 result: [][]byte{}, 413 }, 414 { 415 name: "intersection between A and A should return A", 416 input: [][][]byte{ 417 { 418 {1, 2}, 419 }, 420 { 421 {1, 2}, 422 }, 423 { 424 {1, 2}, 425 }, 426 }, 427 result: [][]byte{{1, 2}}, 428 }, 429 } 430 for _, tt := range testCases { 431 t.Run(tt.name, func(t *testing.T) { 432 result := sliceutil.IntersectionByteSlices(tt.input...) 433 if !reflect.DeepEqual(result, tt.result) { 434 t.Errorf("IntersectionByteSlices(%v)=%v, wanted: %v", 435 tt.input, result, tt.result) 436 } 437 }) 438 } 439 t.Run("properly handle duplicates", func(t *testing.T) { 440 input := [][][]byte{ 441 {{1, 2}, {1, 2}}, 442 {{1, 2}, {1, 2}}, 443 {}, 444 } 445 result := sliceutil.IntersectionByteSlices(input...) 446 if !reflect.DeepEqual(result, [][]byte{}) { 447 t.Errorf("IntersectionByteSlices(%v)=%v, wanted: %v", input, result, [][]byte{}) 448 } 449 }) 450 } 451 452 func TestSplitCommaSeparated(t *testing.T) { 453 tests := []struct { 454 input []string 455 output []string 456 }{ 457 { 458 input: []string{"a,b", "c,d"}, 459 output: []string{"a", "b", "c", "d"}, 460 }, 461 { 462 input: []string{"a", "b,c,d"}, 463 output: []string{"a", "b", "c", "d"}, 464 }, 465 { 466 input: []string{"a", "b", "c"}, 467 output: []string{"a", "b", "c"}, 468 }, 469 } 470 471 for _, tt := range tests { 472 if result := sliceutil.SplitCommaSeparated(tt.input); !reflect.DeepEqual(result, tt.output) { 473 t.Errorf("SplitCommaSeparated(%v) = %v; wanted %v", tt.input, result, tt.output) 474 } 475 } 476 } 477 478 func TestSplitOffset_OK(t *testing.T) { 479 testCases := []struct { 480 listSize uint64 481 chunks uint64 482 index uint64 483 offset uint64 484 }{ 485 {30, 3, 2, 20}, 486 {1000, 10, 60, 6000}, 487 {2482, 10, 70, 17374}, 488 {323, 98, 56, 184}, 489 {273, 8, 6, 204}, 490 {3274, 98, 256, 8552}, 491 {23, 3, 2, 15}, 492 {23, 3, 9, 69}, 493 } 494 for _, tt := range testCases { 495 result := sliceutil.SplitOffset(tt.listSize, tt.chunks, tt.index) 496 if result != tt.offset { 497 t.Errorf("got %d, want %d", result, tt.offset) 498 } 499 500 } 501 } 502 503 func TestIntersectionSlot(t *testing.T) { 504 testCases := []struct { 505 setA []types.Slot 506 setB []types.Slot 507 setC []types.Slot 508 out []types.Slot 509 }{ 510 {[]types.Slot{2, 3, 5}, []types.Slot{3}, []types.Slot{3}, []types.Slot{3}}, 511 {[]types.Slot{2, 3, 5}, []types.Slot{3, 5}, []types.Slot{5}, []types.Slot{5}}, 512 {[]types.Slot{2, 3, 5}, []types.Slot{3, 5}, []types.Slot{3, 5}, []types.Slot{3, 5}}, 513 {[]types.Slot{2, 3, 5}, []types.Slot{5, 3, 2}, []types.Slot{3, 2, 5}, []types.Slot{2, 3, 5}}, 514 {[]types.Slot{3, 2, 5}, []types.Slot{5, 3, 2}, []types.Slot{3, 2, 5}, []types.Slot{2, 3, 5}}, 515 {[]types.Slot{3, 3, 5}, []types.Slot{5, 3, 2}, []types.Slot{3, 2, 5}, []types.Slot{3, 5}}, 516 {[]types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}}, 517 {[]types.Slot{2, 3, 5}, []types.Slot{}, []types.Slot{}, []types.Slot{}}, 518 {[]types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}, []types.Slot{}, []types.Slot{}}, 519 {[]types.Slot{2, 3}, []types.Slot{2, 3, 5}, []types.Slot{5}, []types.Slot{}}, 520 {[]types.Slot{2, 2, 2}, []types.Slot{2, 2, 2}, []types.Slot{}, []types.Slot{}}, 521 {[]types.Slot{}, []types.Slot{2, 3, 5}, []types.Slot{}, []types.Slot{}}, 522 {[]types.Slot{}, []types.Slot{}, []types.Slot{}, []types.Slot{}}, 523 {[]types.Slot{1}, []types.Slot{1}, []types.Slot{}, []types.Slot{}}, 524 {[]types.Slot{1, 1, 1}, []types.Slot{1, 1}, []types.Slot{1, 2, 3}, []types.Slot{1}}, 525 } 526 for _, tt := range testCases { 527 setA := append([]types.Slot{}, tt.setA...) 528 setB := append([]types.Slot{}, tt.setB...) 529 setC := append([]types.Slot{}, tt.setC...) 530 result := sliceutil.IntersectionSlot(setA, setB, setC) 531 sort.Slice(result, func(i, j int) bool { 532 return result[i] < result[j] 533 }) 534 if !reflect.DeepEqual(result, tt.out) { 535 t.Errorf("got %d, want %d", result, tt.out) 536 } 537 if !reflect.DeepEqual(setA, tt.setA) { 538 t.Errorf("slice modified, got %v, want %v", setA, tt.setA) 539 } 540 if !reflect.DeepEqual(setB, tt.setB) { 541 t.Errorf("slice modified, got %v, want %v", setB, tt.setB) 542 } 543 if !reflect.DeepEqual(setC, tt.setC) { 544 t.Errorf("slice modified, got %v, want %v", setC, tt.setC) 545 } 546 } 547 } 548 549 func TestNotSlot(t *testing.T) { 550 testCases := []struct { 551 setA []types.Slot 552 setB []types.Slot 553 out []types.Slot 554 }{ 555 {[]types.Slot{4, 6}, []types.Slot{2, 3, 5, 4, 6}, []types.Slot{2, 3, 5}}, 556 {[]types.Slot{3, 5}, []types.Slot{2, 3, 5}, []types.Slot{2}}, 557 {[]types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}, []types.Slot{}}, 558 {[]types.Slot{2}, []types.Slot{2, 3, 5}, []types.Slot{3, 5}}, 559 {[]types.Slot{}, []types.Slot{2, 3, 5}, []types.Slot{2, 3, 5}}, 560 {[]types.Slot{}, []types.Slot{}, []types.Slot{}}, 561 {[]types.Slot{1}, []types.Slot{1}, []types.Slot{}}, 562 } 563 for _, tt := range testCases { 564 result := sliceutil.NotSlot(tt.setA, tt.setB) 565 if !reflect.DeepEqual(result, tt.out) { 566 t.Errorf("got %d, want %d", result, tt.out) 567 } 568 } 569 } 570 571 func TestIsInSlots(t *testing.T) { 572 testCases := []struct { 573 a types.Slot 574 b []types.Slot 575 result bool 576 }{ 577 {0, []types.Slot{}, false}, 578 {0, []types.Slot{0}, true}, 579 {4, []types.Slot{2, 3, 5, 4, 6}, true}, 580 {100, []types.Slot{2, 3, 5, 4, 6}, false}, 581 } 582 for _, tt := range testCases { 583 result := sliceutil.IsInSlots(tt.a, tt.b) 584 if result != tt.result { 585 t.Errorf("IsIn(%d, %v)=%v, wanted: %v", 586 tt.a, tt.b, result, tt.result) 587 } 588 } 589 }