Repository: go-playground/validator
Pull request #754 (2021-04-16 23:36:05)

Fix boolean support for required_if, required_unless and eqfield
## Fixes Or Enhances
Closes https://github.com/go-playground/validator/issues/683

**Make sure that you've checked the boxes below before you submit PR:**
- [X] Tests exist or have been written that cover this particular change.

@go-playground/admins

coveralls: 
[![Coverage Status](https://coveralls.io/builds/38900448/badge)](https://coveralls.io/builds/38900448)

Coverage increased (+0.02%) to 76.111% when pulling **ed3c60c9b099eb0e16dd2e2a02c405aeb42cf7ee on zane-deg:master** into **b926bf0df97108effd04f9325365cd7969935e16 on go-playground:master**.

deankarn: Thanks you so much @zane-deg , will take a look as soon as I'm able.

Patch:
diff --git a/baked_in.go b/baked_in.go
index dd25705..78af882 100644
--- a/baked_in.go
+++ b/baked_in.go
@@ -1038,6 +1038,9 @@ func isNeCrossStructField(fl FieldLevel) bool {
 	case reflect.Slice, reflect.Map, reflect.Array:
 		return int64(topField.Len()) != int64(field.Len())
 
+	case reflect.Bool:
+		return topField.Bool() != field.Bool()
+
 	case reflect.Struct:
 
 		fieldType := field.Type()
@@ -1085,6 +1088,9 @@ func isEqCrossStructField(fl FieldLevel) bool {
 	case reflect.Slice, reflect.Map, reflect.Array:
 		return int64(topField.Len()) == int64(field.Len())
 
+	case reflect.Bool:
+		return topField.Bool() == field.Bool()
+
 	case reflect.Struct:
 
 		fieldType := field.Type()
@@ -1132,6 +1138,9 @@ func isEqField(fl FieldLevel) bool {
 	case reflect.Slice, reflect.Map, reflect.Array:
 		return int64(field.Len()) == int64(currentField.Len())
 
+	case reflect.Bool:
+		return field.Bool() == currentField.Bool()
+
 	case reflect.Struct:
 
 		fieldType := field.Type()
@@ -1446,6 +1455,9 @@ func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNo
 
 	case reflect.Slice, reflect.Map, reflect.Array:
 		return int64(field.Len()) == asInt(value)
+
+	case reflect.Bool:
+		return field.Bool() == asBool(value)
 	}
 
 	// default reflect.String:


Test patch:
diff --git a/validator_test.go b/validator_test.go
index 1b2e39b..34232c6 100644
--- a/validator_test.go
+++ b/validator_test.go
@@ -1670,12 +1670,14 @@ func TestCrossStructNeFieldValidation(t *testing.T) {
 	i := 1
 	j = 1
 	k = 1.543
+	b := true
 	arr := []string{"test"}
 
 	s2 := "abcd"
 	i2 := 1
 	j2 = 1
 	k2 = 1.543
+	b2 := true
 	arr2 := []string{"test"}
 	arr3 := []string{"test", "test2"}
 	now2 := now
@@ -1696,6 +1698,10 @@ func TestCrossStructNeFieldValidation(t *testing.T) {
 	NotEqual(t, errs, nil)
 	AssertError(t, errs, "", "", "", "", "necsfield")
 
+	errs = validate.VarWithValue(b2, b, "necsfield")
+	NotEqual(t, errs, nil)
+	AssertError(t, errs, "", "", "", "", "necsfield")
+
 	errs = validate.VarWithValue(arr2, arr, "necsfield")
 	NotEqual(t, errs, nil)
 	AssertError(t, errs, "", "", "", "", "necsfield")
@@ -1834,6 +1840,7 @@ func TestCrossStructEqFieldValidation(t *testing.T) {
 	i := 1
 	j = 1
 	k = 1.543
+	b := true
 	arr := []string{"test"}
 
 	var j2 uint64
@@ -1842,6 +1849,7 @@ func TestCrossStructEqFieldValidation(t *testing.T) {
 	i2 := 1
 	j2 = 1
 	k2 = 1.543
+	b2 := true
 	arr2 := []string{"test"}
 	arr3 := []string{"test", "test2"}
 	now2 := now
@@ -1858,6 +1866,9 @@ func TestCrossStructEqFieldValidation(t *testing.T) {
 	errs = validate.VarWithValue(k2, k, "eqcsfield")
 	Equal(t, errs, nil)
 
+	errs = validate.VarWithValue(b2, b, "eqcsfield")
+	Equal(t, errs, nil)
+
 	errs = validate.VarWithValue(arr2, arr, "eqcsfield")
 	Equal(t, errs, nil)
 
@@ -4829,6 +4840,7 @@ func TestIsEqFieldValidation(t *testing.T) {
 	i := 1
 	j = 1
 	k = 1.543
+	b := true
 	arr := []string{"test"}
 	now := time.Now().UTC()
 
@@ -4838,6 +4850,7 @@ func TestIsEqFieldValidation(t *testing.T) {
 	i2 := 1
 	j2 = 1
 	k2 = 1.543
+	b2 := true
 	arr2 := []string{"test"}
 	arr3 := []string{"test", "test2"}
 	now2 := now
@@ -4854,6 +4867,9 @@ func TestIsEqFieldValidation(t *testing.T) {
 	errs = validate.VarWithValue(k2, k, "eqfield")
 	Equal(t, errs, nil)
 
+	errs = validate.VarWithValue(b2, b, "eqfield")
+	Equal(t, errs, nil)
+
 	errs = validate.VarWithValue(arr2, arr, "eqfield")
 	Equal(t, errs, nil)
 
@@ -10065,12 +10081,15 @@ func TestRequiredUnless(t *testing.T) {
 		Field6  uint              `validate:"required_unless=Field5 2" json:"field_6"`
 		Field7  float32           `validate:"required_unless=Field6 0" json:"field_7"`
 		Field8  float64           `validate:"required_unless=Field7 0.0" json:"field_8"`
+		Field9  bool              `validate:"omitempty" json:"field_9"`
+		Field10 string            `validate:"required_unless=Field9 true" json:"field_10"`
 	}{
 		FieldE: "test",
 		Field2: &fieldVal,
 		Field3: map[string]string{"key": "val"},
 		Field4: "test",
 		Field5: 2,
+		Field9: true,
 	}
 
 	validate := New()
@@ -10090,6 +10109,8 @@ func TestRequiredUnless(t *testing.T) {
 		Field5  string            `validate:"required_unless=Field3 0" json:"field_5"`
 		Field6  string            `validate:"required_unless=Inner.Field test" json:"field_6"`
 		Field7  string            `validate:"required_unless=Inner2.Field test" json:"field_7"`
+		Field8  bool              `validate:"omitempty" json:"field_8"`
+		Field9  string            `validate:"required_unless=Field8 true" json:"field_9"`
 	}{
 		Inner:  &Inner{Field: &fieldVal},
 		FieldE: "test",
@@ -10100,10 +10121,11 @@ func TestRequiredUnless(t *testing.T) {
 	NotEqual(t, errs, nil)
 
 	ve := errs.(ValidationErrors)
-	Equal(t, len(ve), 3)
+	Equal(t, len(ve), 4)
 	AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless")
 	AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless")
 	AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless")
+	AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless")
 
 	defer func() {
 		if r := recover(); r == nil {