forked from go-ozzo/ozzo-validation
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
282 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,70 @@ | ||
// 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 ( | ||
"strings" | ||
) | ||
|
||
// StringIn returns a validation rule that checks if a value can be found in the given list of values. | ||
// == or strings.EqualFold will be used to determine if two values are equal. | ||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty. | ||
func StringIn(isCaseSensitive bool, values ...string) StringInRule { | ||
return StringInRule{ | ||
isCaseSensitive: isCaseSensitive, | ||
elements: values, | ||
err: ErrInInvalid, | ||
} | ||
} | ||
|
||
// StringInRule is a validation rule that validates if a value can be found in the given list of values. | ||
type StringInRule struct { | ||
isCaseSensitive bool | ||
elements []string | ||
err Error | ||
} | ||
|
||
// Validate checks if the given value is valid or not. | ||
func (r StringInRule) Validate(value interface{}) error { | ||
_, isStringPtr := value.(*string) | ||
indirectValue, isNil := Indirect(value) | ||
|
||
if isNil && isStringPtr { | ||
return nil | ||
} | ||
valueAsString, err := EnsureString(indirectValue) | ||
if err != nil { | ||
return err | ||
} | ||
if IsEmpty(indirectValue) { | ||
return nil | ||
} | ||
|
||
for _, e := range r.elements { | ||
if r.isCaseSensitive { | ||
if e == valueAsString { | ||
return nil | ||
} | ||
} else { | ||
if strings.EqualFold(e, valueAsString) { | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
return r.err | ||
} | ||
|
||
// Error sets the error message for the rule. | ||
func (r StringInRule) Error(message string) StringInRule { | ||
r.err = r.err.SetMessage(message) | ||
return r | ||
} | ||
|
||
// ErrorObject sets the error struct for the rule. | ||
func (r StringInRule) ErrorObject(err Error) StringInRule { | ||
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,72 @@ | ||
// 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" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestStringIn(t *testing.T) { | ||
var v1 = "A" | ||
var v2 *string | ||
var v3 = "a" | ||
tests := []struct { | ||
tag string | ||
isCaseSensitive bool | ||
values []string | ||
value interface{} | ||
err string | ||
}{ | ||
{"t0", true, []string{"A", "B"}, "", ""}, | ||
{"t1", true, []string{"A", "B"}, "A", ""}, | ||
{"t2", true, []string{"A", "B"}, "B", ""}, | ||
{"t3", true, []string{"A", "B"}, "C", "must be a valid value"}, | ||
{"t4", true, []string{"A", "B"}, 4, "must be either a string or byte slice"}, | ||
{"t5", true, []string{}, "C", "must be a valid value"}, | ||
{"t6", true, []string{"A", "B"}, &v1, ""}, | ||
{"t7", true, []string{"A", "B"}, v2, ""}, | ||
{"t8", true, []string{"A", "B"}, (*int)(nil), "must be either a string or byte slice"}, | ||
{"t9", false, []string{"A", "B"}, "", ""}, | ||
{"t10", false, []string{"A", "B"}, "A", ""}, | ||
{"t11", false, []string{"A", "B"}, "B", ""}, | ||
{"t12", false, []string{"A", "B"}, "C", "must be a valid value"}, | ||
{"t13", false, []string{"A", "B"}, "a", ""}, | ||
{"t14", false, []string{"A", "B"}, "b", ""}, | ||
{"t15", false, []string{"A", "B"}, "c", "must be a valid value"}, | ||
{"t16", false, []string{"A", "B"}, 4, "must be either a string or byte slice"}, | ||
{"t17", false, []string{}, "c", "must be a valid value"}, | ||
{"t18", false, []string{"A", "B"}, &v3, ""}, | ||
{"t19", false, []string{"A", "B"}, v2, ""}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.tag, func(t *testing.T) { | ||
r := StringIn(test.isCaseSensitive, test.values...) | ||
err := r.Validate(test.value) | ||
assertError(t, test.err, err, test.tag) | ||
}) | ||
} | ||
} | ||
|
||
func Test_StringInRule_Error(t *testing.T) { | ||
r := StringIn(true, "A", "B", "C") | ||
val := "D" | ||
assert.Equal(t, "must be a valid value", r.Validate(val).Error()) | ||
r = r.Error("123") | ||
assert.Equal(t, "123", r.err.Message()) | ||
} | ||
|
||
func TestStringInRule_ErrorObject(t *testing.T) { | ||
r := StringIn(true, "A", "B", "C") | ||
|
||
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()) | ||
} |
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,67 @@ | ||
// Copyright 2018 Qiang Xue, Google LLC. 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 "strings" | ||
|
||
// StringNotIn returns a validation rule that checks if a value is absent from the given list of values. | ||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty. | ||
func StringNotIn(isCaseSensitive bool, values ...string) StringNotInRule { | ||
return StringNotInRule{ | ||
isCaseSensitive: isCaseSensitive, | ||
elements: values, | ||
err: ErrNotInInvalid, | ||
} | ||
} | ||
|
||
// StringNotInRule is a validation rule that checks if a value is absent from the given list of values. | ||
type StringNotInRule struct { | ||
isCaseSensitive bool | ||
elements []string | ||
err Error | ||
} | ||
|
||
// Validate checks if the given value is valid or not. | ||
func (r StringNotInRule) Validate(value interface{}) error { | ||
_, isStringPtr := value.(*string) | ||
indirectValue, isNil := Indirect(value) | ||
|
||
if isNil && isStringPtr { | ||
return nil | ||
} | ||
valueAsString, err := EnsureString(indirectValue) | ||
if err != nil { | ||
return err | ||
} | ||
if IsEmpty(indirectValue) { | ||
return nil | ||
} | ||
|
||
for _, e := range r.elements { | ||
if r.isCaseSensitive { | ||
if e == valueAsString { | ||
return r.err | ||
} | ||
} else { | ||
if strings.EqualFold(e, valueAsString) { | ||
return r.err | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Error sets the error message for the rule. | ||
func (r StringNotInRule) Error(message string) StringNotInRule { | ||
r.err = r.err.SetMessage(message) | ||
return r | ||
} | ||
|
||
// ErrorObject sets the error struct for the rule. | ||
func (r StringNotInRule) ErrorObject(err Error) StringNotInRule { | ||
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,71 @@ | ||
// Copyright 2016 Qiang Xue, Google LLC. 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" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestStringNotIn(t *testing.T) { | ||
var v1 = "A" | ||
var v2 *string | ||
var v3 = "a" | ||
var tests = []struct { | ||
tag string | ||
isCaseSensitive bool | ||
values []string | ||
value interface{} | ||
err string | ||
}{ | ||
{"t0", true, []string{"A", "B"}, "", ""}, | ||
{"t1", true, []string{"A", "B"}, "A", "must not be in list"}, | ||
{"t2", true, []string{"A", "B"}, "B", "must not be in list"}, | ||
{"t3", true, []string{"A", "B"}, "C", ""}, | ||
{"t4", true, []string{"A", "B"}, 4, "must be either a string or byte slice"}, | ||
{"t5", true, []string{}, "C", ""}, | ||
{"t6", true, []string{"A", "B"}, &v1, "must not be in list"}, | ||
{"t7", true, []string{"A", "B"}, v2, ""}, | ||
{"t8", true, []string{"A", "B"}, (*int)(nil), "must be either a string or byte slice"}, | ||
{"t9", false, []string{"A", "B"}, "", ""}, | ||
{"t10", false, []string{"A", "B"}, "A", "must not be in list"}, | ||
{"t11", false, []string{"A", "B"}, "B", "must not be in list"}, | ||
{"t12", false, []string{"A", "B"}, "C", ""}, | ||
{"t13", false, []string{"A", "B"}, "a", "must not be in list"}, | ||
{"t14", false, []string{"A", "B"}, "b", "must not be in list"}, | ||
{"t15", false, []string{"A", "B"}, "c", ""}, | ||
{"t16", false, []string{"A", "B"}, 4, "must be either a string or byte slice"}, | ||
{"t17", false, []string{}, "c", ""}, | ||
{"t18", false, []string{"A", "B"}, &v3, "must not be in list"}, | ||
{"t19", false, []string{"A", "B"}, v2, ""}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.tag, func(t *testing.T) { | ||
r := StringNotIn(test.isCaseSensitive, test.values...) | ||
err := r.Validate(test.value) | ||
assertError(t, test.err, err, test.tag) | ||
}) | ||
} | ||
} | ||
|
||
func Test_StringNotInRule_Error(t *testing.T) { | ||
r := StringNotIn(true, "A", "B", "C") | ||
assert.Equal(t, "must not be in list", r.Validate("A").Error()) | ||
r = r.Error("123") | ||
assert.Equal(t, "123", r.err.Message()) | ||
} | ||
|
||
func TestStringNotInRule_ErrorObject(t *testing.T) { | ||
r := StringNotIn(true, "A", "B", "C") | ||
|
||
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()) | ||
} |