github.com/hamba/slices@v0.2.1-0.20220316050741-75c057d92699/except_test.go (about)

     1  package slices_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/hamba/slices"
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestExcept(t *testing.T) {
    11  	tests := []struct {
    12  		name string
    13  		a    interface{}
    14  		b    interface{}
    15  		want interface{}
    16  	}{
    17  		{
    18  			name: "string contains",
    19  			a:    []string{"foo", "bar", "baz", "bat"},
    20  			b:    []string{"bar", "baz", "test"},
    21  			want: []string{"foo", "bat"},
    22  		},
    23  		{
    24  			name: "int contains",
    25  			a:    []int{1, 2, 3, 4},
    26  			b:    []int{2, 3, 5},
    27  			want: []int{1, 4},
    28  		},
    29  		{
    30  			name: "int8 contains",
    31  			a:    []int8{1, 2, 3, 4},
    32  			b:    []int8{2, 3, 5},
    33  			want: []int8{1, 4},
    34  		},
    35  		{
    36  			name: "int16 contains",
    37  			a:    []int16{1, 2, 3, 4},
    38  			b:    []int16{2, 3, 5},
    39  			want: []int16{1, 4},
    40  		},
    41  		{
    42  			name: "int32 contains",
    43  			a:    []int32{1, 2, 3, 4},
    44  			b:    []int32{2, 3, 5},
    45  			want: []int32{1, 4},
    46  		},
    47  		{
    48  			name: "int64 contains",
    49  			a:    []int64{1, 2, 3, 4},
    50  			b:    []int64{2, 3, 5},
    51  			want: []int64{1, 4},
    52  		},
    53  		{
    54  			name: "uint contains",
    55  			a:    []uint{1, 2, 3, 4},
    56  			b:    []uint{2, 3, 5},
    57  			want: []uint{1, 4},
    58  		},
    59  		{
    60  			name: "uint8 contains",
    61  			a:    []uint8{1, 2, 3, 4},
    62  			b:    []uint8{2, 3, 5},
    63  			want: []uint8{1, 4},
    64  		},
    65  		{
    66  			name: "uint16 contains",
    67  			a:    []uint16{1, 2, 3, 4},
    68  			b:    []uint16{2, 3, 5},
    69  			want: []uint16{1, 4},
    70  		},
    71  		{
    72  			name: "uint32 contains",
    73  			a:    []uint32{1, 2, 3, 4},
    74  			b:    []uint32{2, 3, 5},
    75  			want: []uint32{1, 4},
    76  		},
    77  		{
    78  			name: "uint64 contains",
    79  			a:    []uint64{1, 2, 3, 4},
    80  			b:    []uint64{2, 3, 5},
    81  			want: []uint64{1, 4},
    82  		},
    83  		{
    84  			name: "float32 contains",
    85  			a:    []float32{1, 2, 3, 4},
    86  			b:    []float32{2, 3, 5},
    87  			want: []float32{1, 4},
    88  		},
    89  		{
    90  			name: "float64 contains",
    91  			a:    []float64{1, 2, 3, 4},
    92  			b:    []float64{2, 3, 5},
    93  			want: []float64{1, 4},
    94  		},
    95  	}
    96  
    97  	for _, tt := range tests {
    98  		t.Run(tt.name, func(t *testing.T) {
    99  			got := slices.Except(tt.a, tt.b)
   100  
   101  			assert.Equal(t, tt.want, got)
   102  		})
   103  	}
   104  }
   105  
   106  func TestExcept_ChecksSliceType(t *testing.T) {
   107  	assert.Panics(t, func() {
   108  		slices.Except("test", "test")
   109  	})
   110  }
   111  
   112  func TestExcept_ChecksValType(t *testing.T) {
   113  	assert.Panics(t, func() {
   114  		slices.Except([]string{"test"}, 1)
   115  	})
   116  }
   117  
   118  func BenchmarkExcept(b *testing.B) {
   119  	a := []string{"foo", "bar", "baz", "bat"}
   120  	c := []string{"bar", "baz", "test"}
   121  
   122  	b.ReportAllocs()
   123  	b.ResetTimer()
   124  	for i := 0; i < b.N; i++ {
   125  		slices.Except(a, c)
   126  	}
   127  }
   128  
   129  func except(slice, other []string) interface{} {
   130  	s := make([]string, len(slice))
   131  	copy(s, slice)
   132  	for i := 0; i < len(s); i++ {
   133  		for _, v := range other {
   134  			if v == s[i] {
   135  				s = append(s[:i], s[i+1:]...)
   136  				i--
   137  				break
   138  			}
   139  		}
   140  	}
   141  	return s
   142  }
   143  
   144  func BenchmarkExceptNative(b *testing.B) {
   145  	slice := []string{"foo", "bar", "baz", "bat"}
   146  	other := []string{"bar", "baz", "test"}
   147  
   148  	b.ReportAllocs()
   149  	b.ResetTimer()
   150  	for i := 0; i < b.N; i++ {
   151  		except(slice, other)
   152  	}
   153  }