tpl/collections: Add float64 support to where
authorCameron Moore <moorereason@gmail.com>
Tue, 27 Nov 2018 00:40:35 +0000 (18:40 -0600)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 27 Nov 2018 08:04:02 +0000 (09:04 +0100)
Fixes #5466

tpl/collections/where.go
tpl/collections/where_test.go

index be5c8205b1124765e8fcacb91214143aaf4e265f..859353ff09c9cb3718199288b9d01cd6cad9f3a0 100644 (file)
@@ -79,9 +79,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
        }
 
        var ivp, imvp *int64
+       var fvp, fmvp *float64
        var svp, smvp *string
        var slv, slmv interface{}
        var ima []int64
+       var fma []float64
        var sma []string
        if mv.Type() == v.Type() {
                switch v.Kind() {
@@ -95,6 +97,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
                        svp = &sv
                        smv := mv.String()
                        smvp = &smv
+               case reflect.Float64:
+                       fv := v.Float()
+                       fvp = &fv
+                       fmv := mv.Float()
+                       fmvp = &fmv
                case reflect.Struct:
                        switch v.Type() {
                        case timeType:
@@ -136,6 +143,14 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
                                        sma = append(sma, aString)
                                }
                        }
+               case reflect.Float64:
+                       fv := v.Float()
+                       fvp = &fv
+                       for i := 0; i < mv.Len(); i++ {
+                               if aFloat, err := toFloat(mv.Index(i)); err == nil {
+                                       fma = append(fma, aFloat)
+                               }
+                       }
                case reflect.Struct:
                        switch v.Type() {
                        case timeType:
@@ -153,52 +168,73 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
 
        switch op {
        case "", "=", "==", "eq":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp == *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp == *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp == *fmvp, nil
                }
        case "!=", "<>", "ne":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp != *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp != *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp != *fmvp, nil
                }
        case ">=", "ge":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp >= *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp >= *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp >= *fmvp, nil
                }
        case ">", "gt":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp > *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp > *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp > *fmvp, nil
                }
        case "<=", "le":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp <= *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp <= *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp <= *fmvp, nil
                }
        case "<", "lt":
-               if ivp != nil && imvp != nil {
+               switch {
+               case ivp != nil && imvp != nil:
                        return *ivp < *imvp, nil
-               } else if svp != nil && smvp != nil {
+               case svp != nil && smvp != nil:
                        return *svp < *smvp, nil
+               case fvp != nil && fmvp != nil:
+                       return *fvp < *fmvp, nil
                }
        case "in", "not in":
                var r bool
-               if ivp != nil && len(ima) > 0 {
+               switch {
+               case ivp != nil && len(ima) > 0:
                        r = ns.In(ima, *ivp)
-               } else if svp != nil {
+               case fvp != nil && len(fma) > 0:
+                       r = ns.In(fma, *fvp)
+               case svp != nil:
                        if len(sma) > 0 {
                                r = ns.In(sma, *svp)
                        } else if smvp != nil {
                                r = ns.In(*smvp, *svp)
                        }
-               } else {
+               default:
                        return false, nil
                }
                if op == "not in" {
index e702837782f03dfbb5f363c808c4cdebd0f27338..bf3d5011c0bfd58daae31a0862179ee6bb570d64 100644 (file)
@@ -63,6 +63,48 @@ func TestWhere(t *testing.T) {
                                {"a": 3, "b": 4},
                        },
                },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 4.0,
+                       expect: []map[string]float64{{"a": 3, "b": 4}},
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 4.0, op: "!=",
+                       expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 5, "x": 4}},
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 4.0, op: "<",
+                       expect: []map[string]float64{{"a": 1, "b": 2}},
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 4.0, op: "<=",
+                       expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 3, "b": 4}},
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 3}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 2.0, op: ">",
+                       expect: []map[string]float64{{"a": 3, "b": 3}},
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 3}, {"a": 5, "x": 4},
+                       },
+                       key: "b", match: 2.0, op: ">=",
+                       expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 3, "b": 3}},
+               },
                {
                        seq: []TstX{
                                {A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
@@ -180,6 +222,15 @@ func TestWhere(t *testing.T) {
                                {"a": 3, "b": 4}, {"a": 5, "b": 6},
                        },
                },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: ">", match: 3.0,
+                       expect: []map[string]float64{
+                               {"a": 3, "b": 4}, {"a": 5, "b": 6},
+                       },
+               },
                {
                        seq: []TstX{
                                {A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
@@ -198,6 +249,15 @@ func TestWhere(t *testing.T) {
                                {"a": 3, "b": 4},
                        },
                },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: "in", match: []float64{3, 4, 5},
+                       expect: []map[string]float64{
+                               {"a": 3, "b": 4},
+                       },
+               },
                {
                        seq: []map[string][]string{
                                {"a": []string{"A", "B", "C"}, "b": []string{"D", "E", "F"}}, {"a": []string{"G", "H", "I"}, "b": []string{"J", "K", "L"}}, {"a": []string{"M", "N", "O"}, "b": []string{"P", "Q", "R"}},
@@ -279,6 +339,15 @@ func TestWhere(t *testing.T) {
                                {"a": 3, "b": 4},
                        },
                },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: "in", match: ns.Slice(3.0, 4.0, 5.0),
+                       expect: []map[string]float64{
+                               {"a": 3, "b": 4},
+                       },
+               },
                {
                        seq: []map[string]time.Time{
                                {"a": d1, "b": d2}, {"a": d3, "b": d4}, {"a": d5, "b": d6},
@@ -331,6 +400,31 @@ func TestWhere(t *testing.T) {
                        key: "b", op: ">", match: nil,
                        expect: []map[string]int{},
                },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: "", match: nil,
+                       expect: []map[string]float64{
+                               {"a": 3},
+                       },
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: "!=", match: nil,
+                       expect: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 5, "b": 6},
+                       },
+               },
+               {
+                       seq: []map[string]float64{
+                               {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+                       },
+                       key: "b", op: ">", match: nil,
+                       expect: []map[string]float64{},
+               },
                {
                        seq: []map[string]bool{
                                {"a": true, "b": false}, {"c": true, "b": true}, {"d": true, "b": false},