github.com/MontFerret/ferret@v0.18.0/pkg/runtime/collections/sort_test.go (about)

     1  package collections_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"testing"
     7  
     8  	. "github.com/smartystreets/goconvey/convey"
     9  
    10  	"github.com/MontFerret/ferret/pkg/runtime/collections"
    11  	"github.com/MontFerret/ferret/pkg/runtime/core"
    12  	"github.com/MontFerret/ferret/pkg/runtime/values"
    13  )
    14  
    15  func toValues(scopes []*core.Scope) []core.Value {
    16  	res := make([]core.Value, 0, len(scopes))
    17  
    18  	for _, scope := range scopes {
    19  		res = append(res, scope.MustGetVariable(collections.DefaultValueVar))
    20  	}
    21  
    22  	return res
    23  }
    24  
    25  func toArrayOfValues(scopes []*core.Scope) *values.Array {
    26  	return values.NewArrayWith(toValues(scopes)...)
    27  }
    28  
    29  func TestSort(t *testing.T) {
    30  	Convey("Should sort asc", t, func() {
    31  		arr := []core.Value{
    32  			values.NewInt(5),
    33  			values.NewInt(1),
    34  			values.NewInt(3),
    35  			values.NewInt(4),
    36  			values.NewInt(2),
    37  		}
    38  
    39  		s, _ := collections.NewSorter(
    40  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
    41  				return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil
    42  			},
    43  			collections.SortDirectionAsc,
    44  		)
    45  
    46  		iter, err := collections.NewSortIterator(
    47  			sliceIterator(arr),
    48  			s,
    49  		)
    50  
    51  		So(err, ShouldBeNil)
    52  
    53  		ctx := context.Background()
    54  		scope, _ := core.NewRootScope()
    55  
    56  		res, err := collections.ToSlice(ctx, scope, iter)
    57  
    58  		So(err, ShouldBeNil)
    59  
    60  		numbers := []int{1, 2, 3, 4, 5}
    61  
    62  		for idx, num := range numbers {
    63  			So(res[idx].MustGetVariable(collections.DefaultValueVar).Unwrap(), ShouldEqual, num)
    64  		}
    65  	})
    66  
    67  	Convey("Should sort desc", t, func() {
    68  		arr := []core.Value{
    69  			values.NewInt(5),
    70  			values.NewInt(1),
    71  			values.NewInt(3),
    72  			values.NewInt(4),
    73  			values.NewInt(2),
    74  		}
    75  
    76  		s, _ := collections.NewSorter(
    77  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
    78  				return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil
    79  			},
    80  			collections.SortDirectionDesc,
    81  		)
    82  
    83  		iter, err := collections.NewSortIterator(
    84  			sliceIterator(arr),
    85  			s,
    86  		)
    87  
    88  		So(err, ShouldBeNil)
    89  		ctx := context.Background()
    90  		scope, _ := core.NewRootScope()
    91  
    92  		res, err := collections.ToSlice(ctx, scope, iter)
    93  
    94  		So(err, ShouldBeNil)
    95  
    96  		numbers := []int{5, 4, 3, 2, 1}
    97  
    98  		for idx, num := range numbers {
    99  			So(res[idx].MustGetVariable(collections.DefaultValueVar).Unwrap(), ShouldEqual, num)
   100  		}
   101  	})
   102  
   103  	Convey("Should sort asc with multiple sorters", t, func() {
   104  		makeObj := func(one, two int) *values.Object {
   105  			obj := values.NewObject()
   106  
   107  			obj.Set("one", values.NewInt(one))
   108  			obj.Set("two", values.NewInt(two))
   109  
   110  			return obj
   111  		}
   112  
   113  		arr := []core.Value{
   114  			makeObj(1, 2),
   115  			makeObj(1, 1),
   116  			makeObj(3, 1),
   117  			makeObj(4, 2),
   118  			makeObj(2, 1),
   119  			makeObj(3, 2),
   120  			makeObj(4, 1),
   121  			makeObj(2, 2),
   122  		}
   123  
   124  		s1, _ := collections.NewSorter(
   125  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   126  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   127  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   128  
   129  				return o1.Compare(o2), nil
   130  			},
   131  			collections.SortDirectionAsc,
   132  		)
   133  
   134  		s2, _ := collections.NewSorter(
   135  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   136  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   137  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   138  
   139  				return o1.Compare(o2), nil
   140  			},
   141  			collections.SortDirectionAsc,
   142  		)
   143  
   144  		iter, err := collections.NewSortIterator(
   145  			sliceIterator(arr),
   146  			s1,
   147  			s2,
   148  		)
   149  
   150  		So(err, ShouldBeNil)
   151  
   152  		ctx := context.Background()
   153  		scope, _ := core.NewRootScope()
   154  
   155  		sets, err := collections.ToSlice(ctx, scope, iter)
   156  
   157  		So(err, ShouldBeNil)
   158  
   159  		res := toValues(sets)
   160  
   161  		j, _ := json.Marshal(res)
   162  
   163  		So(string(j), ShouldEqual, `[{"one":1,"two":1},{"one":1,"two":2},{"one":2,"two":1},{"one":2,"two":2},{"one":3,"two":1},{"one":3,"two":2},{"one":4,"two":1},{"one":4,"two":2}]`)
   164  	})
   165  
   166  	Convey("Should sort desc with multiple sorters", t, func() {
   167  		makeObj := func(one, two int) *values.Object {
   168  			obj := values.NewObject()
   169  
   170  			obj.Set("one", values.NewInt(one))
   171  			obj.Set("two", values.NewInt(two))
   172  
   173  			return obj
   174  		}
   175  
   176  		arr := []core.Value{
   177  			makeObj(1, 2),
   178  			makeObj(1, 1),
   179  			makeObj(3, 1),
   180  			makeObj(4, 2),
   181  			makeObj(2, 1),
   182  			makeObj(3, 2),
   183  			makeObj(4, 1),
   184  			makeObj(2, 2),
   185  		}
   186  
   187  		s1, _ := collections.NewSorter(
   188  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   189  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   190  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   191  
   192  				return o1.Compare(o2), nil
   193  			},
   194  			collections.SortDirectionDesc,
   195  		)
   196  
   197  		s2, _ := collections.NewSorter(
   198  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   199  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   200  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   201  
   202  				return o1.Compare(o2), nil
   203  			},
   204  			collections.SortDirectionDesc,
   205  		)
   206  
   207  		iter, err := collections.NewSortIterator(
   208  			sliceIterator(arr),
   209  			s1,
   210  			s2,
   211  		)
   212  
   213  		So(err, ShouldBeNil)
   214  
   215  		ctx := context.Background()
   216  		scope, _ := core.NewRootScope()
   217  
   218  		sets, err := collections.ToSlice(ctx, scope, iter)
   219  
   220  		So(err, ShouldBeNil)
   221  
   222  		res := toValues(sets)
   223  
   224  		j, _ := json.Marshal(res)
   225  
   226  		So(string(j), ShouldEqual, `[{"one":4,"two":2},{"one":4,"two":1},{"one":3,"two":2},{"one":3,"two":1},{"one":2,"two":2},{"one":2,"two":1},{"one":1,"two":2},{"one":1,"two":1}]`)
   227  	})
   228  
   229  	Convey("Should sort asc and desc with multiple sorters", t, func() {
   230  		makeObj := func(one, two int) *values.Object {
   231  			obj := values.NewObject()
   232  
   233  			obj.Set("one", values.NewInt(one))
   234  			obj.Set("two", values.NewInt(two))
   235  
   236  			return obj
   237  		}
   238  
   239  		arr := []core.Value{
   240  			makeObj(1, 2),
   241  			makeObj(1, 1),
   242  			makeObj(3, 1),
   243  			makeObj(4, 2),
   244  			makeObj(2, 1),
   245  			makeObj(3, 2),
   246  			makeObj(4, 1),
   247  			makeObj(2, 2),
   248  		}
   249  
   250  		s1, _ := collections.NewSorter(
   251  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   252  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   253  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   254  
   255  				return o1.Compare(o2), nil
   256  			},
   257  			collections.SortDirectionAsc,
   258  		)
   259  
   260  		s2, _ := collections.NewSorter(
   261  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   262  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   263  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   264  
   265  				return o1.Compare(o2), nil
   266  			},
   267  			collections.SortDirectionDesc,
   268  		)
   269  
   270  		iter, err := collections.NewSortIterator(
   271  			sliceIterator(arr),
   272  			s1,
   273  			s2,
   274  		)
   275  
   276  		So(err, ShouldBeNil)
   277  
   278  		ctx := context.Background()
   279  		scope, _ := core.NewRootScope()
   280  
   281  		sets, err := collections.ToSlice(ctx, scope, iter)
   282  
   283  		So(err, ShouldBeNil)
   284  
   285  		res := toValues(sets)
   286  
   287  		j, _ := json.Marshal(res)
   288  
   289  		So(string(j), ShouldEqual, `[{"one":1,"two":2},{"one":1,"two":1},{"one":2,"two":2},{"one":2,"two":1},{"one":3,"two":2},{"one":3,"two":1},{"one":4,"two":2},{"one":4,"two":1}]`)
   290  	})
   291  
   292  	Convey("Should sort desc and asc with multiple sorters", t, func() {
   293  		makeObj := func(one, two int) *values.Object {
   294  			obj := values.NewObject()
   295  
   296  			obj.Set("one", values.NewInt(one))
   297  			obj.Set("two", values.NewInt(two))
   298  
   299  			return obj
   300  		}
   301  
   302  		arr := []core.Value{
   303  			makeObj(1, 2),
   304  			makeObj(1, 1),
   305  			makeObj(3, 1),
   306  			makeObj(4, 2),
   307  			makeObj(2, 1),
   308  			makeObj(3, 2),
   309  			makeObj(4, 1),
   310  			makeObj(2, 2),
   311  		}
   312  
   313  		s1, _ := collections.NewSorter(
   314  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   315  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   316  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one")
   317  
   318  				return o1.Compare(o2), nil
   319  			},
   320  			collections.SortDirectionDesc,
   321  		)
   322  
   323  		s2, _ := collections.NewSorter(
   324  			func(ctx context.Context, first, second *core.Scope) (int64, error) {
   325  				o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   326  				o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two")
   327  
   328  				return o1.Compare(o2), nil
   329  			},
   330  			collections.SortDirectionAsc,
   331  		)
   332  
   333  		src, err := collections.NewSortIterator(
   334  			sliceIterator(arr),
   335  			s1,
   336  			s2,
   337  		)
   338  
   339  		So(err, ShouldBeNil)
   340  
   341  		ctx := context.Background()
   342  		scope, _ := core.NewRootScope()
   343  
   344  		sets, err := collections.ToSlice(ctx, scope, src)
   345  
   346  		So(err, ShouldBeNil)
   347  
   348  		res := toValues(sets)
   349  
   350  		j, _ := json.Marshal(res)
   351  
   352  		So(string(j), ShouldEqual, `[{"one":4,"two":1},{"one":4,"two":2},{"one":3,"two":1},{"one":3,"two":2},{"one":2,"two":1},{"one":2,"two":2},{"one":1,"two":1},{"one":1,"two":2}]`)
   353  	})
   354  }