bash - format_print_test.go
1 package bash
2
3 import (
4 "fmt"
5 "testing"
6
7 "vimagination.zapto.org/parser"
8 )
9
10 func TestPrintSource(t *testing.T) {
11 for n, test := range [...][3]string{
12 { // 1
13 "(( a ))",
14 "((a));",
15 "(( a ));",
16 },
17 { // 2
18 "$(( a + b ))",
19 "$((a+b));",
20 "$(( a + b ));",
21 },
22 { // 3
23 "a=(1)",
24 "a=(1);",
25 "a=( 1 );",
26 },
27 { // 4
28 "a=(\n# word comment\nb # post-word comment\n)",
29 "a=(\n\t# word comment\n\tb # post-word comment\n);",
30 "a=(\n\t# word comment\n\tb # post-word comment\n);",
31 },
32 { // 5
33 "a=1",
34 "a=1;",
35 "a=1;",
36 },
37 { // 6
38 "let a=1+2",
39 "let a=1+2;",
40 "let a=1+2;",
41 },
42 { // 7
43 "let a=1+(2+3)",
44 "let a=1+(2+3);",
45 "let a=1+( 2 + 3 );",
46 },
47 { // 8
48 "let a=b?(c?d:e):f",
49 "let a=b?(c?d:e):f;",
50 "let a=b?( c ? d : e ):f;",
51 },
52 { // 9
53 "case a in b)c\nesac",
54 "case a in\nb)\n\tc;;\nesac;",
55 "case a in\nb)\n\tc;;\nesac;",
56 },
57 { // 10
58 "case a in b);;& c) d;&\nesac",
59 "case a in\nb)\n\t;;&\nc)\n\td;&\nesac;",
60 "case a in\nb)\n\t;;&\nc)\n\td;&\nesac;",
61 },
62 { // 11
63 "case a #A\nin #B\n #C\nb)c;;\n#D\nesac",
64 "case a #A\nin #B\n #C\nb)\n\tc;;\n#D\nesac;",
65 "case a #A\nin #B\n #C\nb)\n\tc;;\n#D\nesac;",
66 },
67 { // 12
68 "a=1 b=2 c d >e <f",
69 "a=1 b=2 c d >e <f;",
70 "a=1 b=2 c d >e <f;",
71 },
72 { // 13
73 "a b >c <d",
74 "a b >c <d;",
75 "a b >c <d;",
76 },
77 { // 14
78 ">a <b",
79 ">a <b;",
80 ">a <b;",
81 },
82 { // 15
83 "a=1 b=2 >c <d",
84 "a=1 b=2 >c <d;",
85 "a=1 b=2 >c <d;",
86 },
87 { // 16
88 "a <<b\nheredoc\ncontents\nb",
89 "a <<b;\nheredoc\ncontents\nb",
90 "a <<b;\nheredoc\ncontents\nb",
91 },
92 { // 17
93 "a <<-b\n\theredoc\n\tcontents\nb",
94 "a <<-b;\nheredoc\ncontents\nb",
95 "a <<-b;\nheredoc\ncontents\nb",
96 },
97 { // 18
98 "$(a)",
99 "$(a);",
100 "$(a);",
101 },
102 { // 19
103 "$(a\nb)",
104 "$(\n\ta;\n\tb;\n);",
105 "$(\n\ta;\n\tb;\n);",
106 },
107 { // 20
108 "# A\na # B\n # C\n\n# D",
109 "# A\na; # B\n # C\n\n# D",
110 "# A\na; # B\n # C\n\n# D",
111 },
112 { // 21
113 "case a in\nesac <a 2>&1;",
114 "case a in\nesac <a 2>&1;",
115 "case a in\nesac <a 2>&1;",
116 },
117 { // 22
118 "a\nb\n\nc\nd\n\n\n\n\ne",
119 "a;\nb;\n\nc;\nd;\n\ne;",
120 "a;\nb;\n\nc;\nd;\n\ne;",
121 },
122 { // 23
123 "a\nfor b; do\nc\ndone",
124 "a;\nfor b; do\n\tc;\ndone;",
125 "a;\nfor b; do\n\tc;\ndone;",
126 },
127 { // 24
128 "for a;do c\nd\ndone",
129 "for a; do\n\tc;\n\td;\ndone;",
130 "for a; do\n\tc;\n\td;\ndone;",
131 },
132 { // 25
133 "for a in b\ndo c\ndone",
134 "for a in b; do\n\tc;\ndone;",
135 "for a in b; do\n\tc;\ndone;",
136 },
137 { // 26
138 "for a in b c\ndo d\ndone",
139 "for a in b c; do\n\td;\ndone;",
140 "for a in b c; do\n\td;\ndone;",
141 },
142 { // 27
143 "for ((a=0;a<1;a++));do b\ndone",
144 "for ((a=0;a<1;a++)); do\n\tb;\ndone;",
145 "for (( a = 0; a < 1; a ++ )); do\n\tb;\ndone;",
146 },
147 { // 28
148 "function a() { b; }",
149 "function a() { b; }",
150 "function a() {\n\tb;\n}",
151 },
152 { // 29
153 "function a { b; }",
154 "function a() { b; }",
155 "function a() {\n\tb;\n}",
156 },
157 { // 30
158 "a() { b; }",
159 "a() { b; }",
160 "a() {\n\tb;\n}",
161 },
162 { // 31
163 "function a() # A\n# B\n{ b; }",
164 "function a() # A\n # B\n{ b; }",
165 "function a() # A\n # B\n{\n\tb;\n}",
166 },
167 { // 32
168 "a() # A\n# B\n{ b; }",
169 "a() # A\n # B\n{ b; }",
170 "a() # A\n # B\n{\n\tb;\n}",
171 },
172 { // 33
173 "{ a; }",
174 "{ a; }",
175 "{\n\ta;\n}",
176 },
177 { // 34
178 "( a; )",
179 "( a; )",
180 "(\n\ta;\n)",
181 },
182 { // 35
183 "{ a; b; }",
184 "{ a; b; }",
185 "{\n\ta;\n\tb;\n}",
186 },
187 { // 36
188 "{ a || b; }",
189 "{ a || b; }",
190 "{\n\ta || b;\n}",
191 },
192 { // 37
193 "( a;\nb; )",
194 "(\n\ta;\n\tb;\n)",
195 "(\n\ta;\n\tb;\n)",
196 },
197 { // 38
198 "{ # A\na; # B\n}",
199 "{ # A\n\ta; # B\n}",
200 "{ # A\n\ta; # B\n}",
201 },
202 { // 39
203 "{ a; # A\n}",
204 "{\n\ta; # A\n}",
205 "{\n\ta; # A\n}",
206 },
207 { // 40
208 "{ a | b $(c\nd)\n}",
209 "{\n\ta | b $(\n\t\tc;\n\t\td;\n\t);\n}",
210 "{\n\ta | b $(\n\t\tc;\n\t\td;\n\t);\n}",
211 },
212 { // 41
213 "{ declare a=$(b); }",
214 "{ declare a=$(b); }",
215 "{\n\tdeclare a=$(b);\n}",
216 },
217 { // 42
218 "{ declare a=$(b;c); }",
219 "{ declare a=$(b; c;); }",
220 "{\n\tdeclare a=$(\n\t\tb;\n\t\tc;\n\t);\n}",
221 },
222 { // 43
223 "{ a=1 b; }",
224 "{ a=1 b; }",
225 "{\n\ta=1 b;\n}",
226 },
227 { // 44
228 "{ a=$(b\nc) d; }",
229 "{\n\ta=$(\n\t\tb;\n\t\tc;\n\t) d;\n}",
230 "{\n\ta=$(\n\t\tb;\n\t\tc;\n\t) d;\n}",
231 },
232 { // 45
233 "{ let a[$(b)]=c; }",
234 "{ let a[$(b)]=c; }",
235 "{\n\tlet a[$(b)]=c;\n}",
236 },
237 { // 46
238 "{ let a[$(b\nc)]=d; }",
239 "{\n\tlet a[$(\n\t\tb;\n\t\tc;\n\t)]=d;\n}",
240 "{\n\tlet a[$(\n\t\tb;\n\t\tc;\n\t)]=d;\n}",
241 },
242 { // 47
243 "{ let a=$(b); }",
244 "{ let a=$(b); }",
245 "{\n\tlet a=$(b);\n}",
246 },
247 { // 48
248 "{ let a=$(b\nc); }",
249 "{\n\tlet a=$(\n\t\tb;\n\t\tc;\n\t);\n}",
250 "{\n\tlet a=$(\n\t\tb;\n\t\tc;\n\t);\n}",
251 },
252 { // 49
253 "{ ${a[$(b\nc)]}; }",
254 "{\n\t${a[$(\n\t\tb;\n\t\tc;\n\t)]};\n}",
255 "{\n\t${a[$(\n\t\tb;\n\t\tc;\n\t)]};\n}",
256 },
257 { // 50
258 "<<a\nb$c\na",
259 "<<a;\nb$c\na",
260 "<<a;\nb$c\na",
261 },
262 { // 51
263 "{\n<<a\nb$c\na\n}",
264 "{\n\t<<a;\nb$c\na\n}",
265 "{\n\t<<a;\nb$c\na\n}",
266 },
267 { // 52
268 "{\n<<-a\nb$c\na\n}",
269 "{\n\t<<-a;\n\tb$c\n\ta\n}",
270 "{\n\t<<-a;\n\tb$c\n\ta\n}",
271 },
272 { // 53
273 "{ function a() { # A\nb; } }",
274 "{\n\tfunction a() { # A\n\t\tb;\n\t}\n}",
275 "{\n\tfunction a() { # A\n\t\tb;\n\t}\n}",
276 },
277 { // 54
278 "{ function a() { b;\nc; } }",
279 "{\n\tfunction a() {\n\t\tb;\n\t\tc;\n\t}\n}",
280 "{\n\tfunction a() {\n\t\tb;\n\t\tc;\n\t}\n}",
281 },
282 { // 55
283 "{ if a; then b\nc\nfi; }",
284 "{\n\tif a; then\n\t\tb;\n\t\tc;\n\tfi;\n}",
285 "{\n\tif a; then\n\t\tb;\n\t\tc;\n\tfi;\n}",
286 },
287 { // 56
288 "{ until a; do b\nc\ndone; }",
289 "{\n\tuntil a; do\n\t\tb;\n\t\tc;\n\tdone;\n}",
290 "{\n\tuntil a; do\n\t\tb;\n\t\tc;\n\tdone;\n}",
291 },
292 { // 57
293 "{ case a in b)c;;esac; }",
294 "{\n\tcase a in\n\tb)\n\t\tc;;\n\tesac;\n}",
295 "{\n\tcase a in\n\tb)\n\t\tc;;\n\tesac;\n}",
296 },
297 { // 58
298 "{ for a in b; do c\nd\ndone; }",
299 "{\n\tfor a in b; do\n\t\tc;\n\t\td;\n\tdone;\n}",
300 "{\n\tfor a in b; do\n\t\tc;\n\t\td;\n\tdone;\n}",
301 },
302 { // 59
303 "{ select a in b; do c\nd\ndone; }",
304 "{\n\tselect a in b; do\n\t\tc;\n\t\td;\n\tdone;\n}",
305 "{\n\tselect a in b; do\n\t\tc;\n\t\td;\n\tdone;\n}",
306 },
307 { // 60
308 "{ [[ a = b ]]; }",
309 "{ [[ a == b ]]; }",
310 "{\n\t[[ a == b ]];\n}",
311 },
312 { // 61
313 "{ [[ a = $(a\nb) ]]; }",
314 "{\n\t[[\n\t\ta == $(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
315 "{\n\t[[\n\t\ta == $(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
316 },
317 { // 62
318 "{ [[ a = b || c = $(a\nb) ]]; }",
319 "{\n\t[[\n\t\ta == b || c == $(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
320 "{\n\t[[\n\t\ta == b || c == $(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
321 },
322 { // 63
323 "{ [[ $(a\nb) ]]; }",
324 "{\n\t[[\n\t\t$(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
325 "{\n\t[[\n\t\t$(\n\t\t\ta;\n\t\t\tb;\n\t\t)\n\t]];\n}",
326 },
327 { // 64
328 "{ ((a)); }",
329 "{ ((a)); }",
330 "{\n\t(( a ));\n}",
331 },
332 { // 65
333 "{ (($(a\nb))); }",
334 "{\n\t(($(\n\t\ta;\n\t\tb;\n\t)));\n}",
335 "{\n\t(( $(\n\t\ta;\n\t\tb;\n\t) ));\n}",
336 },
337 { // 66
338 "{ (($(a\nb))) >&2; }",
339 "{\n\t(($(\n\t\ta;\n\t\tb;\n\t))) >&2;\n}",
340 "{\n\t(( $(\n\t\ta;\n\t\tb;\n\t) )) >&2;\n}",
341 },
342 { // 67
343 "{ ((a)) >$(a\nb); }",
344 "{\n\t((a)) >$(\n\t\ta;\n\t\tb;\n\t);\n}",
345 "{\n\t(( a )) >$(\n\t\ta;\n\t\tb;\n\t);\n}",
346 },
347 { // 68
348 "a | b <<c\nc",
349 "a | b <<c;\nc",
350 "a | b <<c;\nc",
351 },
352 { // 69
353 "a && b <<c\nc",
354 "a && b <<c;\nc",
355 "a && b <<c;\nc",
356 },
357 { // 70
358 "if a; then b;fi",
359 "if a; then\n\tb;\nfi;",
360 "if a; then\n\tb;\nfi;",
361 },
362 { // 71
363 "if a||b; then b\nc\nelif d\nthen\ne\nelse if f\nthen\ng\nfi\nfi",
364 "if a || b; then\n\tb;\n\tc;\nelif d; then\n\te;\nelse\n\tif f; then\n\t\tg;\n\tfi;\nfi;",
365 "if a || b; then\n\tb;\n\tc;\nelif d; then\n\te;\nelse\n\tif f; then\n\t\tg;\n\tfi;\nfi;",
366 },
367 { // 72
368 "if a; then b;elif c; then d;elif e\nthen f;fi",
369 "if a; then\n\tb;\nelif c; then\n\td;\nelif e; then\n\tf;\nfi;",
370 "if a; then\n\tb;\nelif c; then\n\td;\nelif e; then\n\tf;\nfi;",
371 },
372 { // 73
373 "while a\ndo\nb\ndone",
374 "while a; do\n\tb;\ndone;",
375 "while a; do\n\tb;\ndone;",
376 },
377 { // 74
378 "until a&&b; # A\n# B\ndo\n# C\nb\nc\ndone",
379 "until a && b; # A\n # B\ndo\n\t# C\n\tb;\n\tc;\ndone;",
380 "until a && b; # A\n # B\ndo\n\t# C\n\tb;\n\tc;\ndone;",
381 },
382 { // 75
383 "a[b]=",
384 "a[b]=;",
385 "a[b]=;",
386 },
387 { // 76
388 "a[b+c]=",
389 "a[b+c]=;",
390 "a[b + c]=;",
391 },
392 { // 77
393 "a[$(b\nc)]=",
394 "a[$(\n\tb;\n\tc;\n)]=;",
395 "a[$(\n\tb;\n\tc;\n)]=;",
396 },
397 { // 78
398 "${a}",
399 "${a};",
400 "${a};",
401 },
402 { // 79
403 "${!a}",
404 "${!a};",
405 "${!a};",
406 },
407 { // 80
408 "${#a}",
409 "${#a};",
410 "${#a};",
411 },
412 { // 81
413 "${a:=b}",
414 "${a:=b};",
415 "${a:=b};",
416 },
417 { // 82
418 "${a=b}",
419 "${a=b};",
420 "${a=b};",
421 },
422 { // 83
423 "${a:?b}",
424 "${a:?b};",
425 "${a:?b};",
426 },
427 { // 84
428 "${a?b}",
429 "${a?b};",
430 "${a?b};",
431 },
432 { // 85
433 "${a:+b}",
434 "${a:+b};",
435 "${a:+b};",
436 },
437 { // 86
438 "${a+b}",
439 "${a+b};",
440 "${a+b};",
441 },
442 { // 87
443 "${a:-b}",
444 "${a:-b};",
445 "${a:-b};",
446 },
447 { // 88
448 "${a-b}",
449 "${a-b};",
450 "${a-b};",
451 },
452 { // 89
453 "${a#b}",
454 "${a#b};",
455 "${a#b};",
456 },
457 { // 90
458 "${a##b}",
459 "${a##b};",
460 "${a##b};",
461 },
462 { // 91
463 "${a%b}",
464 "${a%b};",
465 "${a%b};",
466 },
467 { // 92
468 "${a%%b}",
469 "${a%%b};",
470 "${a%%b};",
471 },
472 { // 93
473 "${a/b}",
474 "${a/b};",
475 "${a/b};",
476 },
477 { // 94
478 "${a/b/c}",
479 "${a/b/c};",
480 "${a/b/c};",
481 },
482 { // 95
483 "${a//b}",
484 "${a//b};",
485 "${a//b};",
486 },
487 { // 96
488 "${a//b/c}",
489 "${a//b/c};",
490 "${a//b/c};",
491 },
492 { // 97
493 "${a/%b}",
494 "${a/%b};",
495 "${a/%b};",
496 },
497 { // 98
498 "${a/%b/c}",
499 "${a/%b/c};",
500 "${a/%b/c};",
501 },
502 { // 99
503 "${a/#b}",
504 "${a/#b};",
505 "${a/#b};",
506 },
507 { // 100
508 "${a/#b/c}",
509 "${a/#b/c};",
510 "${a/#b/c};",
511 },
512 { // 101
513 "${a^b}",
514 "${a^b};",
515 "${a^b};",
516 },
517 { // 102
518 "${a^^b}",
519 "${a^^b};",
520 "${a^^b};",
521 },
522 { // 103
523 "${a,b}",
524 "${a,b};",
525 "${a,b};",
526 },
527 { // 104
528 "${a,,b}",
529 "${a,,b};",
530 "${a,,b};",
531 },
532 { // 105
533 "${*}",
534 "${*};",
535 "${*};",
536 },
537 { // 106
538 "${@}",
539 "${@};",
540 "${@};",
541 },
542 { // 107
543 "${a:1}",
544 "${a:1};",
545 "${a:1};",
546 },
547 { // 108
548 "${a:1:2}",
549 "${a:1:2};",
550 "${a:1:2};",
551 },
552 { // 109
553 "${a: -1:2}",
554 "${a: -1:2};",
555 "${a: -1:2};",
556 },
557 { // 110
558 "${a@U}",
559 "${a@U};",
560 "${a@U};",
561 },
562 { // 111
563 "${a@u}",
564 "${a@u};",
565 "${a@u};",
566 },
567 { // 112
568 "${a@L}",
569 "${a@L};",
570 "${a@L};",
571 },
572 { // 113
573 "${a@Q}",
574 "${a@Q};",
575 "${a@Q};",
576 },
577 { // 114
578 "${a@E}",
579 "${a@E};",
580 "${a@E};",
581 },
582 { // 115
583 "${a@P}",
584 "${a@P};",
585 "${a@P};",
586 },
587 { // 116
588 "${a@A}",
589 "${a@A};",
590 "${a@A};",
591 },
592 { // 117
593 "${a@K}",
594 "${a@K};",
595 "${a@K};",
596 },
597 { // 118
598 "${a@a}",
599 "${a@a};",
600 "${a@a};",
601 },
602 { // 119
603 "${a@k}",
604 "${a@k};",
605 "${a@k};",
606 },
607 { // 120
608 "${!a@}",
609 "${!a@};",
610 "${!a@};",
611 },
612 { // 121
613 "${!a*}",
614 "${!a*};",
615 "${!a*};",
616 },
617 { // 122
618 "[[ a == b ]]",
619 "[[ a == b ]];",
620 "[[ a == b ]];",
621 },
622 { // 123
623 "[[ a == b$c ]]",
624 "[[ a == b$c ]];",
625 "[[ a == b$c ]];",
626 },
627 { // 124
628 "[[ a == b\"c\" ]]",
629 "[[ a == b\"c\" ]];",
630 "[[ a == b\"c\" ]];",
631 },
632 { // 125
633 "case a in a|b) a;\nb\nesac",
634 "case a in\na|b)\n\ta;\n\tb;;\nesac;",
635 "case a in\na|b)\n\ta;\n\tb;;\nesac;",
636 },
637 { // 126
638 "case a in a|b|\"c\") a;\nb\nesac",
639 "case a in\na|b|\"c\")\n\ta;\n\tb;;\nesac;",
640 "case a in\na|b|\"c\")\n\ta;\n\tb;;\nesac;",
641 },
642 { // 127
643 "! a",
644 "! a;",
645 "! a;",
646 },
647 { // 128
648 "coproc a",
649 "coproc a;",
650 "coproc a;",
651 },
652 { // 129
653 "coproc a if b; then c\nfi",
654 "coproc a if b; then\n\tc;\nfi;",
655 "coproc a if b; then\n\tc;\nfi;",
656 },
657 { // 130
658 "select a; do b; done",
659 "select a; do\n\tb;\ndone;",
660 "select a; do\n\tb;\ndone;",
661 },
662 { // 131
663 "select a in b c; do b; done",
664 "select a in b c; do\n\tb;\ndone;",
665 "select a in b c; do\n\tb;\ndone;",
666 },
667 { // 132
668 "a&",
669 "a&",
670 "a &",
671 },
672 { // 133
673 "[[ # A\na == b\n# B\n]]",
674 "[[ # A\n\ta == b\n# B\n]];",
675 "[[ # A\n\ta == b\n# B\n]];",
676 },
677 { // 134
678 "[[ # A\na == b\n]]",
679 "[[ # A\n\ta == b\n]];",
680 "[[ # A\n\ta == b\n]];",
681 },
682 { // 135
683 "[[\n\t! # A\n\ta == b ]]",
684 "[[\n\t! # A\n\ta == b\n]];",
685 "[[\n\t! # A\n\ta == b\n]];",
686 },
687 { // 136
688 "[[\n\t! # A\n\ta == b ]]",
689 "[[\n\t! # A\n\ta == b\n]];",
690 "[[\n\t! # A\n\ta == b\n]];",
691 },
692 { // 137
693 "[[ (a == b) ]]",
694 "[[ ( a == b ) ]];",
695 "[[ ( a == b ) ]];",
696 },
697 { // 138
698 "[[ (# A\na == b) ]]",
699 "[[\n\t( # A\n\t\ta == b\n\t)\n]];",
700 "[[\n\t( # A\n\t\ta == b\n\t)\n]];",
701 },
702 { // 139
703 "[[ (a == b\n# A\n) ]]",
704 "[[\n\t(\n\t\ta == b\n\t# A\n\t)\n]];",
705 "[[\n\t(\n\t\ta == b\n\t# A\n\t)\n]];",
706 },
707 { // 140
708 "[[ (\n# A\na == b # B\n) ]]",
709 "[[\n\t(\n\t\t# A\n\t\ta == b # B\n\t)\n]];",
710 "[[\n\t(\n\t\t# A\n\t\ta == b # B\n\t)\n]];",
711 },
712 } {
713 for m, input := range test {
714 if m == 2 && (n == 41 || n == 34) {
715 continue
716 }
717
718 tk := parser.NewStringTokeniser(input)
719
720 if f, err := Parse(&tk); err != nil {
721 t.Errorf("test %d.%d: unexpected error: %s", n+1, m+1, err)
722 } else if simple := fmt.Sprintf("%s", f); simple != test[1] {
723 t.Errorf("test %d.%d.1: expecting output %q, got %q", n+1, m+1, test[1], simple)
724 } else if verbose := fmt.Sprintf("%+s", f); verbose != test[2] {
725 t.Errorf("test %d.%d.2: expecting output %q, got %q", n+1, m+1, test[2], verbose)
726 }
727 }
728 }
729 }
730