]> ocean-lang.org Git - ocean/blob - csrc/scanner-tests.mdc
14a70572a6646886c485423fc770ffd452049b0e
[ocean] / csrc / scanner-tests.mdc
1 # Scanner test code
2
3 The focus of these tests is coverage of the code in scanner.mdc
4 with the aim of being able to detect regressions.
5
6 We have a few different input files, and scan each with a variety
7 of different setting and ensure the output is as expected.
8
9 The inputs are in sectoins called "test: name" and the expected
10 outputs are in "test: name,arg,arg,arg".  As we cannot (yet)
11 extract a list of section names, we need to tell the make script
12 about each test.
13
14 ###### File: scanner-tests.mk
15
16         scanner_tests :=
17         ## test list
18
19         tests:: scanner_test_suite
20         scanner_test_suite : md2c coverage_scanner
21                 @rm -rf coverage; mkdir -p coverage
22                 @cp *.gcno coverage
23                 @for T in $(scanner_tests); do \
24                     echo -n "Tests $$T ... ";  \
25                     i="$IFS"; IFS=,; set $$T; IFS="$$i"; t=$$1; shift; \
26                     ./md2c scanner-tests.mdc "output: $$T" | grep -v '^#' > .tmp.want; \
27                     echo '~~~~~~~' > .tmp.code ;\
28                     ./md2c scanner-tests.mdc "test: $$t" | grep -v '^#' >> .tmp.code; \
29                     ./coverage_scanner --file .tmp.code $${1+"$$@"} > .tmp.have; \
30                     if ! cmp -s .tmp.want .tmp.have; then \
31                         echo "FAILED"; diff -u .tmp.want .tmp.have; exit 1; fi ; \
32                     echo "PASSED"; \
33                 done
34
35                 @gcov -o coverage scanner.c libscanner.c > /dev/null 2> /dev/null
36                 @mv *.gcov coverage; [ -f .gcov ] && mv .gcov coverage || true
37                 @awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \
38                     END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \
39                          if (ran < (ran + skip) *0.90) exit(1) }' \
40                         coverage/scanner.mdc.gcov
41                 @rm -f .tmp*
42
43         coverage_scanner: scanner.c libscanner.c libmdcode.o libnumber.o libstring.o
44                 $(CC) $(CFLAGS) --coverage -fprofile-dir=coverage -o coverage_scanner \
45                         scanner.c libscanner.c \
46                         libmdcode.o libnumber.o libstring.o -licuuc -lgmp
47
48 ## Basic tests
49
50 Some simple tests... maybe all tests are simple.
51 Include a special test for numbers, as they are interesting.
52
53 ###### test list
54         scanner_tests += "test1,if,then,+,-"
55         scanner_tests += "test1,if,then,+,-,/"
56         scanner_tests += "test1,--ignore-indent,if,then,+,-,/"
57         scanner_tests += "test1,--ignore-indent,--ignore-newline,if,then,+,-,/"
58         scanner_tests += "test1,-Cc,--ignore-indent,--ignore-newline,if,then,+,-,/"
59         scanner_tests += "test1,-CcSz,--ignore-indent,--ignore-newline,if,then,+,-,/"
60
61 ###### test: test1
62
63         A B C
64           D E
65            F G
66          H
67         I
68
69         A
70           B
71             C
72             D
73           E
74         F
75           G
76         H
77
78         if else then fi while
79         1234,  1.234 -123.456e45
80         0x1234 +  0x543p+3
81         "This is a string" &"so is this"a
82         a = """
83            This is a multi-
84            line string that
85            has three lines
86            """bb
87         I think # some comments are like this
88         and // some are like this
89         and some /* can go
90         over multiplt
91         lines */
92         divident /+ divisor
93
94 ###### output: test1,if,then,+,-
95         Tokenizing: 
96         2:0 ident(A)
97         2:2 ident(B)
98         2:4 ident(C)
99         3:2 in()
100         3:2 ident(D)
101         3:4 ident(E)
102         4:3 in()
103         4:3 ident(F)
104         4:5 ident(G)
105         5:1 newline()
106         5:1 out()
107         5:1 newline()
108         5:1 out()
109         5:1 in()
110         5:1 ident(H)
111         6:0 newline()
112         6:0 out()
113         6:0 newline()
114         6:0 ident(I)
115         8:0 newline()
116         8:0 newline()
117         8:0 ident(A)
118         9:2 in()
119         9:2 ident(B)
120         10:4 in()
121         10:4 ident(C)
122         11:4 newline()
123         11:4 ident(D)
124         12:2 newline()
125         12:2 out()
126         12:2 newline()
127         12:2 ident(E)
128         13:0 newline()
129         13:0 out()
130         13:0 newline()
131         13:0 ident(F)
132         14:2 in()
133         14:2 ident(G)
134         15:0 newline()
135         15:0 out()
136         15:0 newline()
137         15:0 ident(H)
138         17:0 newline()
139         17:0 newline()
140         17:0 if
141         17:3 ident(else)
142         17:8 then
143         17:13 ident(fi)
144         17:16 ident(while)
145         18:0 newline()
146         18:0 number(1234)  1234
147         18:4 mark(,)
148         18:7 number(1.234)  617/500
149         18:13 -
150         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
151         19:0 newline()
152         19:0 number(0x1234)  4660
153         19:7 +
154         19:10 number(0x543p+3)  10776
155         20:0 newline()
156         20:0 string("This is a string")  This is a string
157         20:19 mark(&)
158         20:20 string("so is this"a) a so is this
159         21:0 newline()
160         21:0 ident(a)
161         21:2 mark(=)
162         21:4 mstring("""\x0a   This is a m..) bb This is a multi-\x0al..
163         26:0 newline()
164         26:0 ident(I)
165         26:2 ident(think)
166         26:8 lcomment(# some comments ar..)
167         27:0 newline()
168         27:0 ident(and)
169         27:4 lcomment(// some are like t..)
170         28:0 newline()
171         28:0 ident(and)
172         28:4 ident(some)
173         28:9 bcomment(/* can go\x0aover mul..)
174         31:0 newline()
175         31:0 ident(divident)
176         31:9 mark(/+)
177         31:12 ident(divisor)
178         32:0 newline()
179         32:0 eof()
180
181 ###### output: test1,if,then,+,-,/
182         Tokenizing: 
183         2:0 ident(A)
184         2:2 ident(B)
185         2:4 ident(C)
186         3:2 in()
187         3:2 ident(D)
188         3:4 ident(E)
189         4:3 in()
190         4:3 ident(F)
191         4:5 ident(G)
192         5:1 newline()
193         5:1 out()
194         5:1 newline()
195         5:1 out()
196         5:1 in()
197         5:1 ident(H)
198         6:0 newline()
199         6:0 out()
200         6:0 newline()
201         6:0 ident(I)
202         8:0 newline()
203         8:0 newline()
204         8:0 ident(A)
205         9:2 in()
206         9:2 ident(B)
207         10:4 in()
208         10:4 ident(C)
209         11:4 newline()
210         11:4 ident(D)
211         12:2 newline()
212         12:2 out()
213         12:2 newline()
214         12:2 ident(E)
215         13:0 newline()
216         13:0 out()
217         13:0 newline()
218         13:0 ident(F)
219         14:2 in()
220         14:2 ident(G)
221         15:0 newline()
222         15:0 out()
223         15:0 newline()
224         15:0 ident(H)
225         17:0 newline()
226         17:0 newline()
227         17:0 if
228         17:3 ident(else)
229         17:8 then
230         17:13 ident(fi)
231         17:16 ident(while)
232         18:0 newline()
233         18:0 number(1234)  1234
234         18:4 mark(,)
235         18:7 number(1.234)  617/500
236         18:13 -
237         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
238         19:0 newline()
239         19:0 number(0x1234)  4660
240         19:7 +
241         19:10 number(0x543p+3)  10776
242         20:0 newline()
243         20:0 string("This is a string")  This is a string
244         20:19 mark(&)
245         20:20 string("so is this"a) a so is this
246         21:0 newline()
247         21:0 ident(a)
248         21:2 mark(=)
249         21:4 mstring("""\x0a   This is a m..) bb This is a multi-\x0al..
250         26:0 newline()
251         26:0 ident(I)
252         26:2 ident(think)
253         26:8 lcomment(# some comments ar..)
254         27:0 newline()
255         27:0 ident(and)
256         27:4 lcomment(// some are like t..)
257         28:0 newline()
258         28:0 ident(and)
259         28:4 ident(some)
260         28:9 bcomment(/* can go\x0aover mul..)
261         31:0 newline()
262         31:0 ident(divident)
263         31:9 /
264         31:10 +
265         31:12 ident(divisor)
266         32:0 newline()
267         32:0 eof()
268
269 ###### output: test1,--ignore-indent,if,then,+,-,/
270         Tokenizing: 
271         2:0 ident(A)
272         2:2 ident(B)
273         2:4 ident(C)
274         2:5 newline()
275         3:2 ident(D)
276         3:4 ident(E)
277         3:5 newline()
278         4:3 ident(F)
279         4:5 ident(G)
280         4:6 newline()
281         5:1 ident(H)
282         5:2 newline()
283         6:0 ident(I)
284         6:1 newline()
285         7:0 newline()
286         8:0 ident(A)
287         8:1 newline()
288         9:2 ident(B)
289         9:3 newline()
290         10:4 ident(C)
291         10:5 newline()
292         11:4 ident(D)
293         11:5 newline()
294         12:2 ident(E)
295         12:3 newline()
296         13:0 ident(F)
297         13:1 newline()
298         14:2 ident(G)
299         14:3 newline()
300         15:0 ident(H)
301         15:1 newline()
302         16:0 newline()
303         17:0 if
304         17:3 ident(else)
305         17:8 then
306         17:13 ident(fi)
307         17:16 ident(while)
308         17:21 newline()
309         18:0 number(1234)  1234
310         18:4 mark(,)
311         18:7 number(1.234)  617/500
312         18:13 -
313         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
314         18:24 newline()
315         19:0 number(0x1234)  4660
316         19:7 +
317         19:10 number(0x543p+3)  10776
318         19:18 newline()
319         20:0 string("This is a string")  This is a string
320         20:19 mark(&)
321         20:20 string("so is this"a) a so is this
322         20:33 newline()
323         21:0 ident(a)
324         21:2 mark(=)
325         21:4 mstring("""\x0a   This is a m..) bb This is a multi-\x0al..
326         25:8 newline()
327         26:0 ident(I)
328         26:2 ident(think)
329         26:8 lcomment(# some comments ar..)
330         26:37 newline()
331         27:0 ident(and)
332         27:4 lcomment(// some are like t..)
333         27:25 newline()
334         28:0 ident(and)
335         28:4 ident(some)
336         28:9 bcomment(/* can go\x0aover mul..)
337         30:8 newline()
338         31:0 ident(divident)
339         31:9 /
340         31:10 +
341         31:12 ident(divisor)
342         31:19 newline()
343         32:0 eof()
344
345 ###### output: test1,--ignore-indent,--ignore-newline,if,then,+,-,/
346         Tokenizing: 
347         2:0 ident(A)
348         2:2 ident(B)
349         2:4 ident(C)
350         3:2 ident(D)
351         3:4 ident(E)
352         4:3 ident(F)
353         4:5 ident(G)
354         5:1 ident(H)
355         6:0 ident(I)
356         8:0 ident(A)
357         9:2 ident(B)
358         10:4 ident(C)
359         11:4 ident(D)
360         12:2 ident(E)
361         13:0 ident(F)
362         14:2 ident(G)
363         15:0 ident(H)
364         17:0 if
365         17:3 ident(else)
366         17:8 then
367         17:13 ident(fi)
368         17:16 ident(while)
369         18:0 number(1234)  1234
370         18:4 mark(,)
371         18:7 number(1.234)  617/500
372         18:13 -
373         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
374         19:0 number(0x1234)  4660
375         19:7 +
376         19:10 number(0x543p+3)  10776
377         20:0 string("This is a string")  This is a string
378         20:19 mark(&)
379         20:20 string("so is this"a) a so is this
380         21:0 ident(a)
381         21:2 mark(=)
382         21:4 mstring("""\x0a   This is a m..) bb This is a multi-\x0al..
383         26:0 ident(I)
384         26:2 ident(think)
385         26:8 lcomment(# some comments ar..)
386         27:0 ident(and)
387         27:4 lcomment(// some are like t..)
388         28:0 ident(and)
389         28:4 ident(some)
390         28:9 bcomment(/* can go\x0aover mul..)
391         31:0 ident(divident)
392         31:9 /
393         31:10 +
394         31:12 ident(divisor)
395         32:0 eof()
396
397 ###### output: test1,-Cc,--ignore-indent,--ignore-newline,if,then,+,-,/
398         Tokenizing: 
399         2:0 ident(A)
400         2:2 ident(B)
401         2:4 ident(C)
402         3:2 ident(D)
403         3:4 ident(E)
404         4:3 ident(F)
405         4:5 ident(G)
406         5:1 ident(H)
407         6:0 ident(I)
408         8:0 ident(A)
409         9:2 ident(B)
410         10:4 ident(C)
411         11:4 ident(D)
412         12:2 ident(E)
413         13:0 ident(F)
414         14:2 ident(G)
415         15:0 ident(H)
416         17:0 if
417         17:3 ident(else)
418         17:8 then
419         17:13 ident(fi)
420         17:16 ident(while)
421         18:0 number(1234)  1234
422         18:4 mark(,)
423         18:7 number(1.234)  617/500
424         18:13 -
425         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
426         19:0 number(0x1234)  4660
427         19:7 +
428         19:10 number(0x543p+3)  10776
429         20:0 string("This is a string")  This is a string
430         20:19 mark(&)
431         20:20 string("so is this"a) a so is this
432         21:0 ident(a)
433         21:2 mark(=)
434         21:4 mstring("""\x0a   This is a m..) bb This is a multi-\x0al..
435         26:0 ident(I)
436         26:2 ident(think)
437         27:0 ident(and)
438         28:0 ident(and)
439         28:4 ident(some)
440         31:0 ident(divident)
441         31:9 /
442         31:10 +
443         31:12 ident(divisor)
444         32:0 eof()
445
446 ###### output: test1,-CcSz,--ignore-indent,--ignore-newline,if,then,+,-,/
447         Tokenizing: 
448         2:0 ident(A)
449         2:2 ident(B)
450         2:4 ident(C)
451         3:2 ident(D)
452         3:4 ident(E)
453         4:3 ident(F)
454         4:5 ident(G)
455         5:1 ident(H)
456         6:0 ident(I)
457         8:0 ident(A)
458         9:2 ident(B)
459         10:4 ident(C)
460         11:4 ident(D)
461         12:2 ident(E)
462         13:0 ident(F)
463         14:2 ident(G)
464         15:0 ident(H)
465         17:0 if
466         17:3 ident(else)
467         17:8 then
468         17:13 ident(fi)
469         17:16 ident(while)
470         18:0 number(1234)  1234
471         18:4 mark(,)
472         18:7 number(1.234)  617/500
473         18:13 -
474         18:14 number(123.456e45)  123456000000000000000000000000000000000000000000
475         19:0 number(0x1234)  4660
476         19:7 +
477         19:10 number(0x543p+3)  10776
478         20:0 mark(")
479         20:1 ident(This)
480         20:6 ident(is)
481         20:9 ident(a)
482         20:11 ident(string)
483         20:17 mark(")
484         20:19 mark(&")
485         20:21 ident(so)
486         20:24 ident(is)
487         20:27 ident(this)
488         20:31 mark(")
489         20:32 ident(a)
490         21:0 ident(a)
491         21:2 mark(=)
492         21:4 mark(""")
493         22:3 ident(This)
494         22:8 ident(is)
495         22:11 ident(a)
496         22:13 ident(multi)
497         22:18 -
498         23:3 ident(line)
499         23:8 ident(string)
500         23:15 ident(that)
501         24:3 ident(has)
502         24:7 ident(three)
503         24:13 ident(lines)
504         25:3 mark(""")
505         25:6 ident(bb)
506         26:0 ident(I)
507         26:2 ident(think)
508         27:0 ident(and)
509         28:0 ident(and)
510         28:4 ident(some)
511         31:0 ident(divident)
512         31:9 /
513         31:10 +
514         31:12 ident(divisor)
515         32:0 eof()
516
517 ###### test list
518         scanner_tests += "testnum"
519
520 ###### test: testnum
521         12345
522         1234.56
523         1234.56e7
524         1234.56e-7
525         0x1234
526         0x123,456
527         0o777
528         0o111.111p4
529         0b11011110p3
530
531         123 456 789
532         0x1234_5678_9abc
533
534         "Now for some non-number"
535         1234p4
536         12-34
537         01234
538         0c1234
539         123.456e1a
540         123.e4
541         0x123 456
542         0b1234
543         123_345_.34
544         .75
545
546 ###### output: testnum
547         Tokenizing: 
548         2:0 number(12345)  12345
549         3:0 newline()
550         3:0 number(1234.56)  30864/25
551         4:0 newline()
552         4:0 number(1234.56e7)  12345600000
553         5:0 newline()
554         5:0 number(1234.56e-7)  1929/15625000
555         6:0 newline()
556         6:0 number(0x1234)  4660
557         7:0 newline()
558         7:0 number(0x123,456)  596523/2048
559         8:0 newline()
560         8:0 number(0o777)  511
561         9:0 newline()
562         9:0 number(0o111.111p4)  37449/32
563         10:0 newline()
564         10:0 number(0b11011110p3)  1776
565         12:0 newline()
566         12:0 newline()
567         12:0 number(123 456 789)  123456789
568         13:0 newline()
569         13:0 number(0x1234_5678_9abc)  20015998343868
570         15:0 newline()
571         15:0 newline()
572         15:0 string("Now for some non-..)  Now for some non-n..
573         16:0 newline()
574         16:0 number(1234p4) BAD NUMBER
575         17:0 newline()
576         17:0 number(12)  12
577         17:2 mark(-)
578         17:3 number(34)  34
579         18:0 newline()
580         18:0 number(01234) BAD NUMBER
581         19:0 newline()
582         19:0 number(0c1234) BAD NUMBER
583         20:0 newline()
584         20:0 number(123.456e1a) a 30864/25
585         21:0 newline()
586         21:0 number(123.e4)  1230000
587         22:0 newline()
588         22:0 number(0x123 456) BAD NUMBER
589         23:0 newline()
590         23:0 number(0b1234) BAD NUMBER
591         24:0 newline()
592         24:0 number(123_345)  123345
593         24:7 ident(_)
594         24:8 mark(.)
595         24:9 number(34)  34
596         25:0 newline()
597         25:0 mark(.)
598         25:1 number(75)  75
599         26:0 newline()
600         26:0 eof()
601
602 ## Error tests
603
604 Now to test for some errors ... though things I thought would be errors
605 sometimes aren't.
606
607 ###### test list
608         scanner_tests += "errtest,--ignore-ident,--ignore-mark,-W_,-w_,if,then,+,-"
609         scanner_tests += "errtest,--ignore-ident,--ignore-mark,-N,if,then,+,-"
610
611 ###### test: errtest
612
613         multiple decimal pointer 3.141.59
614         "Check for decimal commas" 3,14159 = 3,141,59
615         """A multi-string must not have text here
616         """
617         "or after close" + """
618                 no text ..
619                 """ here
620
621         /* No embedded /* comments */ in comments */
622         /* or content after
623          * a multiline comment */ Error
624
625         "  \\ \t \n special chars in strings"
626
627 ###### output: errtest,--ignore-ident,--ignore-mark,-W_,-w_,if,then,+,-
628
629         Tokenizing: 
630         2:0 ERROR(multiple)
631         2:9 ERROR(decimal)
632         2:17 ERROR(pointer)
633         2:25 number(3.141)  3141/1000
634         2:30 ERROR(.)
635         2:31 number(59)  59
636         3:0 newline()
637         3:0 string("Check for decimal..)  Check for decimal ..
638         3:27 number(3,14159)  314159/100000
639         3:35 ERROR(=)
640         3:37 number(3,141)  3141/1000
641         3:42 ERROR(,)
642         3:43 number(59)  59
643         4:0 newline()
644         4:0 string("")  
645         4:2 ERROR("A multi-string mu..)
646         5:0 newline()
647         5:0 ERROR("""\x0a"or after clos..)
648         8:12 ERROR(here)
649         10:0 newline()
650         10:0 newline()
651         10:0 ERROR(/* No embedded /*)
652         10:15 bcomment(/* comments */)
653         10:30 ERROR(in)
654         10:33 ERROR(comments)
655         10:42 ERROR(*/)
656         11:0 newline()
657         11:0 ERROR(/* or content afte..)
658         12:26 ERROR(Error)
659         14:0 newline()
660         14:0 newline()
661         14:0 string("  \\\\ \\t \\n specia..)    \\ \x09 \x0a special ch..
662         15:0 newline()
663         15:0 eof()
664
665 ###### output: errtest,--ignore-ident,--ignore-mark,-N,if,then,+,-
666         Tokenizing: 
667         2:0 ERROR(multiple)
668         2:9 ERROR(decimal)
669         2:17 ERROR(pointer)
670         2:25 ERROR(3)
671         2:26 ERROR(.)
672         2:27 ERROR(1)
673         2:28 ERROR(4)
674         2:29 ERROR(1)
675         2:30 ERROR(.)
676         2:31 ERROR(5)
677         2:32 ERROR(9)
678         3:0 newline()
679         3:0 string("Check for decimal..)  Check for decimal ..
680         3:27 ERROR(3)
681         3:28 ERROR(,)
682         3:29 ERROR(1)
683         3:30 ERROR(4)
684         3:31 ERROR(1)
685         3:32 ERROR(5)
686         3:33 ERROR(9)
687         3:35 ERROR(=)
688         3:37 ERROR(3)
689         3:38 ERROR(,)
690         3:39 ERROR(1)
691         3:40 ERROR(4)
692         3:41 ERROR(1)
693         3:42 ERROR(,)
694         3:43 ERROR(5)
695         3:44 ERROR(9)
696         4:0 newline()
697         4:0 string("")  
698         4:2 ERROR("A multi-string mu..)
699         5:0 newline()
700         5:0 ERROR("""\x0a"or after clos..)
701         8:12 ERROR(here)
702         10:0 newline()
703         10:0 newline()
704         10:0 ERROR(/* No embedded /*)
705         10:15 bcomment(/* comments */)
706         10:30 ERROR(in)
707         10:33 ERROR(comments)
708         10:42 ERROR(*/)
709         11:0 newline()
710         11:0 ERROR(/* or content afte..)
711         12:26 ERROR(Error)
712         14:0 newline()
713         14:0 newline()
714         14:0 string("  \\\\ \\t \\n specia..)    \\ \x09 \x0a special ch..
715         15:0 newline()
716         15:0 eof()
717
718 ## Ad-hoc test
719
720 These tests test bugs that were found in practice, and so prevent them recuring.
721
722 The "bad_indent" test was written because I was seeing a TK_in before the
723 "program" instead of TK_newline
724
725 ###### test list
726         scanner_tests += "bad_indent"
727
728 ###### test: bad_indent
729
730                 const:
731                         foo : number = 45
732                         bar := "string"
733                 program:
734                         foo := 4
735                         print foo, bar
736
737 ###### output: bad_indent
738         Tokenizing: 
739         2:8 in()
740         2:8 ident(const)
741         2:13 mark(:)
742         3:16 in()
743         3:16 ident(foo)
744         3:20 mark(:)
745         3:22 ident(number)
746         3:29 mark(=)
747         3:31 number(45)  45
748         4:16 newline()
749         4:16 ident(bar)
750         4:20 mark(:=)
751         4:23 string("string")  string
752         5:8 newline()
753         5:8 out()
754         5:8 newline()
755         5:8 ident(program)
756         5:15 mark(:)
757         6:16 in()
758         6:16 ident(foo)
759         6:20 mark(:=)
760         6:23 number(4)  4
761         7:16 newline()
762         7:16 ident(print)
763         7:22 ident(foo)
764         7:25 mark(,)
765         7:27 ident(bar)
766         8:0 newline()
767         8:0 out()
768         8:0 newline()
769         8:0 out()
770         8:0 newline()
771         8:0 eof()