shithub: hugo

Download patch

ref: 0c251be66bf3ad4abafbc47583e394ca4e6ffcf1
parent: 836c24261f9f175254256fb326d92a3db47e1c75
author: Tan Yuanhong <leotan.yh@gmail.com>
date: Sun Jan 19 15:52:06 EST 2020

Allow multiple arguments in ne/ge/gt/le/lt functions
Treat op arg1 arg2 arg3 ... as (arg1 op arg2) && (arg1 op arg3)
and so on for ne/ge/gt/le/lt.

Closes #6619

--- a/tpl/compare/compare.go
+++ b/tpl/compare/compare.go
@@ -135,33 +135,58 @@
 	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.
--- a/tpl/compare/compare_test.go
+++ b/tpl/compare/compare_test.go
@@ -149,16 +149,36 @@
 		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)
 	}
@@ -259,6 +279,109 @@
 
 		result := ns.Eq(test.first, test.others...)
 
+		c.Assert(result, qt.Equals, test.expect)
+	}
+}
+
+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)
 	}
 }