Skip to content

Commit b589ba5

Browse files
authored
Add method Skip.When() (#123)
Skip.When() determines if all rules following it should be skipped
1 parent 6a5d431 commit b589ba5

File tree

3 files changed

+41
-27
lines changed

3 files changed

+41
-27
lines changed

struct_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,17 @@ func TestValidateStruct(t *testing.T) {
100100
// validatable field
101101
{"t6.1", &m2, []*FieldRules{Field(&m2.E)}, "E: error 123."},
102102
{"t6.2", &m2, []*FieldRules{Field(&m2.E, Skip)}, ""},
103+
{"t6.3", &m2, []*FieldRules{Field(&m2.E, Skip.When(true))}, ""},
104+
{"t6.4", &m2, []*FieldRules{Field(&m2.E, Skip.When(false))}, "E: error 123."},
103105
// Required, NotNil
104106
{"t7.1", &m2, []*FieldRules{Field(&m2.F, Required)}, "F: cannot be blank."},
105107
{"t7.2", &m2, []*FieldRules{Field(&m2.F, NotNil)}, "F: is required."},
106-
{"t7.3", &m2, []*FieldRules{Field(&m2.E, Required, Skip)}, ""},
107-
{"t7.4", &m2, []*FieldRules{Field(&m2.E, NotNil, Skip)}, ""},
108+
{"t7.3", &m2, []*FieldRules{Field(&m2.F, Skip, Required)}, ""},
109+
{"t7.4", &m2, []*FieldRules{Field(&m2.F, Skip, NotNil)}, ""},
110+
{"t7.5", &m2, []*FieldRules{Field(&m2.F, Skip.When(true), Required)}, ""},
111+
{"t7.6", &m2, []*FieldRules{Field(&m2.F, Skip.When(true), NotNil)}, ""},
112+
{"t7.7", &m2, []*FieldRules{Field(&m2.F, Skip.When(false), Required)}, "F: cannot be blank."},
113+
{"t7.8", &m2, []*FieldRules{Field(&m2.F, Skip.When(false), NotNil)}, "F: is required."},
108114
// embedded structs
109115
{"t8.1", &m3, []*FieldRules{Field(&m3.M3, Skip)}, ""},
110116
{"t8.2", &m3, []*FieldRules{Field(&m3.M3)}, "M3: (A: error abc.)."},
@@ -126,9 +132,7 @@ func TestValidateStruct(t *testing.T) {
126132

127133
// embedded struct
128134
err := Validate(&m3)
129-
if assert.NotNil(t, err) {
130-
assert.Equal(t, "A: error abc.", err.Error())
131-
}
135+
assert.EqualError(t, err, "A: error abc.")
132136

133137
a := struct {
134138
Name string
@@ -138,9 +142,7 @@ func TestValidateStruct(t *testing.T) {
138142
Field(&a.Name, Required),
139143
Field(&a.Value, Required, Length(5, 10)),
140144
)
141-
if assert.NotNil(t, err) {
142-
assert.Equal(t, "Value: the length must be between 5 and 10.", err.Error())
143-
}
145+
assert.EqualError(t, err, "Value: the length must be between 5 and 10.")
144146
}
145147

146148
func TestValidateStructWithContext(t *testing.T) {

validation.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ var (
5151
ErrorTag = "json"
5252

5353
// Skip is a special validation rule that indicates all rules following it should be skipped.
54-
Skip = &skipRule{}
54+
Skip = skipRule{skip: true}
5555

5656
validatableType = reflect.TypeOf((*Validatable)(nil)).Elem()
5757
validatableWithContextType = reflect.TypeOf((*ValidatableWithContext)(nil)).Elem()
@@ -67,7 +67,7 @@ var (
6767
// for each element call the element value's `Validate()`. Return with the validation result.
6868
func Validate(value interface{}, rules ...Rule) error {
6969
for _, rule := range rules {
70-
if _, ok := rule.(*skipRule); ok {
70+
if s, ok := rule.(skipRule); ok && s.skip {
7171
return nil
7272
}
7373
if err := rule.Validate(value); err != nil {
@@ -115,7 +115,7 @@ func Validate(value interface{}, rules ...Rule) error {
115115
// for each element call the element value's `Validate()`. Return with the validation result.
116116
func ValidateWithContext(ctx context.Context, value interface{}, rules ...Rule) error {
117117
for _, rule := range rules {
118-
if _, ok := rule.(*skipRule); ok {
118+
if s, ok := rule.(skipRule); ok && s.skip {
119119
return nil
120120
}
121121
if rc, ok := rule.(RuleWithContext); ok {
@@ -228,12 +228,20 @@ func validateSliceWithContext(ctx context.Context, rv reflect.Value) error {
228228
return nil
229229
}
230230

231-
type skipRule struct{}
231+
type skipRule struct {
232+
skip bool
233+
}
232234

233-
func (r *skipRule) Validate(interface{}) error {
235+
func (r skipRule) Validate(interface{}) error {
234236
return nil
235237
}
236238

239+
// When determines if all rules following it should be skipped.
240+
func (r skipRule) When(condition bool) skipRule {
241+
r.skip = condition
242+
return r
243+
}
244+
237245
type inlineRule struct {
238246
f RuleFunc
239247
fc RuleWithContextFunc

validation_test.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,26 @@ func TestValidate(t *testing.T) {
5656

5757
// with rules
5858
err := Validate("123", &validateAbc{}, &validateXyz{})
59-
if assert.NotNil(t, err) {
60-
assert.Equal(t, "error abc", err.Error())
61-
}
59+
assert.EqualError(t, err, "error abc")
6260
err = Validate("abc", &validateAbc{}, &validateXyz{})
63-
if assert.NotNil(t, err) {
64-
assert.Equal(t, "error xyz", err.Error())
65-
}
61+
assert.EqualError(t, err, "error xyz")
6662
err = Validate("abcxyz", &validateAbc{}, &validateXyz{})
67-
assert.Nil(t, err)
63+
assert.NoError(t, err)
6864

6965
err = Validate("123", &validateAbc{}, Skip, &validateXyz{})
70-
if assert.NotNil(t, err) {
71-
assert.Equal(t, "error abc", err.Error())
72-
}
66+
assert.EqualError(t, err, "error abc")
7367
err = Validate("abc", &validateAbc{}, Skip, &validateXyz{})
74-
assert.Nil(t, err)
68+
assert.NoError(t, err)
69+
70+
err = Validate("123", &validateAbc{}, Skip.When(true), &validateXyz{})
71+
assert.EqualError(t, err, "error abc")
72+
err = Validate("abc", &validateAbc{}, Skip.When(true), &validateXyz{})
73+
assert.NoError(t, err)
74+
75+
err = Validate("123", &validateAbc{}, Skip.When(false), &validateXyz{})
76+
assert.EqualError(t, err, "error abc")
77+
err = Validate("abc", &validateAbc{}, Skip.When(false), &validateXyz{})
78+
assert.EqualError(t, err, "error xyz")
7579
}
7680

7781
func stringEqual(str string) RuleFunc {
@@ -131,9 +135,9 @@ func Test_skipRule_Validate(t *testing.T) {
131135

132136
func assertError(t *testing.T, expected string, err error, tag string) {
133137
if expected == "" {
134-
assert.Nil(t, err, tag)
135-
} else if assert.NotNil(t, err, tag) {
136-
assert.Equal(t, expected, err.Error(), tag)
138+
assert.NoError(t, err, tag)
139+
} else {
140+
assert.EqualError(t, err, expected, tag)
137141
}
138142
}
139143

0 commit comments

Comments
 (0)