ref: dd732e84f43570d87dba49a1e42061f8bd4f6afa
parent: 033a13e10e5ef42424db72ae45e01380b0d1e07c
author: Tatsushi Demachi <tdemachi@gmail.com>
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},--
⑨