From b64f0d0b59384f9040e7b78c7d25dd4bf806d8fa Mon Sep 17 00:00:00 2001 From: Victor Kryukov Date: Sat, 13 Sep 2014 13:13:42 -0600 Subject: [PATCH] Implement Regexp and NotRegexp --- assert/assertions.go | 49 +++++++++++++++++++++++++++++++ assert/assertions_test.go | 35 ++++++++++++++++++++++ assert/forward_assertions.go | 20 +++++++++++++ assert/forward_assertions_test.go | 36 +++++++++++++++++++++++ 4 files changed, 140 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index dfd6e44..5de1ab1 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -5,6 +5,7 @@ import ( "bytes" "fmt" "reflect" + "regexp" "runtime" "strings" "time" @@ -731,3 +732,51 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte return Equal(t, theError.Error(), errString, s, errString, theError.Error(), message) } + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func Regexp(t TestingT, rx interface{}, str interface{}) bool { + + match := matchRegexp(rx, str) + + if !match { + Fail(t, "Expect \"%s\" to match \"%s\"") + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func NotRegexp(t TestingT, rx interface{}, str interface{}) bool { + match := matchRegexp(rx, str) + + if match { + Fail(t, "Expect \"%s\" to NOT match \"%s\"") + } + + return !match + +} diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 62693fd..e5f1237 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2,6 +2,7 @@ package assert import ( "errors" + "regexp" "testing" "time" ) @@ -686,3 +687,37 @@ func TestInEpsilon(t *testing.T) { } } + +func TestRegexp(t *testing.T) { + mockT := new(testing.T) + + cases := []struct { + rx, str string + }{ + {"^start", "start of the line"}, + {"end$", "in the end"}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"}, + } + + for _, tc := range cases { + True(t, Regexp(mockT, tc.rx, tc.str)) + True(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + False(t, NotRegexp(mockT, tc.rx, tc.str)) + False(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + } + + cases = []struct { + rx, str string + }{ + {"^asdfastart", "Not the start of the line"}, + {"end$", "in the end."}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"}, + } + + for _, tc := range cases { + False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + True(t, NotRegexp(mockT, tc.rx, tc.str)) + True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str)) + } +} diff --git a/assert/forward_assertions.go b/assert/forward_assertions.go index 2e04e71..e2866f8 100644 --- a/assert/forward_assertions.go +++ b/assert/forward_assertions.go @@ -230,3 +230,23 @@ func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) bool { func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { return EqualError(a.t, theError, errString, msgAndArgs...) } + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Regexp(rx interface{}, str interface{}) bool { + return Regexp(a.t, rx, str) +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotRegexp(rx interface{}, str interface{}) bool { + return NotRegexp(a.t, rx, str) +} diff --git a/assert/forward_assertions_test.go b/assert/forward_assertions_test.go index e0b2b42..20cca6e 100644 --- a/assert/forward_assertions_test.go +++ b/assert/forward_assertions_test.go @@ -2,6 +2,7 @@ package assert import ( "errors" + "regexp" "testing" "time" ) @@ -480,3 +481,38 @@ func TestInEpsilonWrapper(t *testing.T) { False(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) } } + +func TestRegexpWrapper(t *testing.T) { + + assert := New(new(testing.T)) + + cases := []struct { + rx, str string + }{ + {"^start", "start of the line"}, + {"end$", "in the end"}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"}, + } + + for _, tc := range cases { + True(t, assert.Regexp(tc.rx, tc.str)) + True(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str)) + False(t, assert.NotRegexp(tc.rx, tc.str)) + False(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str)) + } + + cases = []struct { + rx, str string + }{ + {"^asdfastart", "Not the start of the line"}, + {"end$", "in the end."}, + {"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"}, + } + + for _, tc := range cases { + False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str)) + True(t, assert.NotRegexp(tc.rx, tc.str)) + True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str)) + } +}