Skip to content

Commit b5b5b94

Browse files
authored
Merge pull request #41 from hashicorp/add-regexp-support
Add regular expression support to TestImportCase.Error
2 parents 521c2c7 + 344ebb3 commit b5b5b94

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

Diff for: testing/import.go

+27-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"os/exec"
1212
"path/filepath"
13+
"regexp"
1314
"strings"
1415
"text/scanner"
1516

@@ -62,9 +63,16 @@ type TestImportCase struct {
6263
ImportName string
6364

6465
// A string containing any expected runtime error during evaluation. If
65-
// this field is non-empty, a runtime error is expected to occur, and the
66-
// Sentinel output is searched for the string given here. If a match is
67-
// found, the test passes. If it is not found the test will fail.
66+
// this field is non-empty, a runtime error is expected to occur, and
67+
// the Sentinel output is searched for the string given here. If the
68+
// output contains the string, the test passes. If it does not contain
69+
// the string, the test will fail.
70+
//
71+
// More advanced matches can be done with regular expression patterns.
72+
// If the Error string is delimited by slashes (/), the string is
73+
// compiled as a regular expression and the Sentinel output is matched
74+
// against the resulting pattern. If a match is found, the test passes.
75+
// If it does not match, the tests will fail.
6876
Error string
6977
}
7078

@@ -187,7 +195,7 @@ func TestImportDir(t testing.T, path string, customize func(*TestImportCase)) {
187195
// support a t.Run(), and adding context about which policy is failing
188196
// to the error is obtuse otherwise, so we'll just log the policy file
189197
// name here to give that context to the developer.
190-
t.Logf("Checking %s", file)
198+
t.Logf("Checking %s ...", file)
191199
TestImport(t, tc)
192200
}
193201
}
@@ -269,9 +277,21 @@ func TestImport(t testing.T, c TestImportCase) {
269277
output, err := cmd.CombinedOutput()
270278
if err != nil {
271279
if c.Error != "" {
272-
if !strings.Contains(string(output), c.Error) {
273-
t.Fatalf("expected error %q not found:\n\n%s",
274-
c.Error, string(output))
280+
if c.Error[:1]+c.Error[len(c.Error)-1:] == "//" {
281+
pattern := c.Error[1 : len(c.Error)-1]
282+
exp, err := regexp.Compile(pattern)
283+
if err != nil {
284+
t.Fatalf("error compiling expected error pattern: %s", err)
285+
}
286+
if !exp.Match(output) {
287+
t.Fatalf("the resulting error does not match the expected pattern: %s\n\nError output:\n\n%s",
288+
c.Error, string(output))
289+
}
290+
} else {
291+
if !strings.Contains(string(output), c.Error) {
292+
t.Fatalf("resulting error does not contain %q\n\nError output:\n\n%s",
293+
c.Error, string(output))
294+
}
275295
}
276296
} else {
277297
t.Fatalf("error executing test. output:\n\n%s", string(output))

Diff for: testing/import_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ func TestTestImport(t *testing.T) {
5353
})
5454
})
5555

56+
// Test runtime error w/ regular expression
57+
t.Run("error with regex", func(t *testing.T) {
58+
TestImport(&testingiface.RuntimeT{}, TestImportCase{
59+
ImportPath: path,
60+
Source: `main = rule { error("super 1337 error") }`,
61+
Error: `/super \d+ error/`,
62+
})
63+
})
64+
65+
// Test runtime error w/ errored regular expression
66+
t.Run("error with errored regex", func(t *testing.T) {
67+
// Use a defer to catch a panic that RuntimeT will throw. We can
68+
// detect the failure this way.
69+
defer func() {
70+
if e := recover(); e == nil {
71+
t.Fatal("should fail")
72+
}
73+
}()
74+
75+
TestImport(&testingiface.RuntimeT{}, TestImportCase{
76+
ImportPath: path,
77+
Source: `main = rule { error("super 1337 error") }`,
78+
Error: `/(super \d+ error/`,
79+
})
80+
})
81+
5682
// Test configuration
5783
t.Run("config", func(t *testing.T) {
5884
TestImport(t, TestImportCase{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//error: /hello \w+!/
2+
3+
main = rule {
4+
error("hello world" + exclamation)
5+
}

0 commit comments

Comments
 (0)