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  }