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 }