package help import ( "math" "reflect" "testing" "unsafe" ) func TestAll(t *testing.T) { input := []int{2, 4, 6, 8} r1 := From(input).All(func(i interface{}) bool { return i.(int)%2 == 0 }) r2 := From(input).All(func(i interface{}) bool { return i.(int)%2 != 0 }) if !r1 { t.Errorf("From(%v).All()=%v", input, r1) } if r2 { t.Errorf("From(%v).All()=%v", input, r2) } } func TestAllT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "AllT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).AllT(func(item int) int { return item + 2 }) }) } func TestAny(t *testing.T) { tests := []struct { input interface{} want bool }{ {[]int{1, 2, 2, 3, 1}, true}, {[9]int{1, 1, 1, 2, 1, 2, 3, 4, 2}, true}, {"sstr", true}, {[]int{}, false}, } for _, test := range tests { if r := From(test.input).Any(); r != test.want { t.Errorf("From(%v).Any()=%v expected %v", test.input, r, test.want) } } } func TestAnyWith(t *testing.T) { tests := []struct { input interface{} want bool }{ {[]int{1, 2, 2, 3, 1}, false}, {[9]int{1, 1, 1, 2, 1, 2, 3, 4, 2}, true}, {[]int{}, false}, } for _, test := range tests { if r := From(test.input).AnyWith(func(i interface{}) bool { return i.(int) == 4 }); r != test.want { t.Errorf("From(%v).Any()=%v expected %v", test.input, r, test.want) } } } func TestAnyWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "AnyWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).AnyWithT(func(item int) int { return item + 2 }) }) } func TestAverage(t *testing.T) { tests := []struct { input interface{} want float64 }{ {[]int{1, 2, 2, 3, 1}, 1.8}, {[5]uint{1, 2, 5, 7, 10}, 5.}, {[]float32{1., 1.}, 1.}, } for _, test := range tests { if r := From(test.input).Average(); r != test.want { t.Errorf("From(%v).Average()=%v expected %v", test.input, r, test.want) } } } func TestAverageForNaN(t *testing.T) { if r := From([]int{}).Average(); !math.IsNaN(r) { t.Errorf("From([]int{}).Average()=%v expected %v", r, math.NaN()) } } func TestContains(t *testing.T) { tests := []struct { input interface{} value interface{} want bool }{ {[]int{1, 2, 2, 3, 1}, 10, false}, {[5]uint{1, 2, 5, 7, 10}, uint(5), true}, {[]float32{}, 1., false}, } for _, test := range tests { if r := From(test.input).Contains(test.value); r != test.want { t.Errorf("From(%v).Contains(%v)=%v expected %v", test.input, test.value, r, test.want) } } } func TestCount(t *testing.T) { tests := []struct { input interface{} want int }{ {[]int{1, 2, 2, 3, 1}, 5}, {[7]uint{1, 2, 5, 7, 10, 12, 15}, 7}, {[]float32{}, 0}, } for _, test := range tests { if r := From(test.input).Count(); r != test.want { t.Errorf("From(%v).Count()=%v expected %v", test.input, r, test.want) } } } func TestCountWith(t *testing.T) { tests := []struct { input interface{} want int }{ {[]int{1, 2, 2, 3, 1}, 4}, {[]int{}, 0}, } for _, test := range tests { if r := From(test.input).CountWith(func(i interface{}) bool { return i.(int) <= 2 }); r != test.want { t.Errorf("From(%v).CountWith()=%v expected %v", test.input, r, test.want) } } } func TestCountWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "CountWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).CountWithT(func(item int) int { return item + 2 }) }) } func TestFirst(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, 1}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).First(); r != test.want { t.Errorf("From(%v).First()=%v expected %v", test.input, r, test.want) } } } func TestFirstWith(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, 3}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).FirstWith(func(i interface{}) bool { return i.(int) > 2 }); r != test.want { t.Errorf("From(%v).FirstWith()=%v expected %v", test.input, r, test.want) } } } func TestFirstWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "FirstWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).FirstWithT(func(item int) int { return item + 2 }) }) } func TestForEach(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[5]int{1, 2, 2, 35, 111}, []int{2, 4, 4, 70, 222}}, {[]int{}, []int{}}, } for _, test := range tests { output := []int{} From(test.input).ForEach(func(item interface{}) { output = append(output, item.(int)*2) }) if !reflect.DeepEqual(output, test.want) { t.Fatalf("From(%#v).ForEach()=%#v expected=%#v", test.input, output, test.want) } } } func TestForEachT_PanicWhenActionFnIsInvalid(t *testing.T) { mustPanicWithError(t, "ForEachT: parameter [actionFn] has a invalid function signature. Expected: 'func(T)', actual: 'func(int,int)'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ForEachT(func(item, idx int) { item = item + 2 }) }) } func TestForEachIndexed(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[5]int{1, 2, 2, 35, 111}, []int{1, 3, 4, 38, 115}}, {[]int{}, []int{}}, } for _, test := range tests { output := []int{} From(test.input).ForEachIndexed(func(index int, item interface{}) { output = append(output, item.(int)+index) }) if !reflect.DeepEqual(output, test.want) { t.Fatalf("From(%#v).ForEachIndexed()=%#v expected=%#v", test.input, output, test.want) } } } func TestForEachIndexedT_PanicWhenActionFnIsInvalid(t *testing.T) { mustPanicWithError(t, "ForEachIndexedT: parameter [actionFn] has a invalid function signature. Expected: 'func(int,T)', actual: 'func(int)'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ForEachIndexedT(func(item int) { item = item + 2 }) }) } func TestLast(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, 1}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).Last(); r != test.want { t.Errorf("From(%v).Last()=%v expected %v", test.input, r, test.want) } } } func TestLastWith(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1, 4, 2, 5, 1, 1}, 5}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).LastWith(func(i interface{}) bool { return i.(int) > 2 }); r != test.want { t.Errorf("From(%v).LastWith()=%v expected %v", test.input, r, test.want) } } } func TestLastWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "LastWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).LastWithT(func(item int) int { return item + 2 }) }) } func TestMax(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, 3}, {[]int{1}, 1}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).Max(); r != test.want { t.Errorf("From(%v).Max()=%v expected %v", test.input, r, test.want) } } } func TestMin(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 0}, 0}, {[]int{1}, 1}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).Min(); r != test.want { t.Errorf("From(%v).Min()=%v expected %v", test.input, r, test.want) } } } func TestResults(t *testing.T) { input := []int{1, 2, 3} want := []interface{}{1, 2, 3} if r := From(input).Results(); !reflect.DeepEqual(r, want) { t.Errorf("From(%v).Raw()=%v expected %v", input, r, want) } } func TestSequenceEqual(t *testing.T) { tests := []struct { input interface{} input2 interface{} want bool }{ {[]int{1, 2, 2, 3, 1}, []int{4, 6}, false}, {[]int{1, -1, 100}, []int{1, -1, 100}, true}, {[]int{}, []int{}, true}, } for _, test := range tests { if r := From(test.input).SequenceEqual(From(test.input2)); r != test.want { t.Errorf("From(%v).SequenceEqual(%v)=%v expected %v", test.input, test.input2, r, test.want) } } } func TestSingle(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, nil}, {[]int{1}, 1}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).Single(); r != test.want { t.Errorf("From(%v).Single()=%v expected %v", test.input, r, test.want) } } } func TestSingleWith(t *testing.T) { tests := []struct { input interface{} want interface{} }{ {[]int{1, 2, 2, 3, 1}, 3}, {[]int{1, 1, 1}, nil}, {[]int{5, 1, 1, 10, 2, 2}, nil}, {[]int{}, nil}, } for _, test := range tests { if r := From(test.input).SingleWith(func(i interface{}) bool { return i.(int) > 2 }); r != test.want { t.Errorf("From(%v).SingleWith()=%v expected %v", test.input, r, test.want) } } } func TestSingleWithT_PanicWhenPredicateFnIsInvalid(t *testing.T) { mustPanicWithError(t, "SingleWithT: parameter [predicateFn] has a invalid function signature. Expected: 'func(T)bool', actual: 'func(int)int'", func() { From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).SingleWithT(func(item int) int { return item + 2 }) }) } func TestSumInts(t *testing.T) { tests := []struct { input interface{} want int64 }{ {[]int{1, 2, 2, 3, 1}, 9}, {[]int{1}, 1}, {[]int{}, 0}, } for _, test := range tests { if r := From(test.input).SumInts(); r != test.want { t.Errorf("From(%v).SumInts()=%v expected %v", test.input, r, test.want) } } } func TestSumUInts(t *testing.T) { tests := []struct { input interface{} want uint64 }{ {[]uint{1, 2, 2, 3, 1}, 9}, {[]uint{1}, 1}, {[]uint{}, 0}, } for _, test := range tests { if r := From(test.input).SumUInts(); r != test.want { t.Errorf("From(%v).SumInts()=%v expected %v", test.input, r, test.want) } } } func TestSumFloats(t *testing.T) { tests := []struct { input interface{} want float64 }{ {[]float32{1., 2., 2., 3., 1.}, 9.}, {[]float64{1.}, 1.}, {[]float32{}, 0.}, } for _, test := range tests { if r := From(test.input).SumFloats(); r != test.want { t.Errorf("From(%v).SumFloats()=%v expected %v", test.input, r, test.want) } } } func TestToChannel(t *testing.T) { c := make(chan interface{}) input := []int{1, 2, 3, 4, 5} go func() { From(input).ToChannel(c) }() result := []int{} for value := range c { result = append(result, value.(int)) } if !reflect.DeepEqual(result, input) { t.Errorf("From(%v).ToChannel()=%v expected %v", input, result, input) } } func TestToChannelT(t *testing.T) { c := make(chan string) input := []string{"1", "2", "3", "4", "5"} go From(input).ToChannelT(c) result := []string{} for value := range c { result = append(result, value) } if !reflect.DeepEqual(result, input) { t.Errorf("From(%v).ToChannelT()=%v expected %v", input, result, input) } } func TestToMap(t *testing.T) { input := make(map[int]bool) input[1] = true input[2] = false input[3] = true result := make(map[int]bool) From(input).ToMap(&result) if !reflect.DeepEqual(result, input) { t.Errorf("From(%v).ToMap()=%v expected %v", input, result, input) } } func TestToMapBy(t *testing.T) { input := make(map[int]bool) input[1] = true input[2] = false input[3] = true result := make(map[int]bool) From(input).ToMapBy(&result, func(i interface{}) interface{} { return i.(KeyValue).Key }, func(i interface{}) interface{} { return i.(KeyValue).Value }) if !reflect.DeepEqual(result, input) { t.Errorf("From(%v).ToMapBy()=%v expected %v", input, result, input) } } func TestToMapByT_PanicWhenKeySelectorFnIsInvalid(t *testing.T) { mustPanicWithError(t, "ToMapByT: parameter [keySelectorFn] has a invalid function signature. Expected: 'func(T)T', actual: 'func(int,int)int'", func() { result := make(map[int]bool) From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ToMapByT( &result, func(item, j int) int { return item + 2 }, func(item int) int { return item + 2 }, ) }) } func TestToMapByT_PanicWhenValueSelectorFnIsInvalid(t *testing.T) { mustPanicWithError(t, "ToMapByT: parameter [valueSelectorFn] has a invalid function signature. Expected: 'func(T)T', actual: 'func(int,int)int'", func() { result := make(map[int]bool) From([]int{1, 1, 1, 2, 1, 2, 3, 4, 2}).ToMapByT( &result, func(item int) int { return item + 2 }, func(item, j int) int { return item + 2 }, ) }) } func TestToSlice(t *testing.T) { tests := []struct { input []int output []int want []int wantedOutputCap int outputIsANewSlice bool }{ // output is nil slice { []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 16, true}, // output is empty slice (cap=0) { []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, []int{}, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 16, true}, // ToSlice() overwrites existing elements and reslices. {[]int{1, 2, 3}, []int{99, 98, 97, 96, 95}, []int{1, 2, 3}, 5, false}, // cap(out)>len(result): we get the same slice, resliced. cap unchanged. {[]int{1, 2, 3, 4, 5}, make([]int, 0, 11), []int{1, 2, 3, 4, 5}, 11, false}, // cap(out)==len(result): we get the same slice, cap unchanged. {[]int{1, 2, 3, 4, 5}, make([]int, 0, 5), []int{1, 2, 3, 4, 5}, 5, false}, // cap(out) 52 -> 104) {make([]int, 100), make([]int, 0, 26), make([]int, 100), 104, true}, // len(out) > len(result): we get the same slice with len(out)=len(result) and cap unchanged: cap(out')==cap(out) {[]int{1, 2, 3, 4, 5}, make([]int, 0, 50), []int{1, 2, 3, 4, 5}, 50, false}, } for c, test := range tests { initialOutputValue := test.output From(test.input).ToSlice(&test.output) modifiedOutputValue := test.output // test slice values if !reflect.DeepEqual(test.output, test.want) { t.Fatalf("case #%d: From(%#v).ToSlice()=%#v expected=%#v", c, test.input, test.output, test.want) } // test capacity of output slice if cap(test.output) != test.wantedOutputCap { t.Fatalf("case #%d: cap(output)=%d expected=%d", c, cap(test.output), test.wantedOutputCap) } // test if a new slice is allocated inPtr := (*reflect.SliceHeader)(unsafe.Pointer(&initialOutputValue)).Data outPtr := (*reflect.SliceHeader)(unsafe.Pointer(&modifiedOutputValue)).Data isNewSlice := inPtr != outPtr if isNewSlice != test.outputIsANewSlice { t.Fatalf("case #%d: isNewSlice=%v (in=0x%X out=0x%X) expected=%v", c, isNewSlice, inPtr, outPtr, test.outputIsANewSlice) } } }