github.com/MontFerret/ferret@v0.18.0/pkg/runtime/collections/filter_test.go (about) 1 package collections_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "math" 7 "testing" 8 9 . "github.com/smartystreets/goconvey/convey" 10 11 "github.com/MontFerret/ferret/pkg/runtime/collections" 12 "github.com/MontFerret/ferret/pkg/runtime/core" 13 "github.com/MontFerret/ferret/pkg/runtime/values" 14 ) 15 16 func TestFilter(t *testing.T) { 17 Convey("Should filter out non-even result", t, func() { 18 arr := []core.Value{ 19 values.NewInt(1), 20 values.NewInt(2), 21 values.NewInt(3), 22 values.NewInt(4), 23 values.NewInt(5), 24 } 25 26 predicate := func(_ context.Context, scope *core.Scope) (bool, error) { 27 i := float64(scope.MustGetVariable(collections.DefaultValueVar).Unwrap().(int)) 28 calc := i / 2 29 30 return calc == math.Floor(calc), nil 31 } 32 33 iter, err := collections.NewFilterIterator( 34 sliceIterator(arr), 35 predicate, 36 ) 37 38 So(err, ShouldBeNil) 39 40 scope, _ := core.NewRootScope() 41 res, err := collections.ToSlice(context.Background(), scope, iter) 42 43 So(err, ShouldBeNil) 44 So(res, ShouldHaveLength, 2) 45 }) 46 47 Convey("Should filter out non-even groupKeys", t, func() { 48 arr := []core.Value{ 49 values.NewInt(1), 50 values.NewInt(2), 51 values.NewInt(3), 52 values.NewInt(4), 53 values.NewInt(5), 54 } 55 56 predicate := func(_ context.Context, scope *core.Scope) (bool, error) { 57 i := float64(scope.MustGetVariable(collections.DefaultKeyVar).Unwrap().(int)) 58 59 if i == 0 { 60 return false, nil 61 } 62 63 calc := i / 2 64 65 return calc == math.Floor(calc), nil 66 } 67 68 iter, err := collections.NewFilterIterator( 69 sliceIterator(arr), 70 predicate, 71 ) 72 73 So(err, ShouldBeNil) 74 75 scope, _ := core.NewRootScope() 76 res, err := collections.ToSlice(context.Background(), scope, iter) 77 78 So(err, ShouldBeNil) 79 80 So(res, ShouldHaveLength, 2) 81 }) 82 83 Convey("Should filter out result all result", t, func() { 84 arr := []core.Value{ 85 values.NewInt(1), 86 values.NewInt(2), 87 values.NewInt(3), 88 values.NewInt(4), 89 values.NewInt(5), 90 } 91 92 predicate := func(_ context.Context, _ *core.Scope) (bool, error) { 93 return false, nil 94 } 95 96 iter, err := collections.NewFilterIterator( 97 sliceIterator(arr), 98 predicate, 99 ) 100 101 So(err, ShouldBeNil) 102 103 scope, _ := core.NewRootScope() 104 res, err := collections.ToSlice(context.Background(), scope, iter) 105 106 So(err, ShouldBeNil) 107 So(res, ShouldHaveLength, 0) 108 }) 109 110 Convey("Should pass through all result", t, func() { 111 arr := []core.Value{ 112 values.NewInt(1), 113 values.NewInt(2), 114 values.NewInt(3), 115 values.NewInt(4), 116 values.NewInt(5), 117 } 118 119 predicate := func(_ context.Context, _ *core.Scope) (bool, error) { 120 return true, nil 121 } 122 123 iter, err := collections.NewFilterIterator( 124 sliceIterator(arr), 125 predicate, 126 ) 127 128 So(err, ShouldBeNil) 129 130 scope, _ := core.NewRootScope() 131 res, err := collections.ToSlice(context.Background(), scope, iter) 132 133 So(err, ShouldBeNil) 134 So(res, ShouldHaveLength, len(arr)) 135 }) 136 137 Convey("Should return an error when exhausted", t, func() { 138 arr := []core.Value{ 139 values.NewInt(1), 140 values.NewInt(2), 141 values.NewInt(3), 142 values.NewInt(4), 143 values.NewInt(5), 144 } 145 146 predicate := func(_ context.Context, _ *core.Scope) (bool, error) { 147 return true, nil 148 } 149 150 iter, err := collections.NewFilterIterator( 151 sliceIterator(arr), 152 predicate, 153 ) 154 155 So(err, ShouldBeNil) 156 157 scope, _ := core.NewRootScope() 158 _, err = collections.ToSlice(context.Background(), scope, iter) 159 160 So(err, ShouldBeNil) 161 162 item, err := iter.Next(context.Background(), scope) 163 164 So(item, ShouldBeNil) 165 So(err, ShouldEqual, core.ErrNoMoreData) 166 }) 167 168 Convey("Should iterate over nested filter", t, func() { 169 arr := []core.Value{ 170 values.NewInt(1), 171 values.NewInt(2), 172 values.NewInt(3), 173 values.NewInt(4), 174 values.NewInt(5), 175 } 176 177 // i < 5 178 predicate1 := func(_ context.Context, scope *core.Scope) (bool, error) { 179 return scope.MustGetVariable(collections.DefaultValueVar).Compare(values.NewInt(5)) == -1, nil 180 } 181 182 // i > 2 183 predicate2 := func(_ context.Context, scope *core.Scope) (bool, error) { 184 return scope.MustGetVariable(collections.DefaultValueVar).Compare(values.NewInt(2)) == 1, nil 185 } 186 187 it, _ := collections.NewFilterIterator( 188 sliceIterator(arr), 189 predicate1, 190 ) 191 192 iter, err := collections.NewFilterIterator( 193 it, 194 predicate2, 195 ) 196 197 So(err, ShouldBeNil) 198 199 scope, _ := core.NewRootScope() 200 sets, err := collections.ToSlice(context.Background(), scope, iter) 201 202 So(err, ShouldBeNil) 203 204 res := toArrayOfValues(sets) 205 206 js, _ := json.Marshal(res) 207 208 So(string(js), ShouldEqual, `[3,4]`) 209 }) 210 }