-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapper_test.go
255 lines (221 loc) · 6.11 KB
/
mapper_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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package hunkee
import (
"fmt"
"io"
"net"
"net/url"
"strings"
"testing"
"time"
)
func TestInitMapper(t *testing.T) {
t.Parallel()
type (
tooEasy struct {
ID int `hunk:"id"`
Name string `hunk:"name"`
Added time.Time `hunk:"added"`
}
easy struct {
Id uint64 `hunk:"id"`
Token string `hunk:"token"`
Temp float64 `hunk:"temp"`
Nice bool `hunk:"nice"`
IP net.Addr `hunk:"ip"`
}
notSoEasy struct {
Id uint64 `hunk:"id"`
IdRaw string `hunk:"id_raw"`
Token string `hunk:"token"`
TokenRaw string `hunk:"token_raw"`
Temp float64 `hunk:"temp"`
Nice bool `hunk:"nice"`
Ch rune `hunk:"ch"`
Date time.Time `hunk:"date"`
Dur time.Duration `hunk:"dur"`
ExplicitURL url.URL `hunk:"explicit_url"`
IP net.Addr `hunk:"ip"`
ignoreIt bool `hunk:"ignore_it"`
failWithIt []byte `hunk:"fail_with_it"`
}
embed struct {
// tooEasy `hunk:"too_easy"`
SoWhat bool `hunk:"so_what"`
ST struct {
InTime bool `hunk:"in_time"`
Arrival time.Time `hunk:"arrival"`
Token string `hunk:"token"`
TicketID uint64 `hunk:"ticket_id"`
} `hunk:"st"`
}
raw struct {
Size uint64 `hunk:"size"`
SizeRaw string `hunk:"size_raw"`
}
)
var (
te tooEasy
e easy
nse notSoEasy
em embed
r raw
tef = ":id :name :added"
ef = ":id :temp :token :ip :nice"
nsef = ":id :temp :token :ip :nice :ch :date :dur :explicit_url :fail_with_it"
emf = ":so_what :in_time :arrival :token :ticket_id"
rawf = ":size"
badWithPoint = ":id :name.name :added"
)
_, err := initMapper(tef, &te)
if err != nil {
t.Fatalf("Mapper initialization over %q should be finished without error, but have: %s", tef, err)
}
_, err = initMapper(badWithPoint, &te)
if err == nil {
t.Fatalf("Mapper initialization over %q should be finished with error of unexpected symbol, but no error occured", badWithPoint)
}
_, err = initMapper(ef, &e)
if err != nil {
t.Fatalf("Unexpected error %s", err)
}
_, err = initMapper(nsef, &nse)
if err == nil {
t.Fatal("expected error about absence of filed 'fail_with_it', got nil")
}
_, err = initMapper(emf, &em)
if err == nil {
t.Fatalf("Unexpected successfull finish of maper initialization")
}
_, err = initMapper(rawf, &r)
if err != nil {
t.Fatalf("unexpected error %s", err)
}
}
func TestExtractNames(t *testing.T) {
t.Parallel()
// valid formats
a := ":id :temp :token :ip :nice :ch :date :dur :explicit_url :ignore_it :fail_with_it"
b := ":so_what :in_time :starrival :token :ticket_id"
// c := `":id" ":temp" ":token" ":ip" ":nice" ":ch" ":date" ":dur" ":explicit_url" ":ignore_it" ":fail_with_it"`
// invalid formats
ia := ":id :temp :token :ip :nice :en:e"
ib := ":id :temp.far :token :ip :nice :en:e"
ic := ":so-what :ticket-id"
// case A
p, err := extractNames(a)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
la := 11
if len(p) != la {
t.Fatalf("%q - wrong length or extracted names: %d elements instead of %d", a, len(p), la)
}
// case B
p, err = extractNames(b)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
lb := 5
if len(p) != lb {
t.Fatalf("wrong length or extracted names: %d elements instead of %d", len(p), lb)
}
// case IA (invalid A)
expErr := "unexpected"
p, err = extractNames(ia)
for i := 0; i < len(p); i++ {
fmt.Println(p[i].name)
}
if err == nil || !strings.Contains(err.Error(), expErr) {
t.Fatalf("%q - expected error %q, have %q", ia, expErr+"..", err)
}
// case IB
expErr = "unsupported symbol"
_, err = extractNames(ib)
if err == nil || !strings.Contains(err.Error(), expErr) {
t.Fatalf("%q - expected error %q, have %q", ib, expErr+"..", err)
}
// case IC
expErr = "unsupported symbol"
p, err = extractNames(ic)
if err == nil || !strings.Contains(err.Error(), expErr) {
t.Fatalf("%q - expected error %q, have %q", ic, expErr+"..", err)
}
}
func TestExtractFieldsOnTags(t *testing.T) {
type (
notSoEasy struct {
Id uint64 `hunk:"id"`
IdRaw string `hunk:"id_raw"`
Token string `hunk:"token"`
TokenRaw string `hunk:"token_raw"`
Temp float64 `hunk:"temp"`
TempRaw string `hunk:"temp_raw"`
Nice bool `hunk:"nice"`
Ch rune `hunk:"ch"`
Date time.Time `hunk:"date"`
Dur time.Duration `hunk:"dur"`
ExplicitURL url.URL `hunk:"explicit_url"`
IP net.Addr `hunk:"ip"`
ignoreIt bool `hunk:"ignore_it"`
failWithIt []byte `hunk:"fail_with_it"`
FailWithItToo []byte `hunk:"Fail_with_it_too"`
}
withReader struct {
Name string `hunk:"name"`
R io.Reader `hunk:"r"`
}
)
var (
nse notSoEasy
wr withReader
)
f, err := extractFieldsOnTags(nse)
if err != nil {
t.Fatal(err.Error())
}
in := func(k string, valid []string) bool {
for i := 0; i < len(valid); i++ {
if valid[i] == k {
return true
}
}
return false
}
hasRaw := []string{"id", "token", "temp"}
for k, v := range f {
if in(k, hasRaw) && !v.hasRaw {
t.Fatalf("field %q has raw in structure but that field was not detected", k)
}
}
_, err = extractFieldsOnTags(wr)
if err != nil {
t.Fatal(err.Error())
}
var abc interface{}
_, err = extractFieldsOnTags(abc)
if err == nil {
t.Fatalf("expected %s have nil error", ErrOnlyStructs)
}
}
func TestMapperRaw(t *testing.T) {
t.Parallel()
var te struct {
IDr string `hunk:"id_raw"`
ID int `hunk:"id"`
Name string `hunk:"name"`
Added time.Time `hunk:"added"`
}
tef := ":id :name :added"
m, err := initMapper(tef, &te)
if err != nil {
t.Fatalf("Mapper initialization over %q should be finished without error, but have: %s", tef, err)
}
f := m.raw(m.getField("id"))
if f == nil {
t.Error("expected non-nil _raw value, have nil")
}
f = m.raw(m.getField("name"))
if f != nil {
t.Error("unexpected non-nil _raw value, want nil")
}
}