Skip to content

Commit cba0e87

Browse files
committed
Add StringMatching assertion for regular expressions
Closes #6
1 parent 65922d2 commit cba0e87

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ g.Should(be.DeepEqual([]string{"a", "b"}, []string{"a", "b"}))
109109

110110
g.Should(be.SliceContaining([]int{1, 2, 3}, 2))
111111
g.Should(be.StringContaining("foobar", "foo"))
112+
g.Should(be.StringMatching("foobar", `^foo`))
112113

113114
var err error
114115
g.NoError(err)

be/assertions.go

+46
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package be
33
import (
44
"fmt"
55
"reflect"
6+
"regexp"
67
"strconv"
78
"strings"
89

@@ -442,6 +443,51 @@ substr: %s
442443
}
443444
}
444445

446+
// StringMatching asserts that a given string matches a regular expression.
447+
func StringMatching(str string, expr string) ghost.Result {
448+
args := ghostlib.ArgsFromAST(str, expr)
449+
argStr, argExpr := args[0], args[1]
450+
451+
re, err := regexp.Compile(expr)
452+
if err != nil {
453+
return ghost.Result{
454+
Ok: false,
455+
Message: fmt.Sprintf(`%v is not a valid regular expression
456+
%v
457+
`,
458+
argExpr,
459+
err,
460+
),
461+
}
462+
}
463+
464+
if re.MatchString(str) {
465+
return ghost.Result{
466+
Ok: true,
467+
Message: fmt.Sprintf(`%v matches regular expression %v
468+
str: %s
469+
expr: %s
470+
`,
471+
argStr, argExpr,
472+
quoteString(str),
473+
re.String(),
474+
),
475+
}
476+
}
477+
478+
return ghost.Result{
479+
Ok: false,
480+
Message: fmt.Sprintf(`%v does not match regular expression %v
481+
str: %s
482+
expr: %s
483+
`,
484+
argStr, argExpr,
485+
quoteString(str),
486+
re.String(),
487+
),
488+
}
489+
}
490+
445491
// True asserts that a value is true.
446492
func True(b bool) ghost.Result {
447493
args := ghostlib.ArgsFromAST(b)

be/assertions_test.go

+61
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,67 @@ substr: "two"
919919
})
920920
}
921921

922+
func TestStringMatching(t *testing.T) {
923+
t.Run("matches", func(t *testing.T) {
924+
g := ghost.New(t)
925+
926+
str := "foobar"
927+
expr := "^foo"
928+
929+
result := be.StringMatching(str, expr)
930+
g.Should(be.True(result.Ok))
931+
g.Should(be.Equal(result.Message, `str matches regular expression expr
932+
str: "foobar"
933+
expr: ^foo
934+
`))
935+
936+
result = be.StringMatching("foobar", "^foo")
937+
g.Should(be.True(result.Ok))
938+
g.Should(be.Equal(result.Message, `"foobar" matches regular expression "^foo"
939+
str: "foobar"
940+
expr: ^foo
941+
`))
942+
})
943+
944+
t.Run("does not match", func(t *testing.T) {
945+
g := ghost.New(t)
946+
947+
str := "foobar"
948+
expr := "^foo$"
949+
950+
result := be.StringMatching(str, expr)
951+
g.Should(be.False(result.Ok))
952+
g.Should(be.Equal(result.Message, `str does not match regular expression expr
953+
str: "foobar"
954+
expr: ^foo$
955+
`))
956+
957+
result = be.StringMatching("foobar", "^foo$")
958+
g.Should(be.False(result.Ok))
959+
g.Should(be.Equal(result.Message, `"foobar" does not match regular expression "^foo$"
960+
str: "foobar"
961+
expr: ^foo$
962+
`))
963+
})
964+
965+
t.Run("invalid", func(t *testing.T) {
966+
g := ghost.New(t)
967+
968+
str := "foobar"
969+
expr := "^foo\\j"
970+
971+
result := be.StringMatching(str, expr)
972+
g.Should(be.False(result.Ok))
973+
g.Should(be.Equal(result.Message, `expr is not a valid regular expression
974+
error parsing regexp: invalid escape sequence: `+"`\\j`\n"))
975+
976+
result = be.StringMatching("foobar", "^foo\\j")
977+
g.Should(be.False(result.Ok))
978+
g.Should(be.Equal(result.Message, `"^foo\\j" is not a valid regular expression
979+
error parsing regexp: invalid escape sequence: `+"`\\j`\n"))
980+
})
981+
}
982+
922983
func TestTrue(t *testing.T) {
923984
t.Run("true", func(t *testing.T) {
924985
g := ghost.New(t)

example_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func TestExample(t *testing.T) {
2626
g.Should(be.SliceLen([]string{"a", "b", "c"}, 3))
2727

2828
g.Should(be.StringContaining("foobar", "foo"))
29+
g.Should(be.StringMatching("foobar", `^foo`))
2930

3031
var err error
3132
g.NoError(err)

0 commit comments

Comments
 (0)