Allow multiple arguments in ne/ge/gt/le/lt functions
authorTan Yuanhong <leotan.yh@gmail.com>
Sun, 19 Jan 2020 12:52:06 +0000 (20:52 +0800)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 23 Jan 2020 09:36:35 +0000 (10:36 +0100)
Treat op arg1 arg2 arg3 ... as (arg1 op arg2) && (arg1 op arg3)
and so on for ne/ge/gt/le/lt.

Closes #6619

tpl/compare/compare.go
tpl/compare/compare_test.go

index ad26559300d91552163eb84f2df0a1fd8673bb59..b5b99ff9af9cc217a74d1af6488269fd602d17da 100644 (file)
@@ -135,33 +135,58 @@ func (n *Namespace) Eq(first interface{}, others ...interface{}) bool {
        return false
 }
 
-// Ne returns the boolean truth of arg1 != arg2.
-func (n *Namespace) Ne(x, y interface{}) bool {
-       return !n.Eq(x, y)
+// Ne returns the boolean truth of arg1 != arg2 && arg1 != arg3 && arg1 != arg4.
+func (n *Namespace) Ne(first interface{}, others ...interface{}) bool {
+       for _, other := range others {
+               if n.Eq(first, other) {
+                       return false
+               }
+       }
+       return true
 }
 
-// Ge returns the boolean truth of arg1 >= arg2.
-func (n *Namespace) Ge(a, b interface{}) bool {
-       left, right := n.compareGet(a, b)
-       return left >= right
+// Ge returns the boolean truth of arg1 >= arg2 && arg1 >= arg3 && arg1 >= arg4.
+func (n *Namespace) Ge(first interface{}, others ...interface{}) bool {
+       for _, other := range others {
+               left, right := n.compareGet(first, other)
+               if !(left >= right) {
+                       return false
+               }
+       }
+       return true
 }
 
-// Gt returns the boolean truth of arg1 > arg2.
-func (n *Namespace) Gt(a, b interface{}) bool {
-       left, right := n.compareGet(a, b)
-       return left > right
+// Gt returns the boolean truth of arg1 > arg2 && arg1 > arg3 && arg1 > arg4.
+func (n *Namespace) Gt(first interface{}, others ...interface{}) bool {
+       for _, other := range others {
+               left, right := n.compareGet(first, other)
+               if !(left > right) {
+                       return false
+               }
+       }
+       return true
 }
 
-// Le returns the boolean truth of arg1 <= arg2.
-func (n *Namespace) Le(a, b interface{}) bool {
-       left, right := n.compareGet(a, b)
-       return left <= right
+// Le returns the boolean truth of arg1 <= arg2 && arg1 <= arg3 && arg1 <= arg4.
+func (n *Namespace) Le(first interface{}, others ...interface{}) bool {
+       for _, other := range others {
+               left, right := n.compareGet(first, other)
+               if !(left <= right) {
+                       return false
+               }
+       }
+       return true
 }
 
-// Lt returns the boolean truth of arg1 < arg2.
-func (n *Namespace) Lt(a, b interface{}) bool {
-       left, right := n.compareGet(a, b)
-       return left < right
+// Lt returns the boolean truth of arg1 < arg2 && arg1 < arg3 && arg1 < arg4.
+func (n *Namespace) Lt(first interface{}, others ...interface{}) bool {
+       for _, other := range others {
+               left, right := n.compareGet(first, other)
+               if !(left < right) {
+                       return false
+               }
+       }
+       return true
 }
 
 // Conditional can be used as a ternary operator.
index fdbcc24bb4e4ea30dec81d36311f1928d3ee8db7..aeadb02f9bd8077a04b7f895471e05adf85ab2a5 100644 (file)
@@ -149,16 +149,36 @@ func TestCompare(t *testing.T) {
                return n.Eq(a, b)
        }
 
+       twoGt := func(a, b interface{}) bool {
+               return n.Gt(a, b)
+       }
+
+       twoLt := func(a, b interface{}) bool {
+               return n.Lt(a, b)
+       }
+
+       twoGe := func(a, b interface{}) bool {
+               return n.Ge(a, b)
+       }
+
+       twoLe := func(a, b interface{}) bool {
+               return n.Le(a, b)
+       }
+
+       twoNe := func(a, b interface{}) bool {
+               return n.Ne(a, b)
+       }
+
        for _, test := range []struct {
                tstCompareType
                funcUnderTest func(a, b interface{}) bool
        }{
-               {tstGt, n.Gt},
-               {tstLt, n.Lt},
-               {tstGe, n.Ge},
-               {tstLe, n.Le},
+               {tstGt, twoGt},
+               {tstLt, twoLt},
+               {tstGe, twoGe},
+               {tstLe, twoLe},
                {tstEq, twoEq},
-               {tstNe, n.Ne},
+               {tstNe, twoNe},
        } {
                doTestCompare(t, test.tstCompareType, test.funcUnderTest)
        }
@@ -263,6 +283,109 @@ func TestEqualExtend(t *testing.T) {
        }
 }
 
+func TestNotEqualExtend(t *testing.T) {
+       t.Parallel()
+       c := qt.New(t)
+
+       ns := New(false)
+
+       for _, test := range []struct {
+               first  interface{}
+               others []interface{}
+               expect bool
+       }{
+               {1, []interface{}{2, 3}, true},
+               {1, []interface{}{2, 1}, false},
+               {1, []interface{}{1, 2}, false},
+       } {
+               result := ns.Ne(test.first, test.others...)
+               c.Assert(result, qt.Equals, test.expect)
+       }
+}
+
+func TestGreaterEqualExtend(t *testing.T) {
+       t.Parallel()
+       c := qt.New(t)
+
+       ns := New(false)
+
+       for _, test := range []struct {
+               first  interface{}
+               others []interface{}
+               expect bool
+       }{
+               {5, []interface{}{2, 3}, true},
+               {5, []interface{}{5, 5}, true},
+               {3, []interface{}{4, 2}, false},
+               {3, []interface{}{2, 4}, false},
+       } {
+               result := ns.Ge(test.first, test.others...)
+               c.Assert(result, qt.Equals, test.expect)
+       }
+}
+
+func TestGreaterThanExtend(t *testing.T) {
+       t.Parallel()
+       c := qt.New(t)
+
+       ns := New(false)
+
+       for _, test := range []struct {
+               first  interface{}
+               others []interface{}
+               expect bool
+       }{
+               {5, []interface{}{2, 3}, true},
+               {5, []interface{}{5, 4}, false},
+               {3, []interface{}{4, 2}, false},
+       } {
+               result := ns.Gt(test.first, test.others...)
+               c.Assert(result, qt.Equals, test.expect)
+       }
+}
+
+func TestLessEqualExtend(t *testing.T) {
+       t.Parallel()
+       c := qt.New(t)
+
+       ns := New(false)
+
+       for _, test := range []struct {
+               first  interface{}
+               others []interface{}
+               expect bool
+       }{
+               {1, []interface{}{2, 3}, true},
+               {1, []interface{}{1, 2}, true},
+               {2, []interface{}{1, 2}, false},
+               {3, []interface{}{2, 4}, false},
+       } {
+               result := ns.Le(test.first, test.others...)
+               c.Assert(result, qt.Equals, test.expect)
+       }
+}
+
+func TestLessThanExtend(t *testing.T) {
+       t.Parallel()
+       c := qt.New(t)
+
+       ns := New(false)
+
+       for _, test := range []struct {
+               first  interface{}
+               others []interface{}
+               expect bool
+       }{
+               {1, []interface{}{2, 3}, true},
+               {1, []interface{}{1, 2}, false},
+               {2, []interface{}{1, 2}, false},
+               {3, []interface{}{2, 4}, false},
+       } {
+               result := ns.Lt(test.first, test.others...)
+               c.Assert(result, qt.Equals, test.expect)
+       }
+}
+
 func TestCase(t *testing.T) {
        c := qt.New(t)
        n := New(true)