From 7aa70841bcfc0a4b9ba8f0a7c182c72bef89878e Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Wed, 17 Jun 2015 08:03:31 -0400 Subject: [PATCH] add uuid, uuid3, uuid4 and uuid5 validators + tests + documentation --- baked_in.go | 20 ++++++++ doc.go | 16 +++++++ regexes.go | 8 ++++ validator_test.go | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+) diff --git a/baked_in.go b/baked_in.go index 50c0c19..da5933e 100644 --- a/baked_in.go +++ b/baked_in.go @@ -53,6 +53,26 @@ var BakedInValidators = map[string]Func{ "isbn": isISBN, "isbn10": isISBN10, "isbn13": isISBN13, + "uuid": isUUID, + "uuid3": isUUID3, + "uuid4": isUUID4, + "uuid5": isUUID5, +} + +func isUUID5(top interface{}, current interface{}, field interface{}, param string) bool { + return matchesRegex(uUID5Regex, field) +} + +func isUUID4(top interface{}, current interface{}, field interface{}, param string) bool { + return matchesRegex(uUID4Regex, field) +} + +func isUUID3(top interface{}, current interface{}, field interface{}, param string) bool { + return matchesRegex(uUID3Regex, field) +} + +func isUUID(top interface{}, current interface{}, field interface{}, param string) bool { + return matchesRegex(uUIDRegex, field) } func isISBN(top interface{}, current interface{}, field interface{}, param string) bool { diff --git a/doc.go b/doc.go index 55d325d..5c8b44b 100644 --- a/doc.go +++ b/doc.go @@ -374,6 +374,22 @@ Here is a list of the current built in validators: This validates that a string value contains a valid isbn13 value. (Usage: isbn13) + uuid + This validates that a string value contains a valid UUID. + (Usage: uuid) + + uuid3 + This validates that a string value contains a valid version 3 UUID. + (Usage: uuid3) + + uuid4 + This validates that a string value contains a valid version 4 UUID. + (Usage: uuid4) + + uuid5 + This validates that a string value contains a valid version 5 UUID. + (Usage: uuid5) + Validator notes: regex diff --git a/regexes.go b/regexes.go index 984ffbd..d8c22cc 100644 --- a/regexes.go +++ b/regexes.go @@ -17,6 +17,10 @@ const ( base64RegexString = "(?:^(?:[A-Za-z0-9+\\/]{4}\\n?)*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=)$)" iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$" iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$" + uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" + uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" ) var ( @@ -34,6 +38,10 @@ var ( base64Regex = regexp.MustCompile(base64RegexString) iSBN10Regex = regexp.MustCompile(iSBN10RegexString) iSBN13Regex = regexp.MustCompile(iSBN13RegexString) + uUID3Regex = regexp.MustCompile(uUID3RegexString) + uUID4Regex = regexp.MustCompile(uUID4RegexString) + uUID5Regex = regexp.MustCompile(uUID5RegexString) + uUIDRegex = regexp.MustCompile(uUIDRegexString) ) func matchesRegex(regex *regexp.Regexp, field interface{}) bool { diff --git a/validator_test.go b/validator_test.go index dc0a1e3..ba7eb5c 100644 --- a/validator_test.go +++ b/validator_test.go @@ -226,6 +226,124 @@ func AssertMapFieldError(t *testing.T, s map[string]*FieldError, field string, e EqualSkip(t, 2, val.Tag, expectedTag) } +func TestUUID5Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"9c858901-8a57-4791-81fe-4c455b099bc9", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"987fbc97-4bed-5078-af07-9141ba07c9f3", true}, + {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + err := validate.Field(test.param, "uuid5") + + if test.expected == true { + if !IsEqual(t, err, nil) { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, err) + } + } else { + if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid5") { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, err) + } + } + } +} + +func TestUUID4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false}, + {"934859", false}, + {"57b73598-8764-4ad0-a76a-679bb6640eb1", true}, + {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true}, + } + + for i, test := range tests { + + err := validate.Field(test.param, "uuid4") + + if test.expected == true { + if !IsEqual(t, err, nil) { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, err) + } + } else { + if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid4") { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, err) + } + } + } +} + +func TestUUID3Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"412452646", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + err := validate.Field(test.param, "uuid3") + + if test.expected == true { + if !IsEqual(t, err, nil) { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, err) + } + } else { + if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid3") { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, err) + } + } + } +} + +func TestUUIDValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, + {"a987fbc94bed3078cf079141ba07c9f3", false}, + {"934859", false}, + {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false}, + {"aaaaaaaa-1111-1111-aaag-111111111111", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + err := validate.Field(test.param, "uuid") + + if test.expected == true { + if !IsEqual(t, err, nil) { + t.Fatalf("Index: %d UUID failed Error: %s", i, err) + } + } else { + if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid") { + t.Fatalf("Index: %d UUID failed Error: %s", i, err) + } + } + } +} + func TestISBNValidation(t *testing.T) { tests := []struct { param string