From e432001e5c5433352d892a8d8490aa1a29c8af93 Mon Sep 17 00:00:00 2001 From: ya-sato Date: Tue, 5 Mar 2019 16:49:10 +0900 Subject: [PATCH] Add DropLeft And Right #40 #41 (#51) --- internal/drop/dispatcher.go | 6 ++- internal/drop/dispatcher_test.go | 77 +++++++++++++++++++------------- internal/drop/drop.go | 48 +++++++++++++++++--- stream/dropLeft.go | 42 +++++++++++++++++ stream/dropLeft_test.go | 50 +++++++++++++++++++++ stream/dropRight.go | 42 +++++++++++++++++ stream/dropRight_test.go | 69 ++++++++++++++++++++++++++++ stream/drop_test.go | 22 ++++++++- 8 files changed, 317 insertions(+), 39 deletions(-) create mode 100644 stream/dropLeft.go create mode 100644 stream/dropLeft_test.go create mode 100644 stream/dropRight.go create mode 100644 stream/dropRight_test.go diff --git a/internal/drop/dispatcher.go b/internal/drop/dispatcher.go index 3e59f36..2e6de23 100644 --- a/internal/drop/dispatcher.go +++ b/internal/drop/dispatcher.go @@ -35,10 +35,12 @@ var dispatcher = map[string]dispatchFunction{ "*float64": dropPtrFloat64, } -func dispatch(items reflect.Value, itemValue interface{}, info *dropInfo) (bool, interface{}) { +func dispatch(items reflect.Value, itemValue interface{}, info *dropInfo, option Option) (bool, interface{}) { input := (*info.itemType).String() if fnVal, ok := dispatcher[input]; ok { - return true, fnVal(items, itemValue) + if option == None { + return true, fnVal(items, itemValue) + } } return false, nil } diff --git a/internal/drop/dispatcher_test.go b/internal/drop/dispatcher_test.go index dcb530b..baed892 100644 --- a/internal/drop/dispatcher_test.go +++ b/internal/drop/dispatcher_test.go @@ -1,16 +1,17 @@ package drop import ( - "github.com/stretchr/testify/assert" - "github.com/wesovilabs/koazee/utils" "reflect" "testing" + + "github.com/stretchr/testify/assert" + "github.com/wesovilabs/koazee/utils" ) func Test_dropString(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayString[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayString), utils.ArrayString[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayString), utils.ArrayString[1], info, None) assert.True(t, found) for index := range output.([]string) { assert.NotEqual(t, utils.ArrayString[1], output.([]string)[index]) @@ -20,7 +21,7 @@ func Test_dropString(t *testing.T) { func Test_dropStringPtr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayStringPtr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayStringPtr), utils.ArrayStringPtr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayStringPtr), utils.ArrayStringPtr[1], info, None) assert.True(t, found) for index := range output.([]*string) { assert.NotEqual(t, *utils.ArrayStringPtr[1], *output.([]*string)[index]) @@ -30,7 +31,7 @@ func Test_dropStringPtr(t *testing.T) { func Test_dropBool(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayBool[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayBool), utils.ArrayBool[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayBool), utils.ArrayBool[1], info, None) assert.True(t, found) for index := range output.([]bool) { assert.NotEqual(t, utils.ArrayBool[1], output.([]bool)[index]) @@ -40,7 +41,7 @@ func Test_dropBool(t *testing.T) { func Test_dropBoolPtr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayBoolPtr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayBoolPtr), utils.ArrayBoolPtr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayBoolPtr), utils.ArrayBoolPtr[1], info, None) assert.True(t, found) for index := range output.([]*bool) { assert.NotEqual(t, *utils.ArrayBoolPtr[1], *output.([]*bool)[index]) @@ -50,7 +51,7 @@ func Test_dropBoolPtr(t *testing.T) { func Test_dropInt(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt), utils.ArrayInt[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt), utils.ArrayInt[1], info, None) assert.True(t, found) for index := range output.([]int) { assert.NotEqual(t, utils.ArrayInt[1], output.([]int)[index]) @@ -60,7 +61,7 @@ func Test_dropInt(t *testing.T) { func Test_dropIntPtr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayIntPtr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayIntPtr), utils.ArrayIntPtr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayIntPtr), utils.ArrayIntPtr[1], info, None) assert.True(t, found) for index := range output.([]*int) { assert.NotEqual(t, *utils.ArrayIntPtr[1], *output.([]*int)[index]) @@ -70,7 +71,7 @@ func Test_dropIntPtr(t *testing.T) { func Test_dropInt8(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt8[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt8), utils.ArrayInt8[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt8), utils.ArrayInt8[1], info, None) assert.True(t, found) for index := range output.([]int8) { assert.NotEqual(t, utils.ArrayInt8[1], output.([]int8)[index]) @@ -80,7 +81,7 @@ func Test_dropInt8(t *testing.T) { func Test_dropInt8Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt8Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt8Ptr), utils.ArrayInt8Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt8Ptr), utils.ArrayInt8Ptr[1], info, None) assert.True(t, found) for index := range output.([]*int8) { assert.NotEqual(t, *utils.ArrayInt8Ptr[1], *output.([]*int8)[index]) @@ -90,7 +91,7 @@ func Test_dropInt8Ptr(t *testing.T) { func Test_dropInt16(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt16[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt16), utils.ArrayInt16[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt16), utils.ArrayInt16[1], info, None) assert.True(t, found) for index := range output.([]int16) { assert.NotEqual(t, utils.ArrayInt16[1], output.([]int16)[index]) @@ -100,7 +101,7 @@ func Test_dropInt16(t *testing.T) { func Test_dropInt16Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt16Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt16Ptr), utils.ArrayInt16Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt16Ptr), utils.ArrayInt16Ptr[1], info, None) assert.True(t, found) for index := range output.([]*int16) { assert.NotEqual(t, *utils.ArrayInt16Ptr[1], *output.([]*int16)[index]) @@ -110,7 +111,7 @@ func Test_dropInt16Ptr(t *testing.T) { func Test_dropInt32(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt32[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt32), utils.ArrayInt32[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt32), utils.ArrayInt32[1], info, None) assert.True(t, found) for index := range output.([]int32) { assert.NotEqual(t, utils.ArrayInt32[1], output.([]int32)[index]) @@ -120,7 +121,7 @@ func Test_dropInt32(t *testing.T) { func Test_dropInt32Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt32Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt32Ptr), utils.ArrayInt32Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt32Ptr), utils.ArrayInt32Ptr[1], info, None) assert.True(t, found) for index := range output.([]*int32) { assert.NotEqual(t, *utils.ArrayInt32Ptr[1], *output.([]*int32)[index]) @@ -130,7 +131,7 @@ func Test_dropInt32Ptr(t *testing.T) { func Test_dropInt64(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt64[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt64), utils.ArrayInt64[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt64), utils.ArrayInt64[1], info, None) assert.True(t, found) for index := range output.([]int64) { assert.NotEqual(t, utils.ArrayInt64[1], output.([]int64)[index]) @@ -140,7 +141,7 @@ func Test_dropInt64(t *testing.T) { func Test_dropInt64Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayInt64Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayInt64Ptr), utils.ArrayInt64Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayInt64Ptr), utils.ArrayInt64Ptr[1], info, None) assert.True(t, found) for index := range output.([]*int64) { assert.NotEqual(t, *utils.ArrayInt64Ptr[1], *output.([]*int64)[index]) @@ -150,7 +151,7 @@ func Test_dropInt64Ptr(t *testing.T) { func Test_dropUint(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint), utils.ArrayUint[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint), utils.ArrayUint[1], info, None) assert.True(t, found) for index := range output.([]uint) { assert.NotEqual(t, utils.ArrayUint[1], output.([]uint)[index]) @@ -160,7 +161,7 @@ func Test_dropUint(t *testing.T) { func Test_dropUintPtr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUintPtr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUintPtr), utils.ArrayUintPtr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUintPtr), utils.ArrayUintPtr[1], info, None) assert.True(t, found) for index := range output.([]*uint) { assert.NotEqual(t, *utils.ArrayUintPtr[1], *output.([]*uint)[index]) @@ -170,7 +171,7 @@ func Test_dropUintPtr(t *testing.T) { func Test_dropUint8(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint8[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint8), utils.ArrayUint8[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint8), utils.ArrayUint8[1], info, None) assert.True(t, found) for index := range output.([]uint8) { assert.NotEqual(t, utils.ArrayUint8[1], output.([]uint8)[index]) @@ -180,7 +181,7 @@ func Test_dropUint8(t *testing.T) { func Test_dropUint8Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint8Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint8Ptr), utils.ArrayUint8Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint8Ptr), utils.ArrayUint8Ptr[1], info, None) assert.True(t, found) for index := range output.([]*uint8) { assert.NotEqual(t, *utils.ArrayUint8Ptr[1], *output.([]*uint8)[index]) @@ -190,7 +191,7 @@ func Test_dropUint8Ptr(t *testing.T) { func Test_dropUint16(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint16[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint16), utils.ArrayUint16[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint16), utils.ArrayUint16[1], info, None) assert.True(t, found) for index := range output.([]uint16) { assert.NotEqual(t, utils.ArrayUint16[1], output.([]uint16)[index]) @@ -200,7 +201,7 @@ func Test_dropUint16(t *testing.T) { func Test_dropUint16Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint16Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint16Ptr), utils.ArrayUint16Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint16Ptr), utils.ArrayUint16Ptr[1], info, None) assert.True(t, found) for index := range output.([]*uint16) { assert.NotEqual(t, *utils.ArrayUint16Ptr[1], *output.([]*uint16)[index]) @@ -210,7 +211,7 @@ func Test_dropUint16Ptr(t *testing.T) { func Test_dropUint32(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint32[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint32), utils.ArrayUint32[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint32), utils.ArrayUint32[1], info, None) assert.True(t, found) for index := range output.([]uint32) { assert.NotEqual(t, utils.ArrayUint32[1], output.([]uint32)[index]) @@ -220,7 +221,7 @@ func Test_dropUint32(t *testing.T) { func Test_dropUint32Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint32Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint32Ptr), utils.ArrayUint32Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint32Ptr), utils.ArrayUint32Ptr[1], info, None) assert.True(t, found) for index := range output.([]*uint32) { assert.NotEqual(t, *utils.ArrayUint32Ptr[1], *output.([]*uint32)[index]) @@ -230,7 +231,7 @@ func Test_dropUint32Ptr(t *testing.T) { func Test_dropUint64(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint64[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint64), utils.ArrayUint64[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint64), utils.ArrayUint64[1], info, None) assert.True(t, found) for index := range output.([]uint64) { assert.NotEqual(t, utils.ArrayUint64[1], output.([]uint64)[index]) @@ -240,7 +241,7 @@ func Test_dropUint64(t *testing.T) { func Test_dropUint64Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayUint64Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayUint64Ptr), utils.ArrayUint64Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayUint64Ptr), utils.ArrayUint64Ptr[1], info, None) assert.True(t, found) for index := range output.([]*uint64) { assert.NotEqual(t, *utils.ArrayUint64Ptr[1], *output.([]*uint64)[index]) @@ -250,7 +251,7 @@ func Test_dropUint64Ptr(t *testing.T) { func Test_dropFloat32(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayFloat32[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayFloat32), utils.ArrayFloat32[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayFloat32), utils.ArrayFloat32[1], info, None) assert.True(t, found) for index := range output.([]float32) { assert.NotEqual(t, utils.ArrayFloat32[1], output.([]float32)[index]) @@ -260,7 +261,7 @@ func Test_dropFloat32(t *testing.T) { func Test_dropFloat32Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayFloat32Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayFloat32Ptr), utils.ArrayFloat32Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayFloat32Ptr), utils.ArrayFloat32Ptr[1], info, None) assert.True(t, found) for index := range output.([]*float32) { assert.NotEqual(t, *utils.ArrayFloat32Ptr[1], *output.([]*float32)[index]) @@ -270,7 +271,7 @@ func Test_dropFloat32Ptr(t *testing.T) { func Test_dropFloat64(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayFloat64[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayFloat64), utils.ArrayFloat64[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayFloat64), utils.ArrayFloat64[1], info, None) assert.True(t, found) for index := range output.([]float64) { assert.NotEqual(t, utils.ArrayFloat64[1], output.([]float64)[index]) @@ -280,9 +281,25 @@ func Test_dropFloat64(t *testing.T) { func Test_dropFloat64Ptr(t *testing.T) { typeElement := reflect.TypeOf(utils.ArrayFloat64Ptr[1]) info := &dropInfo{itemType: &typeElement} - found, output := dispatch(reflect.ValueOf(utils.ArrayFloat64Ptr), utils.ArrayFloat64Ptr[1], info) + found, output := dispatch(reflect.ValueOf(utils.ArrayFloat64Ptr), utils.ArrayFloat64Ptr[1], info, None) assert.True(t, found) for index := range output.([]*float64) { assert.NotEqual(t, *utils.ArrayFloat64Ptr[1], *output.([]*float64)[index]) } } + +func Test_dropString_With_Left(t *testing.T) { + typeElement := reflect.TypeOf(utils.ArrayString[1]) + info := &dropInfo{itemType: &typeElement} + found, output := dispatch(reflect.ValueOf(utils.ArrayString), utils.ArrayString[1], info, Left) + assert.False(t, found) + assert.Nil(t, output) +} + +func Test_dropString_With_Right(t *testing.T) { + typeElement := reflect.TypeOf(utils.ArrayString[1]) + info := &dropInfo{itemType: &typeElement} + found, output := dispatch(reflect.ValueOf(utils.ArrayString), utils.ArrayString[1], info, Right) + assert.False(t, found) + assert.Nil(t, output) +} diff --git a/internal/drop/drop.go b/internal/drop/drop.go index ff6bdb2..3e456b7 100644 --- a/internal/drop/drop.go +++ b/internal/drop/drop.go @@ -1,18 +1,30 @@ package drop import ( - "github.com/wesovilabs/koazee/errors" "reflect" + + "github.com/wesovilabs/koazee/errors" ) // OpCode identifier for operation drop const OpCode = "drop" +// Option defines drop option +type Option int + +// Options +const ( + None Option = iota + Left + Right +) + // Drop struct for operation type Drop struct { ItemsValue reflect.Value ItemsType reflect.Type Item interface{} + Option Option } // Run performs the operations whenever is called @@ -21,23 +33,47 @@ func (op *Drop) Run() (reflect.Value, *errors.Error) { if err != nil { return reflect.ValueOf(nil), err } - if found, result := dispatch(op.ItemsValue, op.Item, info); found { + if found, result := dispatch(op.ItemsValue, op.Item, info, op.Option); found { return reflect.ValueOf(result), nil } + + isFounded := false newItems := reflect.MakeSlice(reflect.SliceOf(op.ItemsType), 0, 0) for index := 0; index < op.ItemsValue.Len(); index++ { val := op.ItemsValue.Index(index) - if equalsValues(val, info.itemValue) { - newItems = reflect.Append(newItems, val) + switch op.Option { + case None: + if equalsValues(val, info.itemValue) == false { + isFounded = true + newItems = reflect.Append(newItems, val) + } + case Left: + if isFounded || equalsValues(val, info.itemValue) { + isFounded = true + newItems = reflect.Append(newItems, val) + } + case Right: + if equalsValues(val, info.itemValue) { + isFounded = true + newItems = reflect.Append(newItems, val) + } else if isFounded == false { + newItems = reflect.Append(newItems, val) + } } } - return newItems, nil + + if isFounded { + return newItems, nil + } + return op.ItemsValue, nil } func (op *Drop) validate() (*dropInfo, *errors.Error) { itemType := reflect.TypeOf(op.Item) if info := cache.get(op.ItemsType, itemType); info != nil { - return info, nil + if equalsValues(info.itemValue, reflect.ValueOf(op.Item)) { + return info, nil + } } info := &dropInfo{itemType: &itemType} if op.ItemsValue.Len() > 0 { diff --git a/stream/dropLeft.go b/stream/dropLeft.go new file mode 100644 index 0000000..91069c7 --- /dev/null +++ b/stream/dropLeft.go @@ -0,0 +1,42 @@ +package stream + +import ( + "reflect" + + "github.com/wesovilabs/koazee/internal/drop" +) + +type streamDropLeft struct { + ItemsValue reflect.Value + ItemsType reflect.Type + Item interface{} + Option drop.Option +} + +func (a *streamDropLeft) run(s Stream) Stream { + if s.itemsLen == 0 { + return s + } + value, err := (&drop.Drop{ + ItemsType: s.itemsType, + ItemsValue: s.itemsValue, + Item: a.Item, + Option: drop.Left, + }).Run() + if err != nil { + s.err = err + return s + } + return s.withItemsValue(value) +} + +// DropLeft remove left of element that matches input +func (s Stream) DropLeft(input interface{}) Stream { + s.operations = append(s.operations, &streamDropLeft{ + ItemsValue: s.itemsValue, + ItemsType: s.itemsType, + Item: input, + Option: drop.Left, + }) + return s +} diff --git a/stream/dropLeft_test.go b/stream/dropLeft_test.go new file mode 100644 index 0000000..840f0cf --- /dev/null +++ b/stream/dropLeft_test.go @@ -0,0 +1,50 @@ +package stream_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/wesovilabs/koazee" + "github.com/wesovilabs/koazee/utils" +) + +func TestStream_DropLeft(t *testing.T) { + expect := []int{34, 45, 67} + actual := koazee.StreamOf([]int{44, 55, 66, 34, 45, 67}). + DropLeft(34). + Out().Val() + assert.Equal(t, expect, actual) +} + +func TestStream_DropLeft_With_Struct(t *testing.T) { + expect := []utils.Person{ + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + DropLeft(utils.Person{"Jim", "Doe", 56, true}). + Out().Val() + assert.Equal(t, expect, actual) +} + +func TestStream_DropLeft_With_Struct_NotFound(t *testing.T) { + expect := []utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + Filter(func(person utils.Person) bool { return person.Age < 25 }). + DropLeft(utils.Person{"Jamie", "Doe", 89, false}). + Out().Val() + assert.Equal(t, expect, actual) +} diff --git a/stream/dropRight.go b/stream/dropRight.go new file mode 100644 index 0000000..1c8fb77 --- /dev/null +++ b/stream/dropRight.go @@ -0,0 +1,42 @@ +package stream + +import ( + "reflect" + + "github.com/wesovilabs/koazee/internal/drop" +) + +type streamDropRight struct { + ItemsValue reflect.Value + ItemsType reflect.Type + Item interface{} + Option drop.Option +} + +func (a *streamDropRight) run(s Stream) Stream { + if s.itemsLen == 0 { + return s + } + value, err := (&drop.Drop{ + ItemsType: s.itemsType, + ItemsValue: s.itemsValue, + Item: a.Item, + Option: drop.Right, + }).Run() + if err != nil { + s.err = err + return s + } + return s.withItemsValue(value) +} + +// DropRight remove right of element that matches input +func (s Stream) DropRight(input interface{}) Stream { + s.operations = append(s.operations, &streamDropRight{ + ItemsValue: s.itemsValue, + ItemsType: s.itemsType, + Item: input, + Option: drop.Right, + }) + return s +} diff --git a/stream/dropRight_test.go b/stream/dropRight_test.go new file mode 100644 index 0000000..64cc4ca --- /dev/null +++ b/stream/dropRight_test.go @@ -0,0 +1,69 @@ +package stream_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/wesovilabs/koazee" + "github.com/wesovilabs/koazee/utils" +) + +func TestStream_DropRight(t *testing.T) { + expect := []string{"hoge", "foo"} + actual := koazee.StreamOf([]string{"hoge", "foo", "bar"}). + DropRight("foo"). + Out().Val() + assert.Equal(t, expect, actual) +} + +func TestStream_DropRight_With_Struct(t *testing.T) { + expect := []utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + DropRight(utils.Person{"Jim", "Doe", 56, true}). + Out().Val() + assert.Equal(t, expect, actual) +} + +func TestStream_DropRight_With_Cache(t *testing.T) { + expect := []utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + DropRight(utils.Person{"Jim", "Doe", 56, true}). + Out().Val() + assert.Equal(t, expect, actual) +} + +func TestStream_DropRight_With_Struct_NotFound(t *testing.T) { + expect := []utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + DropRight(utils.Person{"Mike", "Jamie", 89, true}). + Out().Val() + assert.Equal(t, expect, actual) +} diff --git a/stream/drop_test.go b/stream/drop_test.go index 9be4115..41eee86 100644 --- a/stream/drop_test.go +++ b/stream/drop_test.go @@ -1,9 +1,11 @@ package stream_test import ( - "github.com/wesovilabs/koazee/internal/drop" "testing" + "github.com/wesovilabs/koazee/internal/drop" + "github.com/wesovilabs/koazee/utils" + "github.com/stretchr/testify/assert" "github.com/wesovilabs/koazee" "github.com/wesovilabs/koazee/errors" @@ -28,6 +30,7 @@ func TestStream_Drop(t *testing.T) { ) } + func TestStream_Drop_validation(t *testing.T) { assert.Equal( @@ -42,3 +45,20 @@ func TestStream_Drop_validation(t *testing.T) { "A nil value can not be dropped from a Stream of non-pointers values"), koazee.Stream().Drop(nil).With([]int{2, 3, 1}).Out().Err()) } + +func TestStream_Drop_With_Struct(t *testing.T) { + expect := []utils.Person{ + {"John", "Doe", 23, true}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + } + actual := koazee.StreamOf([]utils.Person{ + {"John", "Doe", 23, true}, + {"Jane", "Doe", 22, false}, + {"Jim", "Doe", 56, true}, + {"Jamie", "Doe", 89, false}, + }). + Drop(utils.Person{"Jane", "Doe", 22, false}). + Out().Val() + assert.Equal(t, expect, actual) +}