aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/testsuite.at
blob: 189fbc177628a427255ace40324a0c721ce1accc (plain)
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
AT_INIT
AT_COLOR_TESTS

# NOTE: There is currently no way to influence the return
# code of SciTECO, except to provoke an error.
# Since errors cannot be yielded explicitly, we use the
# idiom "(0/0)" to enforce a "Division by zero" error
# whenever we want to fail.
#
# NOTE: Square brackets are significant for M4 but
# often required in TECO code as well.
# We therefore use double brackets [[ ... ]]
# (translated to [ ... ]) in simple cases where balanced
# brackets are required in TECO code as well and
# quadrigraphs (@<:@ and @:>@) in all other cases.

AT_BANNER([Features])

AT_SETUP([Number stack])
AT_CHECK([$SCITECO -e "2%a,%a - 3\"N(0/0)'"], 0, ignore, ignore)
# It's not quite clear what would be the best semantics for comma:
# a) Superfluous commas as in ",," or "(1,)" should be an error.
# b) Superfluous commas should be ignored which is effectively what we do now.
#    Even then it might be advisable to treat (1,) like (1).
# c) The empty "list" element is equivalent to 0, so
#    "1,,2" is equivalent to "1,0,2" and (1,) to (1,0).
AT_CHECK([$SCITECO -e "(1,) \"~|(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "1,(2)=="], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Exponentiation])
AT_CHECK([$SCITECO -e "-1^*0  - (-1)\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "-1^*-5 - (-1)\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "0^*-5="], 1, ignore, ignore)
AT_CHECK([$SCITECO -e "0^*0   - 1\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "1^*-5  - 1\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "2^*-5  - 0\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Missing left operand])
AT_CHECK([$SCITECO -e '+23='], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Closing loops at the correct macro level])
AT_CHECK([$SCITECO -e '@^Ua{>} <Ma'], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Pass-through loops])
# NOTE: This requires the <=>, so that values get consumed from the stack.
# More elegant would be a command for popping exactly one argument like <:$>.
AT_CHECK([$SCITECO -e "1,2,3,-1:<\"~1;'%a=> Qa-6\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "1,2,3,-1:<\"~1;'%a= F>(0/0)> Qa-6\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "3<%a:>-3\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "3<%a :F>(0/0):>-3\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([String arguments])
AT_CHECK([$SCITECO -e $'Ifoo^Q\e(0/0)\e'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '@I"foo^Q"(0/0)"'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '@I{foo{bar}foo^Q{(0/0)}'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '@Ia^EQa(0/0)a'], 0, ignore, ignore)
# TODO: String building characters
AT_CLEANUP

AT_SETUP([Q-Register definitions])
AT_CHECK([$SCITECO -e '0Ua'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U.a'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U#ab'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U.#ab'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U[[AB]]'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U.[[AB]]'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '0U[[AB^Q@:>@(0/0)]]'], 0, ignore, ignore)
# TODO: String building in Q-Register definitions
AT_CLEANUP

AT_SETUP([Q-Register stack])
AT_CHECK([$SCITECO -e "[[a 23Ub ]]b Qb\"N(0/0)'"], 0, ignore, ignore)
# FG will temporarily change the working directory to tests/testsuite.dir.
AT_CHECK([$SCITECO -e "[[\$ @FG'..' ]]\$ :Q\$-1Q\$-^^r\"=(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([8-bit cleanliness])
AT_CHECK([$SCITECO -e "0@I//J 0A\"N(0/0)' :@S/^@/\"F(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "@EQa//0EE 1U*0EE 0:@EUa/f^@^@/ :Qa-4\"N(0/0)' Ga Z-4\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "0EE 129@I// -A-129\"N(0/0)' HXa @EQa// EE\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -8e "129@:^Ua// 0Qa-129\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "1EE 167Ua @I/^EUa/ .-1\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -8e "194Ua Qa@I//J :@S/^EUa/\"F(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Unicode])
AT_CHECK([$SCITECO -e "8594@I/Здравствуй, мир!/ Z-17\"N(0/0)' J0A-8594\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "8594@^Ua/Здравствуй, мир!/ :Qa-17\"N(0/0)' 0Qa-8594\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "@I/Здравствуй, мир!/ JW .-10\"N(0/0)' ^E-20\"N(0/0)' 204:EE .-10\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "@I/TEST/ @EW/юникод.txt/"], 0, ignore, ignore)
AT_CHECK([test -f юникод.txt], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "^^ß-223\"N(0/0) 23Uъ Q[Ъ]-23\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "@O/метка/ !метка!"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Automatic EOL normalization])
AT_CHECK([$SCITECO -e "@EB'${srcdir}/autoeol-input.txt' EL-2\"N(0/0)' 2LR 13@I'' 0EL @EW'autoeol-sciteco.txt'"],
         0, ignore, ignore)
AT_CHECK([cmp autoeol-sciteco.txt ${srcdir}/autoeol-output.txt], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Memory limiting])
AT_CHECK([$SCITECO -e "50*1000*1000,2EJ <@<:@a>"], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Execute external command])
# TODO: It would be a better test to generate a random number of bytes.
# Unfortunately, neither $RANDOM, shuf nor jot are portable.
# So we have to wait until SciTECO supports a random number generator.
AT_CHECK([$SCITECO -e "@EC'dd if=/dev/zero bs=512 count=1' Z= Z-512\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "0,128ED @EC'dd if=/dev/zero bs=512 count=1' Z= Z-512\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_BANNER([Regression Tests])

AT_SETUP([Glob patterns with character classes])
# Also checks closing brackets as part of the character set.
AT_CHECK([$SCITECO -e ":@EN/*.[[@:>@ch]]/foo.h/\"F(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Glob patterns with unclosed trailing brackets])
AT_CHECK([$SCITECO -e ":@EN/*.@<:@h/foo.@<:@h/\"F(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Searching with large counts])
# Even though the search will be unsuccessful, it will not be considered
# a proper error, so the process return code is still 0.
AT_CHECK([$SCITECO -e "2147483647@S/foo/"], 0, ignore, ignore)
# Will always break the memory limit which is considered an error.
AT_CHECK([$SCITECO -e "-2147483648@S/foo/"], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Memory limiting during spawning])
# This might result in an OOM if memory limiting is not working
AT_CHECK([$SCITECO -e "50*1000*1000,2EJ 0,128ED @EC'dd if=/dev/zero'"], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Q-Register stack cleanup])
AT_CHECK([$SCITECO -e '@<:@a'], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Uninitialized "_"-register])
AT_CHECK([$SCITECO -e ":@S//\"S(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e ":@EN///\"S(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Uninitialized Q-Register in string building])
AT_CHECK([$SCITECO -e '@I/^E@a/'], 0, ignore, ignore)
AT_CHECK([$SCITECO -e '@I/^ENa/'], 0, ignore, ignore)
AT_CLEANUP

AT_SETUP([Empty help topic])
AT_CHECK([$SCITECO -e '@?//'], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Empty lexer name])
AT_CHECK([$SCITECO -e '@ES/SETILEXER//'], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Empty command string])
AT_CHECK([$SCITECO -e '@EC//'], 1, ignore, ignore)
AT_CHECK([$SCITECO -e '@EGa//'], 1, ignore, ignore)
AT_CLEANUP

AT_SETUP([Jump to beginning of macro])
AT_CHECK([$SCITECO -e "%a-2\"< F< ' Qa-2\"N(0/0)'"], 0, ignore, ignore)
AT_CLEANUP

AT_BANNER([Known Bugs])

AT_SETUP([Number stack])
# Nobody needs the current semantic of digit "commands" and they
# will be replaced with proper number parser states, which will also allow for
# floating point constants.
# With the current parser, it is hard to even interpret the following code correctly...
AT_CHECK([$SCITECO -e "(12)3 - 3\"N(0/0)'"], 0, ignore, ignore)
AT_XFAIL_IF(true)
AT_CLEANUP

AT_SETUP([Dangling Else/End-If])
AT_CHECK([$SCITECO -e "'"], 1, ignore, ignore)
AT_CHECK([$SCITECO -e "| (0/0) '"], 1, ignore, ignore)
AT_XFAIL_IF(true)
AT_CLEANUP

# NOTE: This bug depends on specific build options of Glib's
# PCRE which is not predictable.
# It segfaults at least on Ubuntu 20.04 (libpcre3 v2:8.39).
#AT_SETUP([Pattern matching overflow])
## Should no longer dump core.
## It could fail because the memory limit is exceeed,
## but not in this case since the match string isn't too large.
#AT_CHECK([$SCITECO -e '100000<@I"X">J @S"^EM^X"'], 0, ignore, ignore)
#AT_XFAIL_IF(true)
#AT_CLEANUP

AT_SETUP([Recursion overflow])
# Should no longer dump core.
# It could fail because the memory limit is exceeed,
# but not in this case since we limit the recursion.
AT_CHECK([$SCITECO -e "@^Um{U.a Q.a-100000\"<%.aMm'} 0Mm"], 0, ignore, ignore)
AT_XFAIL_IF(true)
AT_CLEANUP