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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// SPDX-License-Identifier: GPL-3.0-or-later
package logs
import (
"errors"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewRegExpParser(t *testing.T) {
tests := []struct {
name string
pattern string
wantErr bool
}{
{name: "valid pattern", pattern: `(?P<A>\d+) (?P<B>\d+)`},
{name: "no names subgroups in pattern", pattern: `(?:\d+) (?:\d+)`, wantErr: true},
{name: "invalid pattern", pattern: `(((?P<A>\d+) (?P<B>\d+)`, wantErr: true},
{name: "empty pattern", wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, nil)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, p)
} else {
assert.NoError(t, err)
assert.NotNil(t, p)
}
})
}
}
func TestRegExpParser_ReadLine(t *testing.T) {
tests := []struct {
name string
row string
pattern string
wantErr bool
wantParseErr bool
}{
{name: "match and no error", row: "1 2", pattern: `(?P<A>\d+) (?P<B>\d+)`},
{name: "match but error on assigning", row: "1 2", pattern: `(?P<A>\d+) (?P<ERR>\d+)`, wantErr: true, wantParseErr: true},
{name: "not match", row: "A B", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true, wantParseErr: true},
{name: "not match multiline", row: "a b\n3 4", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true, wantParseErr: true},
{name: "error on reading EOF", row: "", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var line logLine
r := strings.NewReader(tt.row)
p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, r)
require.NoError(t, err)
err = p.ReadLine(&line)
if tt.wantErr {
require.Error(t, err)
if tt.wantParseErr {
assert.True(t, IsParseError(err))
} else {
assert.False(t, IsParseError(err))
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestRegExpParser_Parse(t *testing.T) {
tests := []struct {
name string
row string
pattern string
wantErr bool
}{
{name: "match and no error", row: "1 2", pattern: `(?P<A>\d+) (?P<B>\d+)`},
{name: "match but error on assigning", row: "1 2", pattern: `(?P<A>\d+) (?P<ERR>\d+)`, wantErr: true},
{name: "not match", row: "A B", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var line logLine
p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, nil)
require.NoError(t, err)
err = p.Parse([]byte(tt.row), &line)
if tt.wantErr {
require.Error(t, err)
assert.True(t, IsParseError(err))
} else {
assert.NoError(t, err)
}
})
}
}
func TestRegExpParser_Info(t *testing.T) {
p, err := NewRegExpParser(RegExpConfig{Pattern: `(?P<A>\d+) (?P<B>\d+)`}, nil)
require.NoError(t, err)
assert.NotZero(t, p.Info())
}
type logLine struct {
assigned map[string]string
}
func newLogLine() *logLine {
return &logLine{
assigned: make(map[string]string),
}
}
func (l *logLine) Assign(name, val string) error {
switch name {
case "$ERR", "ERR":
return errors.New("assign error")
}
if l.assigned != nil {
l.assigned[name] = val
}
return nil
}
|