tpl/collections: Add float64 support to where

Fixes #5466
This commit is contained in:
Cameron Moore 2018-11-26 18:40:35 -06:00 committed by Bjørn Erik Pedersen
parent 94ab125b27
commit 112461fded
2 changed files with 145 additions and 15 deletions

View file

@ -79,9 +79,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
} }
var ivp, imvp *int64 var ivp, imvp *int64
var fvp, fmvp *float64
var svp, smvp *string var svp, smvp *string
var slv, slmv interface{} var slv, slmv interface{}
var ima []int64 var ima []int64
var fma []float64
var sma []string var sma []string
if mv.Type() == v.Type() { if mv.Type() == v.Type() {
switch v.Kind() { switch v.Kind() {
@ -95,6 +97,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
svp = &sv svp = &sv
smv := mv.String() smv := mv.String()
smvp = &smv smvp = &smv
case reflect.Float64:
fv := v.Float()
fvp = &fv
fmv := mv.Float()
fmvp = &fmv
case reflect.Struct: case reflect.Struct:
switch v.Type() { switch v.Type() {
case timeType: case timeType:
@ -136,6 +143,14 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
sma = append(sma, aString) 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: case reflect.Struct:
switch v.Type() { switch v.Type() {
case timeType: case timeType:
@ -153,52 +168,73 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
switch op { switch op {
case "", "=", "==", "eq": case "", "=", "==", "eq":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp == *imvp, nil return *ivp == *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp == *smvp, nil return *svp == *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp == *fmvp, nil
} }
case "!=", "<>", "ne": case "!=", "<>", "ne":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp != *imvp, nil return *ivp != *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp != *smvp, nil return *svp != *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp != *fmvp, nil
} }
case ">=", "ge": case ">=", "ge":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp >= *imvp, nil return *ivp >= *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp >= *smvp, nil return *svp >= *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp >= *fmvp, nil
} }
case ">", "gt": case ">", "gt":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp > *imvp, nil return *ivp > *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp > *smvp, nil return *svp > *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp > *fmvp, nil
} }
case "<=", "le": case "<=", "le":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp <= *imvp, nil return *ivp <= *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp <= *smvp, nil return *svp <= *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp <= *fmvp, nil
} }
case "<", "lt": case "<", "lt":
if ivp != nil && imvp != nil { switch {
case ivp != nil && imvp != nil:
return *ivp < *imvp, nil return *ivp < *imvp, nil
} else if svp != nil && smvp != nil { case svp != nil && smvp != nil:
return *svp < *smvp, nil return *svp < *smvp, nil
case fvp != nil && fmvp != nil:
return *fvp < *fmvp, nil
} }
case "in", "not in": case "in", "not in":
var r bool var r bool
if ivp != nil && len(ima) > 0 { switch {
case ivp != nil && len(ima) > 0:
r = ns.In(ima, *ivp) 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 { if len(sma) > 0 {
r = ns.In(sma, *svp) r = ns.In(sma, *svp)
} else if smvp != nil { } else if smvp != nil {
r = ns.In(*smvp, *svp) r = ns.In(*smvp, *svp)
} }
} else { default:
return false, nil return false, nil
} }
if op == "not in" { if op == "not in" {

View file

@ -63,6 +63,48 @@ func TestWhere(t *testing.T) {
{"a": 3, "b": 4}, {"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{ seq: []TstX{
{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}, {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}, {"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{ seq: []TstX{
{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}, {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}, {"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{ 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"}}, {"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}, {"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{ seq: []map[string]time.Time{
{"a": d1, "b": d2}, {"a": d3, "b": d4}, {"a": d5, "b": d6}, {"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, key: "b", op: ">", match: nil,
expect: []map[string]int{}, 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{ seq: []map[string]bool{
{"a": true, "b": false}, {"c": true, "b": true}, {"d": true, "b": false}, {"a": true, "b": false}, {"c": true, "b": true}, {"d": true, "b": false},