Skip to content

Commit d0d972b

Browse files
committed
Add fuzz testing
1 parent dbd9af5 commit d0d972b

File tree

6 files changed

+3534
-1
lines changed

6 files changed

+3534
-1
lines changed

fuzz_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package expr_test
2+
3+
import (
4+
"os"
5+
"regexp"
6+
"strings"
7+
"testing"
8+
9+
"github.com/antonmedv/expr"
10+
"github.com/antonmedv/expr/test/playground"
11+
)
12+
13+
func FuzzExpr(f *testing.F) {
14+
env := playground.ExampleData()
15+
16+
b, err := os.ReadFile("testdata/corpus.txt")
17+
if err != nil {
18+
f.Fatal(err)
19+
}
20+
for _, testcase := range strings.Split(string(b), "\n") {
21+
f.Add(testcase)
22+
}
23+
24+
f.Add(`Posts[0].Comments[0].AuthorEmail()`)
25+
f.Add(`Posts[0].Comments[0].Upvoted()`)
26+
f.Add(`Posts[0].Comments[0].CommentDate.Add(now())`)
27+
f.Add(`Posts[0].Comments[0].CommentDate.AddDate(0, 0, 1)`)
28+
f.Add(`Authors[Posts[0].Author.ID].Profile.Biography`)
29+
f.Add(`Authors[2].Profile.Age()`)
30+
f.Add(`Authors[2].Profile.Website`)
31+
32+
okCases := []*regexp.Regexp{
33+
regexp.MustCompile(`cannot slice`),
34+
regexp.MustCompile(`integer divide by zero`),
35+
regexp.MustCompile(`invalid operation`),
36+
regexp.MustCompile(`interface conversion`),
37+
regexp.MustCompile(`memory budget exceeded`),
38+
regexp.MustCompile(`slice index out of range`),
39+
regexp.MustCompile(`cannot fetch .* from .*`),
40+
regexp.MustCompile(`cannot get .* from .*`),
41+
regexp.MustCompile(`invalid argument for .*`),
42+
regexp.MustCompile(`json: unsupported value`),
43+
regexp.MustCompile(`error parsing regexp`),
44+
regexp.MustCompile(`time: missing unit in duration`),
45+
regexp.MustCompile(`using interface \{} as type .*`),
46+
regexp.MustCompile(`reflect.Value.MapIndex: value of type .* is not assignable to type .*`),
47+
regexp.MustCompile(`reflect: call of reflect.Value.Call on zero Value`),
48+
regexp.MustCompile(`reflect: call of reflect.Value.Len on bool Value`),
49+
regexp.MustCompile(`reflect: Call using .* as type .*`),
50+
regexp.MustCompile(`reflect: call of reflect.Value.Index on map Value`),
51+
}
52+
53+
skipCode := []string{
54+
`??`,
55+
}
56+
57+
f.Fuzz(func(t *testing.T, code string) {
58+
for _, skipCase := range skipCode {
59+
if strings.Contains(code, skipCase) {
60+
t.Skip()
61+
return
62+
}
63+
}
64+
65+
program, err := expr.Compile(code, expr.Env(playground.Blog{}))
66+
if err != nil {
67+
t.Skip()
68+
}
69+
70+
_, err = expr.Run(program, env)
71+
if err != nil {
72+
for _, okCase := range okCases {
73+
if okCase.MatchString(err.Error()) {
74+
t.Skip()
75+
return
76+
}
77+
}
78+
t.Errorf("code: %s, err: %s", code, err)
79+
}
80+
})
81+
}

test/playground/data.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"time"
66
)
77

8-
func ExampleData() interface{} {
8+
func ExampleData() Blog {
99
profileJohn := UserProfile{
1010
Birthday: time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC),
1111
Biography: "A passionate writer about Go.",

0 commit comments

Comments
 (0)