diff --git a/after_test.go b/after_test.go index 543c3a2..f54d941 100644 --- a/after_test.go +++ b/after_test.go @@ -41,14 +41,14 @@ func Test_After(t *testing.T) { value: "2022-01-01", afterValue: "2022-02-01", isPassed: false, - msg: "birth_date can't be after 2022-02-01.", - expectedMsg: "birth_date can't be after 2022-02-01.", + msg: "birth_date can't be before 2022-02-01.", + expectedMsg: "birth_date can't be before 2022-02-01.", }, } - v := New() - for _, test := range tests { + v := New() + value, _ := time.Parse("2006-01-02", test.value) afterValue, _ := time.Parse("2006-01-02", test.afterValue) diff --git a/before_test.go b/before_test.go index 5cd582e..526b327 100644 --- a/before_test.go +++ b/before_test.go @@ -46,9 +46,9 @@ func Test_Before(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + value, _ := time.Parse("2006-01-02", test.value) beforeValue, _ := time.Parse("2006-01-02", test.beforeValue) diff --git a/between_test.go b/between_test.go index 4ecaebf..4f79823 100644 --- a/between_test.go +++ b/between_test.go @@ -59,9 +59,9 @@ func Test_BetweenInt(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.BetweenInt(test.value, test.min, test.max, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -132,9 +132,9 @@ func Test_BetweenFloat(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.BetweenFloat(test.value, test.min, test.max, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/date_test.go b/date_test.go index da55c12..4c31160 100644 --- a/date_test.go +++ b/date_test.go @@ -64,9 +64,9 @@ func Test_Date(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.Date(test.layout, test.value, test.field, test.msg) if !test.isPassed { diff --git a/email_test.go b/email_test.go index 46b0d40..0599145 100644 --- a/email_test.go +++ b/email_test.go @@ -57,9 +57,9 @@ func Test_Email(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.Email(test.value, test.field, test.message) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/exists_test.go b/exists_test.go index 03810b1..25a4f13 100644 --- a/exists_test.go +++ b/exists_test.go @@ -81,10 +81,10 @@ func TestValidator_Exists(t *testing.T) { }, } - v := New(). - WithRepo(repo{}) - for _, test := range tests { + v := New(). + WithRepo(repo{}) + v.Exists(test.value, test.table, test.column, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/ip_test.go b/ip_test.go index ee166e6..fed99c5 100644 --- a/ip_test.go +++ b/ip_test.go @@ -57,9 +57,9 @@ func Test_IP4(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.IP4(test.value, test.field, test.message) assert.Equal(t, test.isPassed, v.IsPassed(), test.name) diff --git a/len_test.go b/len_test.go index 67e7dd2..7098d7e 100644 --- a/len_test.go +++ b/len_test.go @@ -45,9 +45,9 @@ func Test_LenString(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.LenString(test.value, test.len, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -104,9 +104,9 @@ func Test_LenInt(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.LenInt(test.value, test.len, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -163,9 +163,9 @@ func Test_LenSlice(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.LenSlice(test.value, test.len, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/makefile b/makefile index c801e2d..74ed36e 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ default: help test: ## run all tests - go test -v ./... + go test -v --race ./... test-one: ## run only tests matching the passed regex as `name` ifdef name diff --git a/max.go b/max.go index 10d17fd..9ce1901 100644 --- a/max.go +++ b/max.go @@ -10,7 +10,7 @@ const ( // MaxMsg is the default error message format for fields with Max validation rule. MaxMsg = "%s should be less than %v" // MaxStringMsg is the default error message format for fields with MaxString validation rule. - MaxStringMsg = "%s should has less than %v characters" + MaxStringMsg = "%s should have less than %v characters" ) // MaxInt checks if the integer value is less than or equal the given max value. @@ -48,7 +48,7 @@ func (v *Validator) MaxFloat(f, max float64, field, msg string) *Validator { // Example: // // v := validator.New() -// v.MaxString("rey", 5, "name", "name should has less than 5 characters.") +// v.MaxString("rey", 5, "name", "name should have less than 5 characters.") // if v.IsFailed() { // fmt.Printf("validation errors: %#v\n", v.Errors()) // } diff --git a/max_test.go b/max_test.go index ae70ad5..af41abd 100644 --- a/max_test.go +++ b/max_test.go @@ -45,9 +45,9 @@ func Test_MaxInt(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.MaxInt(test.value, test.max, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -104,9 +104,9 @@ func Test_MaxFloat64(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.MaxFloat(test.value, test.max, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -159,7 +159,7 @@ func Test_MaxString(t *testing.T) { max: -1, isPassed: false, msg: "", - expectedMsg: "username should has less than -1 characters", + expectedMsg: "username should have less than -1 characters", }, { name: "test `abcd` won't pass validation when maximum valid length is 3", @@ -167,14 +167,14 @@ func Test_MaxString(t *testing.T) { value: "abcd", max: 3, isPassed: false, - msg: "alphabet should has less than 3 characters", - expectedMsg: "alphabet should has less than 3 characters", + msg: "alphabet should have less than 3 characters", + expectedMsg: "alphabet should have less than 3 characters", }, } - v := New() - for _, test := range tests { + v := New() + v.MaxString(test.value, test.max, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/min.go b/min.go index f3c10bc..c50ba9b 100644 --- a/min.go +++ b/min.go @@ -10,7 +10,7 @@ const ( // MinMsg is the default error message format for fields with Min validation rule. MinMsg = "%s should be more than %v" // MinStringMsg is the default error message format for fields with MinString validation rule. - MinStringMsg = "%s should has more than %v characters" + MinStringMsg = "%s should have more than %v characters" ) // MinInt checks if the given integer value is greater than or equal the given min value. @@ -48,7 +48,7 @@ func (v *Validator) MinFloat(f, min float64, field, msg string) *Validator { // Example: // // v := validator.New() -// v.MinString("rey", 5, "name", "name should has more than 5 characters.") +// v.MinString("rey", 5, "name", "name should have more than 5 characters.") // if v.IsFailed() { // fmt.Printf("validation errors: %#v\n", v.Errors()) // } diff --git a/min_test.go b/min_test.go index 154532b..5262633 100644 --- a/min_test.go +++ b/min_test.go @@ -45,9 +45,9 @@ func Test_MinInt(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.MinInt(test.value, test.min, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -113,9 +113,9 @@ func Test_MinFloat(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.MinFloat(test.value, test.min, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -159,7 +159,7 @@ func Test_MinString(t *testing.T) { min: 5, isPassed: false, msg: "", - expectedMsg: "username should has more than 5 characters", + expectedMsg: "username should have more than 5 characters", }, { name: "test empty space string won't pass validation when minimum valid length is 2", @@ -168,7 +168,7 @@ func Test_MinString(t *testing.T) { min: 2, isPassed: false, msg: "", - expectedMsg: "username should has more than 2 characters", + expectedMsg: "username should have more than 2 characters", }, { name: "test `abcd` won't pass validation when minimum valid length is 7", @@ -176,14 +176,14 @@ func Test_MinString(t *testing.T) { value: "abcd", min: 7, isPassed: false, - msg: "alphabet should has more than 7 characters", - expectedMsg: "alphabet should has more than 7 characters", + msg: "alphabet should have more than 7 characters", + expectedMsg: "alphabet should have more than 7 characters", }, } - v := New() - for _, test := range tests { + v := New() + v.MinString(test.value, test.min, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/notexists_test.go b/notexists_test.go index f1705cd..351b2b1 100644 --- a/notexists_test.go +++ b/notexists_test.go @@ -49,10 +49,10 @@ func Test_NotExists(t *testing.T) { }, } - v := New(). - WithRepo(repo{}) - for _, test := range tests { + v := New(). + WithRepo(repo{}) + v.NotExists(test.value, test.table, test.column, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/regex_test.go b/regex_test.go index 5962d6b..77bd8cd 100644 --- a/regex_test.go +++ b/regex_test.go @@ -63,9 +63,9 @@ func Test_RegexMatches(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.RegexMatches(test.value, test.pattern, test.field, test.message) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/required_test.go b/required_test.go index a965ffd..1f40b01 100644 --- a/required_test.go +++ b/required_test.go @@ -41,9 +41,9 @@ func Test_RequiredInt(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.RequiredInt(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -104,9 +104,9 @@ func Test_RequiredString(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.RequiredString(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -159,9 +159,9 @@ func Test_RequiredFloat(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.RequiredFloat(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) @@ -222,9 +222,9 @@ func Test_RequiredSlice(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.RequiredSlice(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/url_test.go b/url_test.go index 1f2e135..1f8a730 100644 --- a/url_test.go +++ b/url_test.go @@ -73,9 +73,9 @@ func Test_Url(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.URL(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed(), test.name) diff --git a/uuid_test.go b/uuid_test.go index 2c04a3d..dffe950 100644 --- a/uuid_test.go +++ b/uuid_test.go @@ -57,9 +57,9 @@ func Test_UUID(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + v.UUID(test.value, test.field, test.msg) assert.Equal(t, test.isPassed, v.IsPassed()) diff --git a/validator.go b/validator.go index 51a3f72..934f38b 100644 --- a/validator.go +++ b/validator.go @@ -4,28 +4,23 @@ package govalidator import ( "errors" "fmt" - "maps" ) type ( - // Err is the defined type which will be returned when one or many validator rules fail. - Err = map[string]string - // Validator represents the validator structure - Validator struct { - repo Repository - } - // Repository represent a repository for using in rules that needs a database connection to // check a record exists on database or not. Repository interface { Exists(value any, table, column string) bool } + + // Validator represents the validator structure + Validator struct { + errs map[string]string + repo Repository + } ) var ( - // errs is a map of errors which has all of failed rule messages. - errs = make(Err) - // methodToErrorMessage contains each validation method and its corresponding error message. methodToErrorMessage = map[string]string{ Required: RequiredMsg, @@ -54,7 +49,9 @@ var ( // New will return a new validator func New() *Validator { - return &Validator{} + return &Validator{ + errs: make(map[string]string), + } } // WithRepo sets the desired repository for use in the Exists validation rule. @@ -70,7 +67,7 @@ func (v *Validator) WithRepo(r Repository) *Validator { // IsPassed checks if the validator result has passed or not. func (v *Validator) IsPassed() bool { - return len(errs) == 0 + return len(v.Errors()) == 0 } // IsFailed checks if the validator result has failed or not. @@ -79,12 +76,8 @@ func (v *Validator) IsFailed() bool { } // Errors returns a map of all validator rule errors. -func (v *Validator) Errors() Err { - vErrs := maps.Clone(errs) - - errs = make(map[string]string) - - return vErrs +func (v *Validator) Errors() map[string]string { + return v.errs } // Check is a dynamic method to define any custom validator rule by passing a rule as a function or expression @@ -97,8 +90,8 @@ func (v *Validator) Check(ok bool, field, msg string) { // addError fills the errors map and prevents duplicate fields from being added to validator errors. func (v *Validator) addError(field, msg string) { - if _, exists := errs[field]; !exists { - errs[field] = msg + if _, exists := v.Errors()[field]; !exists { + v.Errors()[field] = msg } } diff --git a/validator_test.go b/validator_test.go index b8db477..7b063a4 100644 --- a/validator_test.go +++ b/validator_test.go @@ -33,9 +33,9 @@ func Test_msg(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + assert.PanicsWithError(t, test.expectedMsg, func() { v.msg(test.method, test.msg) }) } } diff --git a/when_test.go b/when_test.go index c369dfa..85125b6 100644 --- a/when_test.go +++ b/when_test.go @@ -29,9 +29,9 @@ func Test_When(t *testing.T) { }, } - v := New() - for _, test := range tests { + v := New() + executed := false v.When(test.condition, func() {