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  }