Skip to content

Commit

Permalink
panic when regex fails compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
merrett010 committed Oct 29, 2023
1 parent 01d7f54 commit 2899e96
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 24 deletions.
20 changes: 4 additions & 16 deletions gomock/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,10 @@ func (n notMatcher) String() string {
}

type regexMatcher struct {
regex *regexp.Regexp
compileErr error
regex *regexp.Regexp
}

func (m regexMatcher) Matches(x any) bool {
if m.regex == nil {
return false
}

switch t := x.(type) {
case string:
return m.regex.MatchString(t)
Expand All @@ -190,10 +185,7 @@ func (m regexMatcher) Matches(x any) bool {
}

func (m regexMatcher) String() string {
if m.compileErr != nil {
return m.compileErr.Error()
}
return "matching regex " + m.regex.String()
return "matches regex " + m.regex.String()
}

type assignableToTypeOfMatcher struct {
Expand Down Expand Up @@ -415,15 +407,11 @@ func Not(x any) Matcher {
// Example usage:
//
// Regex("[0-9]{2}:[0-9]{2}").Matches("23:02") // returns true
// Regex("[0-9]{2}:[0-9]{2}").Matches([]byte{50,51,58,48,50}) // returns true
// Regex("[0-9]{2}:[0-9]{2}").Matches([]byte{'2', '3', ':', '0', '2'}) // returns true
// Regex("[0-9]{2}:[0-9]{2}").Matches("hello world") // returns false
// Regex("[0-9]{2}").Matches(21) // returns false as it's not a valid type
func Regex(regexStr string) Matcher {
compiledRegexp, err := regexp.Compile(regexStr)
if err == nil {
return regexMatcher{regex: compiledRegexp}
}
return regexMatcher{regex: nil, compileErr: err}
return regexMatcher{regex: regexp.MustCompile(regexStr)}
}

// AssignableToTypeOf is a Matcher that matches if the parameter to the mock
Expand Down
22 changes: 14 additions & 8 deletions gomock/matchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,41 +101,47 @@ func TestRegexMatcher(t *testing.T) {
input any
wantMatch bool
wantStringResponse string
shouldPanic bool
}{
{
name: "match for whole num regex with start and end position matching",
regex: "^\\d+$",
input: "2302",
wantMatch: true,
wantStringResponse: "matching regex ^\\d+$",
wantStringResponse: "matches regex ^\\d+$",
},
{
name: "match for valid regex with start and end position matching on longer string",
regex: "^[0-9]{2}:[0-9]{2}$",
input: "[23:02]: Hello world",
wantMatch: false,
wantStringResponse: "matching regex ^[0-9]{2}:[0-9]{2}$",
wantStringResponse: "matches regex ^[0-9]{2}:[0-9]{2}$",
},
{
name: "match for valid regex with struct as bytes",
regex: `^{"id":[0-9]{2},"name":"world"}$`,
input: []byte{123, 34, 105, 100, 34, 58, 49, 50, 44, 34, 110, 97, 109, 101, 34, 58, 34, 119, 111, 114, 108, 100, 34, 125},
wantMatch: true,
wantStringResponse: `matching regex ^{"id":[0-9]{2},"name":"world"}$`,
wantStringResponse: `matches regex ^{"id":[0-9]{2},"name":"world"}$`,
},
{
name: "match for invalid regex",
regex: `^[0-9]\\?{2}:[0-9]{2}$`,
input: "23:02",
wantMatch: false,
wantStringResponse: "error parsing regexp: invalid nested repetition operator: `?{2}`",
name: "should panic when regex fails to compile",
regex: `^[0-9]\\?{2}:[0-9]{2}$`,
shouldPanic: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.shouldPanic {
defer func() { _ = recover() }()
}
matcher := gomock.Regex(tt.regex)

if tt.shouldPanic {
t.Errorf("test did not panic, and should have")
}

if got := matcher.Matches(tt.input); got != tt.wantMatch {
t.Errorf("got = %v, wantMatch = %v", got, tt.wantMatch)
}
Expand Down

0 comments on commit 2899e96

Please sign in to comment.