-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
fuzz_test.go
67 lines (53 loc) · 1.24 KB
/
fuzz_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//go:build go1.18
// +build go1.18
package main
import (
"context"
"strings"
"testing"
"time"
"github.com/skx/monkey/evaluator"
"github.com/skx/monkey/lexer"
"github.com/skx/monkey/object"
"github.com/skx/monkey/parser"
)
// FuzzMonkey runs the fuzz-testing against our parser and interpreter.
func FuzzMonkey(f *testing.F) {
// Known errors we might see
known := []string{
"as integer",
"divide by zero",
"null operand",
"could not parse",
"exceeded",
"expected assign",
"expected next token",
"impossible",
"nested ternary expressions are illegal",
"no prefix parse function",
}
f.Fuzz(func(t *testing.T, input []byte) {
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
env := object.NewEnvironment()
l := lexer.New(string(input))
p := parser.New(l)
program := p.ParseProgram()
falsePositive := false
// No errors? Then execute
if len(p.Errors()) == 0 {
evaluator.EvalContext(ctx, program, env)
return
}
for _, msg := range p.Errors() {
for _, ignored := range known {
if strings.Contains(msg, ignored) {
falsePositive = true
}
}
}
if !falsePositive {
t.Fatalf("error running input: '%s': %v", input, p.Errors())
}
})
}