ref: dd732e84f43570d87dba49a1e42061f8bd4f6afa
parent: 033a13e10e5ef42424db72ae45e01380b0d1e07c
author: Tatsushi Demachi <[email protected]>
date: Sat Jun 27 22:15:42 EDT 2015
Add nil comparison to where tpl function `where` template function's internal condition check function always returns `false` when a target value doesn't exist or it's nil value but this behavior makes it difficult to filter values which doesn't have a particular parameter. To solve it, this adds nil value comparison to the function. `where Values ".Param.key" nil` like clause can be used for the case above. Only "=", "==", "eq", "!=", "<>", "ne" operators are allowed to be used with `nil`. If an other operator is passed with `nil`, the condition check function returns `false` like before. Fix #1232
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -536,17 +536,21 @@
}
func checkCondition(v, mv reflect.Value, op string) (bool, error) {
- if !v.IsValid() || !mv.IsValid() {
- return false, nil
+ v, vIsNil := indirect(v)
+ if !v.IsValid() {
+ vIsNil = true
}
-
- var isNil bool
- v, isNil = indirect(v)
- if isNil {
- return false, nil
+ mv, mvIsNil := indirect(mv)
+ if !mv.IsValid() {
+ mvIsNil = true
}
- mv, isNil = indirect(mv)
- if isNil {
+ if vIsNil || mvIsNil {
+ switch op {
+ case "", "=", "==", "eq":
+ return vIsNil == mvIsNil, nil
+ case "!=", "<>", "ne":
+ return vIsNil != mvIsNil, nil
+ }
return false, nil
}
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -673,6 +673,7 @@
"",
expect{true, false},
},
+ {reflect.ValueOf(nil), reflect.ValueOf(nil), "", expect{true, false}},
{reflect.ValueOf(123), reflect.ValueOf(456), "!=", expect{true, false}},
{reflect.ValueOf("foo"), reflect.ValueOf("bar"), "!=", expect{true, false}},
{
@@ -681,6 +682,7 @@
"!=",
expect{true, false},
},
+ {reflect.ValueOf(123), reflect.ValueOf(nil), "!=", expect{true, false}},
{reflect.ValueOf(456), reflect.ValueOf(123), ">=", expect{true, false}},
{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">=", expect{true, false}},
{
@@ -942,6 +944,31 @@
expect: []TstX{
{A: "a", B: "b"}, {A: "e", B: "f"},
},
+ },
+ {
+ sequence: []map[string]int{
+ {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+ },
+ key: "b", op: "", match: nil,
+ expect: []map[string]int{
+ {"a": 3},
+ },
+ },
+ {
+ sequence: []map[string]int{
+ {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+ },
+ key: "b", op: "!=", match: nil,
+ expect: []map[string]int{
+ {"a": 1, "b": 2}, {"a": 5, "b": 6},
+ },
+ },
+ {
+ sequence: []map[string]int{
+ {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
+ },
+ key: "b", op: ">", match: nil,
+ expect: []map[string]int{},
},
{sequence: (*[]TstX)(nil), key: "A", match: "a", expect: false},
{sequence: TstX{A: "a", B: "b"}, key: "A", match: "a", expect: false},