tpl/collections: Return error on invalid input in in
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 19 Apr 2019 06:58:12 +0000 (08:58 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 19 Apr 2019 06:58:12 +0000 (08:58 +0200)
See #5875

tpl/collections/collections.go
tpl/collections/collections_test.go
tpl/collections/where.go

index 69d0f7042232f45c23ba8bacfad7555f997af72e..3839ad4728a159c9df428f1d9105a5a34d397fc6 100644 (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.
-func (ns *Namespace) In(l interface{}, v interface{}) bool {
+func (ns *Namespace) In(l interface{}, v interface{}) (bool, error) {
        if l == nil || v == nil {
-               return false
+               return false, nil
        }
 
        lv := reflect.ValueOf(l)
        vv := reflect.ValueOf(v)
 
        if !vv.Type().Comparable() {
-               // TODO(bep) consider adding error to the signature.
-               return false
+               return false, errors.Errorf("value to check must be comparable: %T", v)
        }
 
        // Normalize numeric types to float64 etc.
@@ -269,15 +268,15 @@ func (ns *Namespace) In(l interface{}, v interface{}) bool {
                        lvvk := normalize(lvv)
 
                        if lvvk == vvk {
-                               return true
+                               return true, nil
                        }
                }
        case reflect.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
index c87490b2c099a0e71c9e2ace177cfcf9aad2cb4e..137c6fa3a21627ccd965e2e425d77e5920415153 100644 (file)
@@ -313,9 +313,14 @@ func TestIn(t *testing.T) {
 
                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)
        }
+
+       // Slices are not comparable
+       _, err := ns.In([]string{"a", "b"}, []string{"a", "b"})
+       assert.Error(err)
 }
 
 type testPage struct {
index 2c5dc7f3fac025aad9afc0333d5d995eec6a39ba..d515d019fc53e3df2daabec088f3c275e31fcc42 100644 (file)
@@ -225,14 +225,14 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
                var r bool
                switch {
                case ivp != nil && len(ima) > 0:
-                       r = ns.In(ima, *ivp)
+                       r, _ = ns.In(ima, *ivp)
                case fvp != nil && len(fma) > 0:
-                       r = ns.In(fma, *fvp)
+                       r, _ = ns.In(fma, *fvp)
                case svp != nil:
                        if len(sma) > 0 {
-                               r = ns.In(sma, *svp)
+                               r, _ = ns.In(sma, *svp)
                        } else if smvp != nil {
-                               r = ns.In(*smvp, *svp)
+                               r, _ = ns.In(*smvp, *svp)
                        }
                default:
                        return false, nil