forked from go-ozzo/ozzo-validation
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds support for 'Nil' and 'Empty' rules (go-ozzo#106)
- Loading branch information
Showing
3 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright 2016 Qiang Xue. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package validation | ||
|
||
var ( | ||
// ErrNil is the error that returns when a value is not nil. | ||
ErrNil = NewError("validation_nil", "must be blank") | ||
// ErrEmpty is the error that returns when a not nil value is not empty. | ||
ErrEmpty = NewError("validation_empty", "must be blank") | ||
) | ||
|
||
// Nil is a validation rule that checks if a value is nil. | ||
// It is the opposite of NotNil rule | ||
var Nil = absentRule{err: ErrNil, condition: true, skipNil: false} | ||
|
||
// Empty checks if a not nil value is empty. | ||
var Empty = absentRule{err: ErrEmpty, condition: true, skipNil: true} | ||
|
||
type absentRule struct { | ||
condition bool | ||
err Error | ||
skipNil bool | ||
} | ||
|
||
// Validate checks if the given value is valid or not. | ||
func (r absentRule) Validate(value interface{}) error { | ||
if r.condition { | ||
value, isNil := Indirect(value) | ||
if r.skipNil == false && isNil == false { | ||
return r.err | ||
} | ||
if isNil { | ||
return nil | ||
} | ||
if !IsEmpty(value) { | ||
return r.err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// When sets the condition that determines if the validation should be performed. | ||
func (r absentRule) When(condition bool) absentRule { | ||
r.condition = condition | ||
return r | ||
} | ||
|
||
// Error sets the error message for the rule. | ||
func (r absentRule) Error(message string) absentRule { | ||
r.err = r.err.SetMessage(message) | ||
return r | ||
} | ||
|
||
// ErrorObject sets the error struct for the rule. | ||
func (r absentRule) ErrorObject(err Error) absentRule { | ||
r.err = err | ||
return r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2016 Qiang Xue. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package validation | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestNil(t *testing.T) { | ||
s1 := "123" | ||
s2 := "" | ||
var time1 time.Time | ||
tests := []struct { | ||
tag string | ||
value interface{} | ||
err string | ||
}{ | ||
{"t1", 123, "must be blank"}, | ||
{"t2", "", "must be blank"}, | ||
{"t3", &s1, "must be blank"}, | ||
{"t4", &s2, "must be blank"}, | ||
{"t5", nil, ""}, | ||
{"t6", time1, "must be blank"}, | ||
} | ||
|
||
for _, test := range tests { | ||
r := Nil | ||
err := r.Validate(test.value) | ||
assertError(t, test.err, err, test.tag) | ||
} | ||
} | ||
|
||
func TestEmpty(t *testing.T) { | ||
s1 := "123" | ||
s2 := "" | ||
time1 := time.Now() | ||
var time2 time.Time | ||
tests := []struct { | ||
tag string | ||
value interface{} | ||
err string | ||
}{ | ||
{"t1", 123, "must be blank"}, | ||
{"t2", "", ""}, | ||
{"t3", &s1, "must be blank"}, | ||
{"t4", &s2, ""}, | ||
{"t5", nil, ""}, | ||
{"t6", time1, "must be blank"}, | ||
{"t7", time2, ""}, | ||
} | ||
|
||
for _, test := range tests { | ||
r := Empty | ||
err := r.Validate(test.value) | ||
assertError(t, test.err, err, test.tag) | ||
} | ||
} | ||
|
||
func TestAbsentRule_When(t *testing.T) { | ||
r := Nil.When(false) | ||
err := Validate(42, r) | ||
assert.Nil(t, err) | ||
|
||
r = Nil.When(true) | ||
err = Validate(42, r) | ||
assert.Equal(t, ErrNil, err) | ||
} | ||
|
||
func Test_absentRule_Error(t *testing.T) { | ||
r := Nil | ||
assert.Equal(t, "must be blank", r.Validate("42").Error()) | ||
assert.False(t, r.skipNil) | ||
r2 := r.Error("123") | ||
assert.Equal(t, "must be blank", r.Validate("42").Error()) | ||
assert.False(t, r.skipNil) | ||
assert.Equal(t, "123", r2.err.Message()) | ||
assert.False(t, r2.skipNil) | ||
|
||
r = Empty | ||
assert.Equal(t, "must be blank", r.Validate("42").Error()) | ||
assert.True(t, r.skipNil) | ||
r2 = r.Error("123") | ||
assert.Equal(t, "must be blank", r.Validate("42").Error()) | ||
assert.True(t, r.skipNil) | ||
assert.Equal(t, "123", r2.err.Message()) | ||
assert.True(t, r2.skipNil) | ||
} | ||
|
||
func TestAbsentRule_Error(t *testing.T) { | ||
r := Nil | ||
|
||
err := NewError("code", "abc") | ||
r = r.ErrorObject(err) | ||
|
||
assert.Equal(t, err, r.err) | ||
assert.Equal(t, err.Code(), r.err.Code()) | ||
assert.Equal(t, err.Message(), r.err.Message()) | ||
assert.NotEqual(t, err, Nil.err) | ||
} |