diff --git a/README.md b/README.md
index 12c7bc8..c731f8f 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,25 @@ func TestSomething(t *testing.T) {
# Matchers
+
+
+RegexpMatcher - Matcher which accepts a string to be interpreted as a Go Regexp.
+
+Regexpmatcher returns a matcher which will match if the supplied string, interpreted
+as a regexp, matches the input string.
+
+This is useful when you don't know exactly what the string might be in a run.
+Maybe it's a timestamp or something else outside of your control.
+
+```go
+func TestRegexpMatcher(t *testing.T) {
+ m := matchers.Regexp("^[^@]+@.+$")
+ m.Matches("donald_duck@duckburg.di") // true
+ m.Matches("daisy") // false
+}
+```
+
+
RecordMatcher - Proxy matcher which captures the argument for further inspection.
Wraps another matcher and records the value of the argument it's called with.
@@ -105,7 +124,7 @@ func TestAsyncBlockMatcher(t *testing.T) {
// This blocks until `Matches` is actually called
<-m.Channel()
- assert.True(didMatch)
+ assert.True(didMatch)
}
```
diff --git a/regex.go b/regex.go
new file mode 100644
index 0000000..f309bdc
--- /dev/null
+++ b/regex.go
@@ -0,0 +1,29 @@
+package matchers
+
+import (
+ "fmt"
+ "regexp"
+)
+
+type regexpMatcher struct {
+ pattern *regexp.Regexp
+}
+
+func Regexp(pattern string) *regexpMatcher {
+ return ®expMatcher{
+ pattern: regexp.MustCompile(pattern),
+ }
+}
+
+func (m *regexpMatcher) String() string {
+ return fmt.Sprintf("matches pattern /%v/", m.pattern)
+}
+
+func (m *regexpMatcher) Matches(x interface{}) bool {
+ s, ok := x.(string)
+ if !ok {
+ return false
+ }
+
+ return m.pattern.MatchString(s)
+}
diff --git a/regex_test.go b/regex_test.go
new file mode 100644
index 0000000..9bdad81
--- /dev/null
+++ b/regex_test.go
@@ -0,0 +1,59 @@
+package matchers_test
+
+import (
+ "fmt"
+ "testing"
+
+ matchers "github.com/Storytel/gomock-matchers"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRegexpMatcher(t *testing.T) {
+
+ testCases := []struct {
+ pattern string
+ value interface{}
+ matches bool
+ }{
+ {"^something .*", "something good", true},
+ {"^something .*", "that's something good", false},
+ {"^[0-9][1-5]a?$", "42a", true},
+ {".*", 12, false},
+ }
+
+ for i, testCase := range testCases {
+ t.Run(fmt.Sprintf("Test #%d", i), func(t *testing.T) {
+ assert := assert.New(t)
+ m := matchers.Regexp(testCase.pattern)
+ assert.Equal(testCase.matches, m.Matches(testCase.value))
+ })
+ }
+}
+
+func TestRegexpMatcherCompileError(t *testing.T) {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Errorf("invalid regexp did not panic")
+ }
+ }()
+ _ = matchers.Regexp("^(abc$")
+}
+
+func TestRegexpMatcherString(t *testing.T) {
+ testCases := []struct {
+ pattern string
+ str string
+ }{
+ {"^[a-z]$", "matches pattern /^[a-z]$/"},
+ {"asdf", "matches pattern /asdf/"},
+ {"something[[:space:]]", "matches pattern /something[[:space:]]/"},
+ }
+
+ for i, testCase := range testCases {
+ t.Run(fmt.Sprintf("Test #%d", i), func(t *testing.T) {
+ assert := assert.New(t)
+ m := matchers.Regexp(testCase.pattern)
+ assert.Equal(testCase.str, m.String())
+ })
+ }
+}