-
Notifications
You must be signed in to change notification settings - Fork 4
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
14 changed files
with
687 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package govals | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
// CustomValidate is validate data value | ||
// with custom rule, your can write your regexp custom rule | ||
func CustomValidate(val string, rule string) (bool, error) { | ||
return checkRule(val, rule) | ||
} | ||
|
||
func (d *customValRule) validate() (bool, error) { | ||
if d.count > 0 { | ||
if d.tagType.Type.Kind() != reflect.String { | ||
return false, fmt.Errorf("invalid value type, value type must be string") | ||
} | ||
val := d.val.String() | ||
return checkRule(val, d.rule) | ||
} | ||
return false, nil | ||
} |
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,34 @@ | ||
package govals | ||
|
||
import "testing" | ||
|
||
func TestCustomValidate(t *testing.T) { | ||
tc := []struct { | ||
name string | ||
val string | ||
rule string | ||
err error | ||
}{ | ||
{name: "valid test", val: "ludinnento", rule: "^[a-zA-Z]*$"}, | ||
{name: "empty value", val: "", rule: "^[a-zA-Z]*$", err: errEmptyValue}, | ||
{name: "invalid value", val: "ludin1233", rule: "^[a-zA-Z]*$", err: errInvalidFormat}, | ||
{name: "invalid rule", val: "ludin", rule: "^[a-zA-Z", err: errInvalidRuleFormat}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := CustomValidate(tt.val, tt.rule) | ||
if tt.err != nil { | ||
if tt.err != err { | ||
t.Errorf("error value expects %v got %v\n", tt.err, err) | ||
} | ||
return | ||
} | ||
|
||
if !ok { | ||
t.Errorf("%s invalid result", tt.val) | ||
} | ||
}) | ||
} | ||
|
||
} |
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,93 @@ | ||
package govals | ||
|
||
import ( | ||
"regexp" | ||
) | ||
|
||
// Email validate string if is valid email format, | ||
// this function return bool and error | ||
// if value does not valid | ||
func Email(s string) (bool, error) { | ||
return checkRule(s, emailRules) | ||
} | ||
|
||
// Numeric validate string contains digits only [0-9] | ||
// this function return bool and error | ||
// if value does not valid | ||
func Numeric(s string) (bool, error) { | ||
return checkRule(s, numericRule) | ||
} | ||
|
||
// Alpha validate string contains letters only [a-zA-Z] | ||
// this function return bool and error | ||
// if value does not valid | ||
func Alpha(s string) (bool, error) { | ||
return checkRule(s, alphaRule) | ||
} | ||
|
||
// AlphaNumeric validate string contains letters | ||
// and number only [a-zA-Z0-9] | ||
// this function return bool and error | ||
// if value does not valid | ||
func AlphaNumeric(s string) (bool, error) { | ||
return checkRule(s, alphaNumericRule) | ||
} | ||
|
||
// Date checking string format as date | ||
// like mm-dd-yyyy or mm/dd/yyyy | ||
// this function return bool and error | ||
// if value does not valid | ||
func Date(s string) (bool, error) { | ||
return checkRule(s, dateRule) | ||
} | ||
|
||
// Times checking string format time | ||
// like 12:00:01 or 12:00 | ||
func Times(s string) (bool, error) { | ||
return checkRule(s, timeRule) | ||
} | ||
|
||
// PhoneNumber checking string match phone number | ||
// like +62828882888 or 082323333333 | ||
// this function return bool and error | ||
// if value does not valid | ||
func PhoneNumber(s string) (bool, error) { | ||
return checkRule(s, phoneNumberRule) | ||
} | ||
|
||
func (d *defaultValsRule) validate() (bool, error) { | ||
val := d.val.String() | ||
switch d.tag { | ||
case "email": | ||
return checkRule(val, emailRules) | ||
case "time": | ||
return checkRule(val, timeRule) | ||
case "date": | ||
return checkRule(val, dateRule) | ||
case "alpha": | ||
return checkRule(val, alphaRule) | ||
case "numeric": | ||
return checkRule(val, numericRule) | ||
case "alphaNumeric": | ||
return checkRule(val, alphaNumericRule) | ||
case "phone": | ||
return checkRule(val, phoneNumberRule) | ||
} | ||
return true, nil | ||
|
||
} | ||
|
||
func checkRule(s, rule string) (bool, error) { | ||
if len(s) == 0 { | ||
return false, errEmptyValue | ||
} | ||
re, err := regexp.Compile(rule) | ||
if err != nil { | ||
return false, errInvalidRuleFormat | ||
} | ||
ok := re.MatchString(s) | ||
if !ok { | ||
return false, errInvalidFormat | ||
} | ||
return ok, nil | ||
} |
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,147 @@ | ||
package govals | ||
|
||
import "testing" | ||
|
||
type testCase struct { | ||
name string | ||
val string | ||
err error | ||
} | ||
|
||
func TestEmail(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid email", val: "[email protected]"}, | ||
{name: "invalid email", val: "ludyyn$$##gmail.com", err: errInvalidFormat}, | ||
{name: "empty email", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := Email(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error email expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
|
||
func TestNumeric(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid numeric", val: "122323"}, | ||
{name: "invalid numeric", val: "23dsdfdfsdf", err: errInvalidFormat}, | ||
{name: "empty numeric", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := Numeric(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error numeric expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
|
||
func TestAlpha(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid alpha", val: "Ludin Nento"}, | ||
{name: "invalid alpha", val: "sdfnj23434", err: errInvalidFormat}, | ||
{name: "empty alpha", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := Alpha(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error alpha expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
func TestAlphaNumeric(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid alpha numeric", val: "Ludin Nento2323"}, | ||
{name: "invalid alpha numeric", val: "sdfnj23434^^&9", err: errInvalidFormat}, | ||
{name: "empty alpha numeric", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := AlphaNumeric(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error alpha numeric expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
|
||
func TestDate(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid date", val: "12-12-1996"}, | ||
{name: "invalid date", val: "12-", err: errInvalidFormat}, | ||
{name: "empty date", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := Date(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error date expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
|
||
func TestTimes(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid time", val: "12:12:01"}, | ||
{name: "invalid time", val: "12:", err: errInvalidFormat}, | ||
{name: "empty time", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := Times(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error time expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} | ||
func TestPhoneNumber(t *testing.T) { | ||
tc := []testCase{ | ||
{name: "valid phone number", val: "+6282290202728"}, | ||
{name: "invalid phone number", val: "12--&&809098^^%$:", err: errInvalidFormat}, | ||
{name: "empty phone number", val: "", err: errEmptyValue}, | ||
} | ||
|
||
for _, tt := range tc { | ||
t.Run(tt.name, func(t *testing.T) { | ||
ok, err := PhoneNumber(tt.val) | ||
if tt.err != nil { | ||
if tt.err != err && !ok { | ||
t.Errorf("error phone number expects %v, got %v\n", tt.err, err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
} |
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,12 @@ | ||
package govals | ||
|
||
import ( | ||
"errors" | ||
) | ||
|
||
var ( | ||
errFieldNotResgister = errors.New("field is not register") | ||
errEmptyValue = errors.New("value cannot be empty") | ||
errInvalidFormat = errors.New("value format is invalid") | ||
errInvalidRuleFormat = errors.New("Rule format is invalid") | ||
) |
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,3 @@ | ||
module github.com/fn-code/govals | ||
|
||
go 1.12 |
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,55 @@ | ||
package govals | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"strconv" | ||
) | ||
|
||
// RuneLength is validate text length | ||
func RuneLength(s string, min, max int) (bool, error) { | ||
return minMax(s, min, max) | ||
} | ||
|
||
// Length is validate number length | ||
func Length(s int, min, max int) (bool, error) { | ||
num := strconv.Itoa(s) | ||
return minMax(num, min, max) | ||
} | ||
|
||
func (d *lengthValsRule) validate() (ok bool, err error) { | ||
|
||
switch d.tagType.Type.Kind() { | ||
case reflect.String: | ||
val := d.val.String() | ||
if d.count > 1 { | ||
return minMax(val, d.min, d.max) | ||
} | ||
|
||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||
val := d.val.Int() | ||
if d.count > 1 { | ||
return minMax(strconv.Itoa(int(val)), d.min, d.max) | ||
} | ||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||
val := d.val.Uint() | ||
return minMax(strconv.Itoa(int(val)), d.min, d.max) | ||
} | ||
return true, nil | ||
} | ||
|
||
func minMax(s string, min, max int) (bool, error) { | ||
if len(s) == 0 { | ||
return false, errEmptyValue | ||
} | ||
if min > max { | ||
return false, fmt.Errorf("invalid rule, min must less than max") | ||
} | ||
if len(s) < min { | ||
return false, fmt.Errorf("value must greater than %d", min) | ||
} | ||
if len(s) > max { | ||
return false, fmt.Errorf("value must less than %d", max) | ||
} | ||
return true, nil | ||
} |
Oops, something went wrong.