-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser_test.go
110 lines (103 loc) · 3.3 KB
/
parser_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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package comb_test
import (
"github.com/flowdev/comb"
"github.com/flowdev/comb/cmb"
"strings"
"testing"
)
func TestSaveSpot(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
parser comb.Parser[string]
input string
wantErr bool
wantOutput string
wantRemaining string
}{
{
name: "head matching parser should succeed",
input: "123",
parser: cmb.FirstSuccessful(cmb.Digit1(), comb.SafeSpot(cmb.Alpha1())),
wantErr: false,
wantOutput: "123",
wantRemaining: "",
}, {
name: "tail matching parser should succeed",
input: "abc",
parser: cmb.FirstSuccessful(comb.SafeSpot(cmb.Digit1()), cmb.Alpha1()),
wantErr: false,
wantOutput: "abc",
wantRemaining: "",
}, {
name: "FirstSuccessful: tail matching parser after failing SafeSpot head parser should fail",
input: "abc",
parser: cmb.FirstSuccessful(cmb.Prefixed(comb.SafeSpot(cmb.String("a")), cmb.Digit1()), cmb.Alpha1()),
wantErr: true,
wantOutput: "",
wantRemaining: "abc",
}, {
name: "Optional: tail matching parser after failing SafeSpot head parser should fail",
input: "abc",
parser: cmb.Optional(cmb.Prefixed(comb.SafeSpot(cmb.String("a")), cmb.Digit1())),
wantErr: true,
wantOutput: "",
wantRemaining: "bc",
}, {
name: "Many0: tail matching parser after failing SafeSpot head parser should fail",
input: "abc",
parser: cmb.Map(cmb.Many0(cmb.Prefixed(comb.SafeSpot(cmb.String("a")), cmb.Digit1())), func(tokens []string) (string, error) {
return strings.Join(tokens, ""), nil
}),
wantErr: true,
wantOutput: "",
wantRemaining: "abc",
}, {
name: "Seperated1: matching main parser after failing SafeSpot head parser should fail",
input: "a,1",
parser: cmb.Map(cmb.Separated0(cmb.Prefixed(comb.SafeSpot(cmb.String("a")), cmb.Digit1()), cmb.Char(','), false),
func(tokens []string) (string, error) {
return strings.Join(tokens, ""), nil
},
),
wantErr: true,
wantOutput: "1",
wantRemaining: "a,1",
}, {
name: "no matching parser should fail",
input: "$%^*",
parser: cmb.FirstSuccessful(comb.SafeSpot(cmb.Digit1()), comb.SafeSpot(cmb.Alpha1())),
wantErr: true,
wantOutput: "",
wantRemaining: "$%^*",
}, {
name: "empty input should fail",
input: "",
parser: cmb.FirstSuccessful(comb.SafeSpot(cmb.Digit1()), comb.SafeSpot(cmb.Alpha1())),
wantErr: true,
wantOutput: "",
wantRemaining: "",
},
}
for _, tc := range testCases {
tc := tc // this is needed for t.Parallel() to work correctly (or the same test case will be executed N times)
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
gotResult, gotErr := comb.RunOnString(tc.input, tc.parser)
if (gotErr != nil) != tc.wantErr {
t.Errorf("got error %v, want error: %t", gotErr, tc.wantErr)
}
if gotResult != tc.wantOutput {
t.Errorf("got output %q, want %q", gotResult, tc.wantOutput)
}
})
}
}
func BenchmarkSaveSpot(b *testing.B) {
p := comb.SafeSpot(cmb.Char('1'))
input := comb.NewFromString("123", false)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _, _ = p.Parse(input)
}
}