tpl/collections: Return error on invalid input in in

See #5875
This commit is contained in:
Bjørn Erik Pedersen 2019-04-19 08:58:12 +02:00
parent 06f56fc983
commit 7fbfedf013
No known key found for this signature in database
GPG key ID: 330E6E2BD4859D8F
3 changed files with 16 additions and 12 deletions

View file

@ -242,17 +242,16 @@ func (ns *Namespace) First(limit interface{}, seq interface{}) (interface{}, err
} }
// In returns whether v is in the set l. l may be an array or slice. // In returns whether v is in the set l. l may be an array or slice.
func (ns *Namespace) In(l interface{}, v interface{}) bool { func (ns *Namespace) In(l interface{}, v interface{}) (bool, error) {
if l == nil || v == nil { if l == nil || v == nil {
return false return false, nil
} }
lv := reflect.ValueOf(l) lv := reflect.ValueOf(l)
vv := reflect.ValueOf(v) vv := reflect.ValueOf(v)
if !vv.Type().Comparable() { if !vv.Type().Comparable() {
// TODO(bep) consider adding error to the signature. return false, errors.Errorf("value to check must be comparable: %T", v)
return false
} }
// Normalize numeric types to float64 etc. // Normalize numeric types to float64 etc.
@ -269,15 +268,15 @@ func (ns *Namespace) In(l interface{}, v interface{}) bool {
lvvk := normalize(lvv) lvvk := normalize(lvv)
if lvvk == vvk { if lvvk == vvk {
return true return true, nil
} }
} }
case reflect.String: case reflect.String:
if vv.Type() == lv.Type() && strings.Contains(lv.String(), vv.String()) { if vv.Type() == lv.Type() && strings.Contains(lv.String(), vv.String()) {
return true return true, nil
} }
} }
return false return false, nil
} }
// Intersect returns the common elements in the given sets, l1 and l2. l1 and // Intersect returns the common elements in the given sets, l1 and l2. l1 and

View file

@ -313,9 +313,14 @@ func TestIn(t *testing.T) {
errMsg := fmt.Sprintf("[%d] %v", i, test) errMsg := fmt.Sprintf("[%d] %v", i, test)
result := ns.In(test.l1, test.l2) result, err := ns.In(test.l1, test.l2)
assert.NoError(err)
assert.Equal(test.expect, result, errMsg) assert.Equal(test.expect, result, errMsg)
} }
// Slices are not comparable
_, err := ns.In([]string{"a", "b"}, []string{"a", "b"})
assert.Error(err)
} }
type testPage struct { type testPage struct {

View file

@ -225,14 +225,14 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
var r bool var r bool
switch { switch {
case ivp != nil && len(ima) > 0: case ivp != nil && len(ima) > 0:
r = ns.In(ima, *ivp) r, _ = ns.In(ima, *ivp)
case fvp != nil && len(fma) > 0: case fvp != nil && len(fma) > 0:
r = ns.In(fma, *fvp) r, _ = ns.In(fma, *fvp)
case svp != nil: 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)
} }
default: default:
return false, nil return false, nil