1 package parse
2
3 import (
4 "testing"
5
6 "github.com/google/go-cmp/cmp"
7 )
8
9 var tests = []struct {
10 Text string
11 Node Node
12 }{
13
14
15
16
17 {
18 Text: "text",
19 Node: &TextNode{Value: "text"},
20 },
21 {
22 Text: "}text",
23 Node: &TextNode{Value: "}text"},
24 },
25 {
26 Text: "http://github.com",
27 Node: &TextNode{Value: "http://github.com"},
28 },
29 {
30 Text: "$${string}",
31 Node: &TextNode{Value: "${string}"},
32 },
33 {
34 Text: "$$string",
35 Node: &TextNode{Value: "$string"},
36 },
37 {
38 Text: `\\.\pipe\pipename`,
39 Node: &TextNode{Value: `\\.\pipe\pipename`},
40 },
41
42
43
44
45 {
46 Text: "${string}",
47 Node: &FuncNode{Param: "string"},
48 },
49
50
51
52
53 {
54 Text: "${string,}",
55 Node: &FuncNode{
56 Param: "string",
57 Name: ",",
58 Args: nil,
59 },
60 },
61 {
62 Text: "${string,,}",
63 Node: &FuncNode{
64 Param: "string",
65 Name: ",,",
66 Args: nil,
67 },
68 },
69 {
70 Text: "${string^}",
71 Node: &FuncNode{
72 Param: "string",
73 Name: "^",
74 Args: nil,
75 },
76 },
77 {
78 Text: "${string^^}",
79 Node: &FuncNode{
80 Param: "string",
81 Name: "^^",
82 Args: nil,
83 },
84 },
85
86
87
88
89 {
90 Text: "${string:position}",
91 Node: &FuncNode{
92 Param: "string",
93 Name: ":",
94 Args: []Node{
95 &TextNode{Value: "position"},
96 },
97 },
98 },
99 {
100 Text: "${string:position:length}",
101 Node: &FuncNode{
102 Param: "string",
103 Name: ":",
104 Args: []Node{
105 &TextNode{Value: "position"},
106 &TextNode{Value: "length"},
107 },
108 },
109 },
110
111
112
113
114 {
115 Text: "${string#substring}",
116 Node: &FuncNode{
117 Param: "string",
118 Name: "#",
119 Args: []Node{
120 &TextNode{Value: "substring"},
121 },
122 },
123 },
124 {
125 Text: "${string##substring}",
126 Node: &FuncNode{
127 Param: "string",
128 Name: "##",
129 Args: []Node{
130 &TextNode{Value: "substring"},
131 },
132 },
133 },
134 {
135 Text: "${string%substring}",
136 Node: &FuncNode{
137 Param: "string",
138 Name: "%",
139 Args: []Node{
140 &TextNode{Value: "substring"},
141 },
142 },
143 },
144 {
145 Text: "${string%%substring}",
146 Node: &FuncNode{
147 Param: "string",
148 Name: "%%",
149 Args: []Node{
150 &TextNode{Value: "substring"},
151 },
152 },
153 },
154
155
156
157
158 {
159 Text: "${string/substring/replacement}",
160 Node: &FuncNode{
161 Param: "string",
162 Name: "/",
163 Args: []Node{
164 &TextNode{Value: "substring"},
165 &TextNode{Value: "replacement"},
166 },
167 },
168 },
169 {
170 Text: "${string//substring/replacement}",
171 Node: &FuncNode{
172 Param: "string",
173 Name: "//",
174 Args: []Node{
175 &TextNode{Value: "substring"},
176 &TextNode{Value: "replacement"},
177 },
178 },
179 },
180 {
181 Text: "${string/#substring/replacement}",
182 Node: &FuncNode{
183 Param: "string",
184 Name: "/#",
185 Args: []Node{
186 &TextNode{Value: "substring"},
187 &TextNode{Value: "replacement"},
188 },
189 },
190 },
191 {
192 Text: "${string/%substring/replacement}",
193 Node: &FuncNode{
194 Param: "string",
195 Name: "/%",
196 Args: []Node{
197 &TextNode{Value: "substring"},
198 &TextNode{Value: "replacement"},
199 },
200 },
201 },
202
203
204
205
206 {
207 Text: "${string=default}",
208 Node: &FuncNode{
209 Param: "string",
210 Name: "=",
211 Args: []Node{
212 &TextNode{Value: "default"},
213 },
214 },
215 },
216 {
217 Text: "${string:=default}",
218 Node: &FuncNode{
219 Param: "string",
220 Name: ":=",
221 Args: []Node{
222 &TextNode{Value: "default"},
223 },
224 },
225 },
226 {
227 Text: "${string:-default}",
228 Node: &FuncNode{
229 Param: "string",
230 Name: ":-",
231 Args: []Node{
232 &TextNode{Value: "default"},
233 },
234 },
235 },
236 {
237 Text: "${string:?default}",
238 Node: &FuncNode{
239 Param: "string",
240 Name: ":?",
241 Args: []Node{
242 &TextNode{Value: "default"},
243 },
244 },
245 },
246 {
247 Text: "${string:+default}",
248 Node: &FuncNode{
249 Param: "string",
250 Name: ":+",
251 Args: []Node{
252 &TextNode{Value: "default"},
253 },
254 },
255 },
256
257
258
259
260 {
261 Text: "${#string}",
262 Node: &FuncNode{
263 Param: "string",
264 Name: "#",
265 },
266 },
267
268
269
270
271 {
272 Text: "${string#$%:*{}",
273 Node: &FuncNode{
274 Param: "string",
275 Name: "#",
276 Args: []Node{
277 &TextNode{Value: "$%:*{"},
278 },
279 },
280 },
281
282
283 {
284 Text: "hello ${#string} world",
285 Node: &ListNode{
286 Nodes: []Node{
287 &TextNode{
288 Value: "hello ",
289 },
290 &ListNode{
291 Nodes: []Node{
292 &FuncNode{
293 Param: "string",
294 Name: "#",
295 },
296 &TextNode{
297 Value: " world",
298 },
299 },
300 },
301 },
302 },
303 },
304
305 {
306 Text: `\\ hello ${#string} world \\`,
307 Node: &ListNode{
308 Nodes: []Node{
309 &TextNode{
310 Value: `\\ hello `,
311 },
312 &ListNode{
313 Nodes: []Node{
314 &FuncNode{
315 Param: "string",
316 Name: "#",
317 },
318 &TextNode{
319 Value: ` world \\`,
320 },
321 },
322 },
323 },
324 },
325 },
326
327
328 {
329 Text: `${string/\/position/length}`,
330 Node: &FuncNode{
331 Param: "string",
332 Name: "/",
333 Args: []Node{
334 &TextNode{
335 Value: "/position",
336 },
337 &TextNode{
338 Value: "length",
339 },
340 },
341 },
342 },
343 {
344 Text: `${string/\/position\\/length}`,
345 Node: &FuncNode{
346 Param: "string",
347 Name: "/",
348 Args: []Node{
349 &TextNode{
350 Value: "/position\\",
351 },
352 &TextNode{
353 Value: "length",
354 },
355 },
356 },
357 },
358 {
359 Text: `${string/position/\/length}`,
360 Node: &FuncNode{
361 Param: "string",
362 Name: "/",
363 Args: []Node{
364 &TextNode{
365 Value: "position",
366 },
367 &TextNode{
368 Value: "/length",
369 },
370 },
371 },
372 },
373 {
374 Text: `${string/position/\/length\\}`,
375 Node: &FuncNode{
376 Param: "string",
377 Name: "/",
378 Args: []Node{
379 &TextNode{
380 Value: "position",
381 },
382 &TextNode{
383 Value: "/length\\",
384 },
385 },
386 },
387 },
388 {
389 Text: `${string/position/\/leng\\th}`,
390 Node: &FuncNode{
391 Param: "string",
392 Name: "/",
393 Args: []Node{
394 &TextNode{
395 Value: "position",
396 },
397 &TextNode{
398 Value: "/leng\\th",
399 },
400 },
401 },
402 },
403
404
405 {
406 Text: "${string:${position}}",
407 Node: &FuncNode{
408 Param: "string",
409 Name: ":",
410 Args: []Node{
411 &FuncNode{
412 Param: "position",
413 },
414 },
415 },
416 },
417 {
418 Text: "${string:${stringy:position:length}:${stringz,,}}",
419 Node: &FuncNode{
420 Param: "string",
421 Name: ":",
422 Args: []Node{
423 &FuncNode{
424 Param: "stringy",
425 Name: ":",
426 Args: []Node{
427 &TextNode{Value: "position"},
428 &TextNode{Value: "length"},
429 },
430 },
431 &FuncNode{
432 Param: "stringz",
433 Name: ",,",
434 },
435 },
436 },
437 },
438 {
439 Text: "${string#${stringz}}",
440 Node: &FuncNode{
441 Param: "string",
442 Name: "#",
443 Args: []Node{
444 &FuncNode{Param: "stringz"},
445 },
446 },
447 },
448 {
449 Text: "${string=${stringz}}",
450 Node: &FuncNode{
451 Param: "string",
452 Name: "=",
453 Args: []Node{
454 &FuncNode{Param: "stringz"},
455 },
456 },
457 },
458 {
459 Text: "${string=prefix-${var}}",
460 Node: &FuncNode{
461 Param: "string",
462 Name: "=",
463 Args: []Node{
464 &TextNode{Value: "prefix-"},
465 &FuncNode{Param: "var"},
466 },
467 },
468 },
469 {
470 Text: "${string=${var}-suffix}",
471 Node: &FuncNode{
472 Param: "string",
473 Name: "=",
474 Args: []Node{
475 &FuncNode{Param: "var"},
476 &TextNode{Value: "-suffix"},
477 },
478 },
479 },
480 {
481 Text: "${string=prefix-${var}-suffix}",
482 Node: &FuncNode{
483 Param: "string",
484 Name: "=",
485 Args: []Node{
486 &TextNode{Value: "prefix-"},
487 &FuncNode{Param: "var"},
488 &TextNode{Value: "-suffix"},
489 },
490 },
491 },
492 {
493 Text: "${string=prefix${var} suffix}",
494 Node: &FuncNode{
495 Param: "string",
496 Name: "=",
497 Args: []Node{
498 &TextNode{Value: "prefix"},
499 &FuncNode{Param: "var"},
500 &TextNode{Value: " suffix"},
501 },
502 },
503 },
504 {
505 Text: "${string//${stringy}/${stringz}}",
506 Node: &FuncNode{
507 Param: "string",
508 Name: "//",
509 Args: []Node{
510 &FuncNode{Param: "stringy"},
511 &FuncNode{Param: "stringz"},
512 },
513 },
514 },
515 }
516
517 func TestParse(t *testing.T) {
518 for _, test := range tests {
519 t.Log(test.Text)
520 t.Run(test.Text, func(t *testing.T) {
521 got, err := Parse(test.Text)
522 if err != nil {
523 t.Error(err)
524 }
525
526 if diff := cmp.Diff(test.Node, got.Root); diff != "" {
527 t.Errorf(diff)
528 }
529 })
530 }
531 }
532
View as plain text