@@ -132,7 +132,8 @@ func AddValues(c *Client) {
132132 }
133133
134134}
135- func Init () {
135+
136+ func _init () {
136137 /* load test data */
137138 c := createClient ("docs-games-idx1" )
138139
@@ -149,13 +150,38 @@ func Init() {
149150 AddValues (c )
150151}
151152
153+ func TestAggregateSortByMax (t * testing.T ) {
154+ _init ()
155+ c := createClient ("docs-games-idx1" )
156+
157+ q1 := NewAggregateQuery ().SetQuery (NewQuery ("sony" )).
158+ SetMax (60 ).
159+ SortBy ([]SortingKey {* NewSortingKeyDir ("@price" , false )})
160+
161+ res , _ , err := c .Aggregate (q1 )
162+ assert .Nil (t , err )
163+ f1 , _ := strconv .ParseFloat (res [0 ][1 ], 64 )
164+ f2 , _ := strconv .ParseFloat (res [1 ][1 ], 64 )
165+ assert .GreaterOrEqual (t , f1 , f2 )
166+ assert .Less (t , f1 , 696.0 )
167+
168+ _ , rep , err := c .AggregateQuery (q1 )
169+ assert .Nil (t , err )
170+ f1 , _ = strconv .ParseFloat (rep [0 ]["price" ].(string ), 64 )
171+ f2 , _ = strconv .ParseFloat (rep [1 ]["price" ].(string ), 64 )
172+ assert .GreaterOrEqual (t , f1 , f2 )
173+ assert .Less (t , f1 , 696.0 )
174+ }
175+
152176func TestAggregateGroupBy (t * testing.T ) {
153- Init ()
177+ _init ()
154178 c := createClient ("docs-games-idx1" )
155179
156180 q1 := NewAggregateQuery ().
157181 GroupBy (* NewGroupBy ().AddFields ("@brand" ).
158- Reduce (* NewReducerAlias (GroupByReducerCount , []string {}, "count" ))).
182+ Reduce (* NewReducerAlias ("" , nil , "count" ).
183+ SetName (GroupByReducerCount ).
184+ SetArgs ([]string {}))).
159185 SortBy ([]SortingKey {* NewSortingKeyDir ("@count" , false )}).
160186 Limit (0 , 5 )
161187
@@ -169,7 +195,7 @@ func TestAggregateGroupBy(t *testing.T) {
169195}
170196
171197func TestAggregateMinMax (t * testing.T ) {
172- Init ()
198+ _init ()
173199 c := createClient ("docs-games-idx1" )
174200
175201 q1 := NewAggregateQuery ().SetQuery (NewQuery ("sony" )).
@@ -214,7 +240,7 @@ func TestAggregateMinMax(t *testing.T) {
214240}
215241
216242func TestAggregateCountDistinct (t * testing.T ) {
217- Init ()
243+ _init ()
218244 c := createClient ("docs-games-idx1" )
219245
220246 q1 := NewAggregateQuery ().
@@ -233,7 +259,7 @@ func TestAggregateCountDistinct(t *testing.T) {
233259}
234260
235261func TestAggregateToList (t * testing.T ) {
236- Init ()
262+ _init ()
237263 c := createClient ("docs-games-idx1" )
238264
239265 q1 := NewAggregateQuery ().
@@ -250,7 +276,7 @@ func TestAggregateToList(t *testing.T) {
250276}
251277
252278func TestAggregateFilter (t * testing.T ) {
253- Init ()
279+ _init ()
254280 c := createClient ("docs-games-idx1" )
255281
256282 q1 := NewAggregateQuery ().
@@ -273,6 +299,28 @@ func TestAggregateFilter(t *testing.T) {
273299 }
274300}
275301
302+ func TestAggregateApply (t * testing.T ) {
303+ _init ()
304+ c := createClient ("docs-games-idx1" )
305+
306+ q1 := NewAggregateQuery ().
307+ GroupBy (* NewGroupBy ().AddFields ("@brand" ).
308+ Reduce (* NewReducerAlias (GroupByReducerCount , []string {}, "count" ))).
309+ Apply (* NewProjection ("@count/2" , "halfCount" ))
310+
311+ res , _ , err := c .Aggregate (q1 )
312+ assert .Nil (t , err )
313+ count , _ := strconv .ParseFloat (res [0 ][3 ], 64 )
314+ halfCount , _ := strconv .ParseFloat (res [0 ][5 ], 64 )
315+ assert .Equal (t , halfCount * 2 , count )
316+
317+ _ , rep , err := c .AggregateQuery (q1 )
318+ assert .Nil (t , err )
319+ count , _ = strconv .ParseFloat (rep [0 ]["count" ].(string ), 64 )
320+ halfCount , _ = strconv .ParseFloat (rep [0 ]["halfCount" ].(string ), 64 )
321+ assert .Equal (t , halfCount * 2 , count )
322+ }
323+
276324func makeAggResponseInterface (seed int64 , nElements int , responseSizes []int ) (res []interface {}) {
277325 rand .Seed (seed )
278326 nInner := len (responseSizes )
@@ -326,53 +374,76 @@ func BenchmarkProcessAggResponseSS_100x4Elements(b *testing.B) {
326374}
327375
328376func TestProjection_Serialize (t * testing.T ) {
329- type fields struct {
330- Expression string
331- Alias string
332- }
333377 tests := []struct {
334- name string
335- fields fields
336- want redis.Args
378+ name string
379+ projection Projection
380+ want redis.Args
337381 }{
338- {"Test_Serialize_1" , fields { "sqrt(log(foo) * floor(@bar/baz)) + (3^@qaz % 6)" , "sqrt" } , redis.Args {"APPLY" , "sqrt(log(foo) * floor(@bar/baz)) + (3^@qaz % 6)" , "AS" , "sqrt" }},
382+ {"Test_Serialize_1" , * NewProjection ( "sqrt(log(foo) * floor(@bar/baz)) + (3^@qaz % 6)" , "sqrt" ) , redis.Args {"APPLY" , "sqrt(log(foo) * floor(@bar/baz)) + (3^@qaz % 6)" , "AS" , "sqrt" }},
339383 }
340384 for _ , tt := range tests {
341385 t .Run (tt .name , func (t * testing.T ) {
342- p := Projection {
343- Expression : tt .fields .Expression ,
344- Alias : tt .fields .Alias ,
345- }
346- if got := p .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
386+ if got := tt .projection .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
347387 t .Errorf ("serialize() = %v, want %v" , got , tt .want )
348388 }
349389 })
350390 }
351391}
352392
353393func TestCursor_Serialize (t * testing.T ) {
354- type fields struct {
355- Id int
356- Count int
357- MaxIdle int
358- }
359394 tests := []struct {
360395 name string
361- fields fields
396+ cursor Cursor
362397 want redis.Args
363398 }{
364- {"TestCursor_Serialize_1" , fields {1 , 0 , 0 }, redis.Args {"WITHCURSOR" }},
365- {"TestCursor_Serialize_2_MAXIDLE" , fields {1 , 0 , 30000 }, redis.Args {"WITHCURSOR" , "MAXIDLE" , 30000 }},
366- {"TestCursor_Serialize_3_COUNT_MAXIDLE" , fields {1 , 10 , 30000 }, redis.Args {"WITHCURSOR" , "COUNT" , 10 , "MAXIDLE" , 30000 }},
399+ {"TestCursor_Serialize_basic" , * NewCursor ().SetId (1 ), redis.Args {"WITHCURSOR" }},
400+ {"TestCursor_Serialize_MAXIDLE" , * NewCursor ().SetId (1 ).SetMaxIdle (30000 ), redis.Args {"WITHCURSOR" , "MAXIDLE" , 30000 }},
401+ {"TestCursor_Serialize_COUNT_MAXIDLE" , * NewCursor ().SetId (1 ).SetMaxIdle (30000 ).SetCount (10 ), redis.Args {"WITHCURSOR" , "COUNT" , 10 , "MAXIDLE" , 30000 }},
402+ }
403+ for _ , tt := range tests {
404+ t .Run (tt .name , func (t * testing.T ) {
405+ if got := tt .cursor .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
406+ t .Errorf ("serialize() = %v, want %v" , got , tt .want )
407+ }
408+ })
409+ }
410+ }
411+
412+ func TestQuery_Serialize (t * testing.T ) {
413+ tests := []struct {
414+ name string
415+ query AggregateQuery
416+ want redis.Args
417+ }{
418+ {"TestQuery_Serialize_basic" , * NewAggregateQuery (), redis.Args {"*" }},
419+ {"TestQuery_Serialize_WITHSCHEMA" , * NewAggregateQuery ().SetWithSchema (true ), redis.Args {"*" , "WITHSCHEMA" }},
420+ {"TestQuery_Serialize_VERBATIM" , * NewAggregateQuery ().SetVerbatim (true ), redis.Args {"*" , "VERBATIM" }},
421+ {"TestQuery_Serialize_WITHCURSOR" , * NewAggregateQuery ().SetCursor (NewCursor ()), redis.Args {"*" , "WITHCURSOR" }},
367422 }
368423 for _ , tt := range tests {
369424 t .Run (tt .name , func (t * testing.T ) {
370- c := Cursor {
371- Id : tt .fields .Id ,
372- Count : tt .fields .Count ,
373- MaxIdle : tt .fields .MaxIdle ,
425+ if got := tt .query .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
426+ t .Errorf ("serialize() = %v, want %v" , got , tt .want )
374427 }
375- if got := c .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
428+ })
429+ }
430+ }
431+
432+ func TestGroupBy_Serialize (t * testing.T ) {
433+ testsSerialize := []struct {
434+ name string
435+ group GroupBy
436+ want redis.Args
437+ }{
438+ {"TestGroupBy_Serialize_basic" , * NewGroupBy (), redis.Args {"GROUPBY" , 0 }},
439+ {"TestGroupBy_Serialize_FIELDS" , * NewGroupBy ().AddFields ("a" ), redis.Args {"GROUPBY" , 1 , "a" }},
440+ {"TestGroupBy_Serialize_FIELDS_2" , * NewGroupBy ().AddFields ([]string {"a" , "b" }), redis.Args {"GROUPBY" , 2 , "a" , "b" }},
441+ {"TestGroupBy_Serialize_REDUCE" , * NewGroupBy ().Reduce (* NewReducerAlias (GroupByReducerCount , []string {}, "count" )), redis.Args {"GROUPBY" , 0 , "REDUCE" , "COUNT" , 0 , "AS" , "count" }},
442+ {"TestGroupBy_Serialize_LIMIT" , * NewGroupBy ().Limit (10 , 20 ), redis.Args {"GROUPBY" , 0 , "LIMIT" , 10 , 20 }},
443+ }
444+ for _ , tt := range testsSerialize {
445+ t .Run (tt .name , func (t * testing.T ) {
446+ if got := tt .group .Serialize (); ! reflect .DeepEqual (got , tt .want ) {
376447 t .Errorf ("serialize() = %v, want %v" , got , tt .want )
377448 }
378449 })
@@ -394,11 +465,21 @@ func TestGroupBy_AddFields(t *testing.T) {
394465 args args
395466 want * GroupBy
396467 }{
397- {"TestGroupBy_AddFields_1 " ,
468+ {"TestGroupBy_AddFields_single_field " ,
398469 fields {[]string {}, nil , nil },
399470 args {"a" },
400471 & GroupBy {[]string {"a" }, nil , nil },
401472 },
473+ {"TestGroupBy_AddFields_multi_fields" ,
474+ fields {[]string {}, nil , nil },
475+ args {[]string {"a" , "b" , "c" }},
476+ & GroupBy {[]string {"a" , "b" , "c" }, nil , nil },
477+ },
478+ {"TestGroupBy_AddFields_nil" ,
479+ fields {[]string {}, nil , nil },
480+ args {nil },
481+ & GroupBy {[]string {}, nil , nil },
482+ },
402483 }
403484 for _ , tt := range tests {
404485 t .Run (tt .name , func (t * testing.T ) {
@@ -721,6 +802,7 @@ func Test_processAggReply(t *testing.T) {
721802 {"empty-reply" , args {[]interface {}{}}, 0 , [][]string {}, false },
722803 {"1-element-reply" , args {[]interface {}{1 , []interface {}{"userFullName" , "j" , "count" , "2" }}}, 1 , [][]string {{"userFullName" , "j" , "count" , "2" }}, false },
723804 {"multi-element-reply" , args {[]interface {}{2 , []interface {}{"userFullName" , "j" }, []interface {}{"userFullName" , "a" }}}, 2 , [][]string {{"userFullName" , "j" }, {"userFullName" , "a" }}, false },
805+ {"invalid-parsing-type" , args {[]interface {}{1 , []interface {}{[]interface {}{nil , nil }}}}, 1 , nil , true },
724806 }
725807 for _ , tt := range tests {
726808 t .Run (tt .name , func (t * testing.T ) {
@@ -732,9 +814,44 @@ func Test_processAggReply(t *testing.T) {
732814 if gotTotal != tt .wantTotal {
733815 t .Errorf ("processAggReply() gotTotal = %v, want %v" , gotTotal , tt .wantTotal )
734816 }
735- if ! reflect .DeepEqual (gotAggregateReply , tt .wantAggregateReply ) {
817+ if ! tt . wantErr && ! reflect .DeepEqual (gotAggregateReply , tt .wantAggregateReply ) {
736818 t .Errorf ("processAggReply() gotAggregateReply = %v, want %v" , gotAggregateReply , tt .wantAggregateReply )
737819 }
738820 })
739821 }
740822}
823+
824+ func Test_processAggQueryReply (t * testing.T ) {
825+ type args struct {
826+ res []interface {}
827+ }
828+ tests := []struct {
829+ name string
830+ args args
831+ wantTotal int
832+ wantAggregateReply []map [string ]interface {}
833+ wantErr bool
834+ }{
835+ {"empty-reply" , args {[]interface {}{}}, 0 , []map [string ]interface {}{}, false },
836+ {"1-element-reply" , args {[]interface {}{1 , []interface {}{"userFullName" , "j" , "count" , "2" }}}, 1 , []map [string ]interface {}{{"userFullName" : "j" , "count" : "2" }}, false },
837+ {"multi-element-reply" , args {[]interface {}{2 , []interface {}{"userFullName" , "j" }, []interface {}{"userFullName" , "a" }}}, 2 , []map [string ]interface {}{{"userFullName" : "j" }, {"userFullName" : "a" }}, false },
838+ {"odd-number-of-args" , args {[]interface {}{1 , []interface {}{"userFullName" }}}, 1 , nil , true },
839+ {"invalid-key" , args {[]interface {}{1 , []interface {}{nil , "j" }}}, 1 , nil , true },
840+ {"invalid-value" , args {[]interface {}{1 , []interface {}{"userFullName" , fmt .Errorf ("invalid value type" )}}}, 1 , nil , true },
841+ }
842+ for _ , tt := range tests {
843+ t .Run (tt .name , func (t * testing.T ) {
844+ gotTotal , gotAggregateReply , err := processAggQueryReply (tt .args .res )
845+ if (err != nil ) != tt .wantErr {
846+ t .Errorf ("processAggQueryReply() error = %v, wantErr %v" , err , tt .wantErr )
847+ return
848+ }
849+ if gotTotal != tt .wantTotal {
850+ t .Errorf ("processAggQueryReply() gotTotal = %v, want %v" , gotTotal , tt .wantTotal )
851+ }
852+ if ! tt .wantErr && ! reflect .DeepEqual (gotAggregateReply , tt .wantAggregateReply ) {
853+ t .Errorf ("processAggQueryReply() gotAggregateReply = %v, want %v" , gotAggregateReply , tt .wantAggregateReply )
854+ }
855+ })
856+ }
857+ }
0 commit comments