Line data Source code
1 : // Copyright (c) 2012-2024 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // this diagnostic has to be turned off "globally" so the catch2 does not
20 : // generate the warning on the floating point == operator
21 : //
22 : #pragma GCC diagnostic ignored "-Wfloat-equal"
23 :
24 : // self
25 : //
26 : #include "catch_main.h"
27 :
28 :
29 : // reporter
30 : //
31 : #include <eventdispatcher/reporter/lexer.h>
32 :
33 :
34 : // eventdispatcher
35 : //
36 : #include <eventdispatcher/exception.h>
37 :
38 :
39 : // libexcept
40 : //
41 : #include <libexcept/exception.h>
42 :
43 :
44 : // snapdev
45 : //
46 : #include <snapdev/int128_literal.h>
47 : #include <snapdev/ostream_int128.h>
48 :
49 :
50 : // C++
51 : //
52 : #include <cmath>
53 :
54 :
55 : // last include
56 : //
57 : #include <snapdev/poison.h>
58 :
59 :
60 :
61 : // make literals work
62 : //
63 : using namespace snapdev::literals;
64 :
65 : namespace
66 : {
67 :
68 :
69 :
70 : char g_white_spaces[] = {
71 : U'\r',
72 : U'\n',
73 : U' ',
74 : U'\t',
75 : U'\f',
76 : };
77 :
78 :
79 : char g_simple_tokens[] = {
80 : U'(',
81 : U')',
82 : U'{',
83 : U'}',
84 : U',',
85 : U':',
86 : //U'=',
87 : U'+',
88 : U'-',
89 : U'*',
90 : U'%',
91 : };
92 :
93 :
94 95 : std::string white_spaces(bool force = false, bool newlines = true)
95 : {
96 95 : std::string result;
97 95 : int count(rand() % 30);
98 95 : if(!force)
99 : {
100 94 : count -= 20;
101 : }
102 : else
103 : {
104 1 : ++count;
105 : }
106 95 : if(count > 0)
107 : {
108 197 : for(int i(0); i < count; ++i)
109 : {
110 166 : if(newlines)
111 : {
112 150 : int const space(rand() % sizeof(g_white_spaces));
113 150 : result += g_white_spaces[space];
114 : }
115 : else
116 : {
117 16 : int const space(rand() % (sizeof(g_white_spaces) - 2) + 2);
118 16 : result += g_white_spaces[space];
119 : }
120 : }
121 : }
122 95 : return result;
123 0 : }
124 :
125 :
126 :
127 : } // no name namespace
128 :
129 :
130 :
131 18 : CATCH_TEST_CASE("reporter_lexer", "[lexer][reporter]")
132 : {
133 18 : CATCH_START_SECTION("reporter_lexer: empty input")
134 : {
135 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("empty.rprtr", "");
136 :
137 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
138 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
139 :
140 1 : CATCH_REQUIRE(l.get_filename() == "empty.rprtr");
141 1 : }
142 18 : CATCH_END_SECTION()
143 :
144 18 : CATCH_START_SECTION("reporter_lexer: white spaces only input")
145 : {
146 3 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("white-spaces-only.rprtr", white_spaces(true));
147 :
148 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
149 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
150 1 : }
151 18 : CATCH_END_SECTION()
152 :
153 18 : CATCH_START_SECTION("reporter_lexer: simple tokens")
154 : {
155 11 : for(auto const c : g_simple_tokens)
156 : {
157 30 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("simple-token.rprtr", white_spaces() + c + white_spaces());
158 :
159 10 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
160 10 : CATCH_REQUIRE(t.get_token() == static_cast<SNAP_CATCH2_NAMESPACE::reporter::token_t>(c));
161 10 : t = l.next_token();
162 10 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
163 10 : }
164 : }
165 18 : CATCH_END_SECTION()
166 :
167 18 : CATCH_START_SECTION("reporter_lexer: divide token")
168 : {
169 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("divide.rprtr",
170 2 : white_spaces()
171 4 : + "35.3"
172 4 : + white_spaces()
173 4 : + "/"
174 4 : + white_spaces()
175 4 : + "17.2"
176 5 : + white_spaces());
177 :
178 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
179 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
180 1 : CATCH_REQUIRE(t.get_floating_point() == 35.3);
181 1 : t = l.next_token();
182 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DIVIDE);
183 1 : t = l.next_token();
184 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
185 1 : CATCH_REQUIRE(t.get_floating_point() == 17.2);
186 1 : t = l.next_token();
187 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
188 1 : }
189 18 : CATCH_END_SECTION()
190 :
191 18 : CATCH_START_SECTION("reporter_lexer: simple comment")
192 : {
193 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("float-and-comment.rprtr",
194 2 : white_spaces()
195 4 : + "45.7"
196 4 : + white_spaces()
197 4 : + "//"
198 4 : + white_spaces(false, false) // avoid newlines in those white spaces
199 4 : + "17.2"
200 5 : + white_spaces(false, false));
201 :
202 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
203 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
204 1 : CATCH_REQUIRE(t.get_floating_point() == 45.7);
205 1 : t = l.next_token();
206 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
207 1 : }
208 18 : CATCH_END_SECTION()
209 :
210 18 : CATCH_START_SECTION("reporter_lexer: divide and comments token")
211 : {
212 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("divide-and-comments.rprtr",
213 2 : white_spaces()
214 4 : + "65.31 // this is a float\n"
215 4 : + white_spaces()
216 4 : + "/ // we want to divide it\r\n"
217 4 : + white_spaces()
218 4 : + "71.2 // by another float\n"
219 5 : + white_spaces());
220 :
221 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
222 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
223 1 : CATCH_REQUIRE(t.get_floating_point() == 65.31);
224 1 : t = l.next_token();
225 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DIVIDE);
226 1 : t = l.next_token();
227 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
228 1 : CATCH_REQUIRE(t.get_floating_point() == 71.2);
229 1 : t = l.next_token();
230 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
231 1 : }
232 18 : CATCH_END_SECTION()
233 :
234 18 : CATCH_START_SECTION("reporter_lexer: hexadecimal tokens")
235 : {
236 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("divide-and-comments.rprtr",
237 : "0x4511231232abcdef\n"
238 2 : + white_spaces()
239 4 : + "0XFFFabc // we want to divide it\r\n"
240 4 : + white_spaces()
241 5 : + "0x04d4b1a2 // by another float\n");
242 :
243 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
244 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
245 1 : CATCH_REQUIRE(t.get_integer() == 0x4511231232abcdef);
246 1 : t = l.next_token();
247 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
248 1 : CATCH_REQUIRE(t.get_integer() == 0xFFFABC);
249 1 : t = l.next_token();
250 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
251 1 : CATCH_REQUIRE(t.get_integer() == 0x04d4b1a2);
252 1 : t = l.next_token();
253 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
254 1 : }
255 18 : CATCH_END_SECTION()
256 :
257 18 : CATCH_START_SECTION("reporter_lexer: NaN token")
258 : {
259 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("divide-and-comments.rprtr", "NaN\n");
260 :
261 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
262 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
263 1 : CATCH_REQUIRE(std::isnan(t.get_floating_point()));
264 1 : t = l.next_token();
265 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
266 1 : }
267 18 : CATCH_END_SECTION()
268 :
269 18 : CATCH_START_SECTION("reporter_lexer: compare and comments token")
270 : {
271 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("divide-and-comments.rprtr",
272 2 : white_spaces()
273 4 : + "65.31 // this is a float\n"
274 4 : + white_spaces()
275 4 : + "<=> // we want to compare it\r\n"
276 4 : + white_spaces()
277 4 : + "-71.2 // by another float\n"
278 5 : + white_spaces());
279 :
280 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
281 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
282 1 : CATCH_REQUIRE(t.get_floating_point() == 65.31);
283 1 : t = l.next_token();
284 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_COMPARE);
285 1 : t = l.next_token();
286 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_MINUS);
287 1 : t = l.next_token();
288 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
289 1 : CATCH_REQUIRE(t.get_floating_point() == 71.2);
290 1 : t = l.next_token();
291 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
292 1 : }
293 18 : CATCH_END_SECTION()
294 :
295 18 : CATCH_START_SECTION("reporter_lexer: variable tokens")
296 : {
297 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("variables.rprtr",
298 2 : white_spaces()
299 4 : + "$var // simple name\n"
300 4 : + white_spaces()
301 4 : + "$_Var123 // different characters\n"
302 4 : + white_spaces()
303 4 : + "${Quoted_Variable_3} // inside { and }\n"
304 5 : + white_spaces());
305 :
306 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
307 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_VARIABLE);
308 1 : CATCH_REQUIRE(t.get_string() == "var");
309 1 : t = l.next_token();
310 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_VARIABLE);
311 1 : CATCH_REQUIRE(t.get_string() == "_Var123");
312 1 : t = l.next_token();
313 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_VARIABLE);
314 1 : CATCH_REQUIRE(t.get_string() == "Quoted_Variable_3");
315 1 : t = l.next_token();
316 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
317 1 : }
318 18 : CATCH_END_SECTION()
319 :
320 18 : CATCH_START_SECTION("reporter_lexer: date tokens")
321 : {
322 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("dates.rprtr",
323 2 : white_spaces()
324 4 : + "@1710686374.536271827 // %s.%N timespec\n"
325 4 : + white_spaces()
326 4 : + "@\"03/17/2024 14:35:22\" // double quote %D %T\n"
327 4 : + white_spaces()
328 4 : + "@'05/29/2023 07:41:23' // single quote %D %T\n"
329 5 : + white_spaces());
330 :
331 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
332 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_TIMESPEC);
333 1 : CATCH_REQUIRE(t.get_integer() == 0x65F700A6000000001FF6DBD3_int128);
334 1 : t = l.next_token();
335 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_TIMESPEC);
336 : //std::cerr << "2024 time: " << std::hex << t.get_integer() << "\n";
337 1 : CATCH_REQUIRE(t.get_integer() == 0x65F6FFAA0000000000000000_int128);
338 1 : t = l.next_token();
339 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_TIMESPEC);
340 : //std::cerr << "2023 time: " << std::hex << t.get_integer() << "\n";
341 1 : CATCH_REQUIRE(t.get_integer() == 0x647457230000000000000000_int128);
342 1 : t = l.next_token();
343 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
344 1 : }
345 18 : CATCH_END_SECTION()
346 :
347 18 : CATCH_START_SECTION("reporter_lexer: IP tokens")
348 : {
349 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("ips.rprtr",
350 2 : white_spaces()
351 4 : + "<128.71.3.227> // IPv4 (no port means port 0)\n"
352 4 : + white_spaces()
353 4 : + "<127.0.4.127:8080> // IPv4 with a port\n"
354 4 : + white_spaces()
355 4 : + "<200.6.7.98:443> // another IPv4 with a port\n"
356 4 : + white_spaces()
357 4 : + "<*:53> // localhost IPv4/6 with a port, output as IPv6\n"
358 4 : + white_spaces()
359 4 : + "<[feff::9ab:32:1b6]:2424> // IPv6\n"
360 5 : + white_spaces());
361 :
362 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
363 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS);
364 1 : CATCH_REQUIRE(t.get_string() == "128.71.3.227:0");
365 1 : t = l.next_token();
366 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS);
367 1 : CATCH_REQUIRE(t.get_string() == "127.0.4.127:8080");
368 1 : t = l.next_token();
369 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS);
370 1 : CATCH_REQUIRE(t.get_string() == "200.6.7.98:443");
371 1 : t = l.next_token();
372 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS);
373 1 : CATCH_REQUIRE(t.get_string() == "[::1]:53");
374 1 : t = l.next_token();
375 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS);
376 1 : CATCH_REQUIRE(t.get_string() == "[feff::9ab:32:1b6]:2424");
377 1 : t = l.next_token();
378 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
379 1 : }
380 18 : CATCH_END_SECTION()
381 :
382 18 : CATCH_START_SECTION("reporter_lexer: double string tokens")
383 : {
384 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("strings.rprtr",
385 2 : white_spaces()
386 4 : + "\"\" // empty string\n"
387 4 : + white_spaces()
388 4 : + "\"simple\"\n"
389 4 : + white_spaces()
390 4 : + "\"newline \\n\"\n"
391 4 : + white_spaces()
392 4 : + "\"carriage return \\r\"\n"
393 4 : + white_spaces()
394 4 : + "\"both \\r\\n\"\n"
395 4 : + white_spaces()
396 4 : + "\"backspace \\b\"\n"
397 4 : + white_spaces()
398 4 : + "\"bell \\a\"\n"
399 4 : + white_spaces()
400 4 : + "\"formfeed \\f\"\n"
401 4 : + white_spaces()
402 4 : + "\"tab \\t\"\n"
403 4 : + white_spaces()
404 4 : + "\"vertical tab \\v\"\n"
405 4 : + white_spaces()
406 4 : + "\"others \\\\ \\\" \\' \\`\"\n"
407 5 : + white_spaces());
408 :
409 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
410 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
411 1 : CATCH_REQUIRE(t.get_string() == "");
412 1 : t = l.next_token();
413 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
414 1 : CATCH_REQUIRE(t.get_string() == "simple");
415 1 : t = l.next_token();
416 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
417 1 : CATCH_REQUIRE(t.get_string() == "newline \n");
418 1 : t = l.next_token();
419 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
420 1 : CATCH_REQUIRE(t.get_string() == "carriage return \r");
421 1 : t = l.next_token();
422 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
423 1 : CATCH_REQUIRE(t.get_string() == "both \r\n");
424 1 : t = l.next_token();
425 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
426 1 : CATCH_REQUIRE(t.get_string() == "backspace \b");
427 1 : t = l.next_token();
428 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
429 1 : CATCH_REQUIRE(t.get_string() == "bell \a");
430 1 : t = l.next_token();
431 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
432 1 : CATCH_REQUIRE(t.get_string() == "formfeed \f");
433 1 : t = l.next_token();
434 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
435 1 : CATCH_REQUIRE(t.get_string() == "tab \t");
436 1 : t = l.next_token();
437 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
438 1 : CATCH_REQUIRE(t.get_string() == "vertical tab \v");
439 1 : t = l.next_token();
440 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
441 1 : CATCH_REQUIRE(t.get_string() == "others \\ \" ' `");
442 1 : t = l.next_token();
443 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
444 1 : }
445 18 : CATCH_END_SECTION()
446 :
447 18 : CATCH_START_SECTION("reporter_lexer: currently unsupported backslash tokens")
448 : {
449 : // at this point the following are not implemented
450 : //
451 1 : char unimplemented[] = {
452 : 'x', 'u', 'U',
453 : '0', '1', '2', '3', '4',
454 : '5', '6', '7', '8', '9',
455 : };
456 14 : for(auto const c : unimplemented)
457 : {
458 65 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("backslashes.rprtr", std::string("test: \"\\") + c + "5\"");
459 13 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
460 13 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
461 13 : CATCH_REQUIRE(t.get_string() == "test");
462 13 : t = l.next_token();
463 13 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_COLON);
464 52 : CATCH_REQUIRE_THROWS_MATCHES(
465 : l.next_token()
466 : , libexcept::fixme
467 : , Catch::Matchers::ExceptionMessage("fixme: sorry, the \\... with a number to define a character are not yet supported."));
468 13 : }
469 : }
470 18 : CATCH_END_SECTION()
471 :
472 18 : CATCH_START_SECTION("reporter_lexer: single string tokens")
473 : {
474 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("strings.rprtr",
475 2 : white_spaces()
476 4 : + "'' // empty string\n"
477 4 : + white_spaces()
478 4 : + "'simple'\n"
479 4 : + white_spaces()
480 4 : + "'newline \\n'\n"
481 4 : + white_spaces()
482 4 : + "'carriage return \\r'\n"
483 4 : + white_spaces()
484 4 : + "'both \\r\\n'\n"
485 4 : + white_spaces()
486 4 : + "'backspace \\b'\n"
487 4 : + white_spaces()
488 4 : + "'bell \\a'\n"
489 4 : + white_spaces()
490 4 : + "'formfeed \\f'\n"
491 4 : + white_spaces()
492 4 : + "'tab \\t'\n"
493 4 : + white_spaces()
494 4 : + "'vertical tab \\v'\n"
495 4 : + white_spaces()
496 4 : + "'others \\\\ \\\" \\' \\`'\n"
497 5 : + white_spaces());
498 :
499 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
500 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
501 1 : CATCH_REQUIRE(t.get_string() == "");
502 1 : t = l.next_token();
503 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
504 1 : CATCH_REQUIRE(t.get_string() == "simple");
505 1 : t = l.next_token();
506 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
507 1 : CATCH_REQUIRE(t.get_string() == "newline \n");
508 1 : t = l.next_token();
509 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
510 1 : CATCH_REQUIRE(t.get_string() == "carriage return \r");
511 1 : t = l.next_token();
512 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
513 1 : CATCH_REQUIRE(t.get_string() == "both \r\n");
514 1 : t = l.next_token();
515 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
516 1 : CATCH_REQUIRE(t.get_string() == "backspace \b");
517 1 : t = l.next_token();
518 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
519 1 : CATCH_REQUIRE(t.get_string() == "bell \a");
520 1 : t = l.next_token();
521 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
522 1 : CATCH_REQUIRE(t.get_string() == "formfeed \f");
523 1 : t = l.next_token();
524 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
525 1 : CATCH_REQUIRE(t.get_string() == "tab \t");
526 1 : t = l.next_token();
527 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
528 1 : CATCH_REQUIRE(t.get_string() == "vertical tab \v");
529 1 : t = l.next_token();
530 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING);
531 1 : CATCH_REQUIRE(t.get_string() == "others \\ \" ' `");
532 1 : t = l.next_token();
533 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
534 1 : }
535 18 : CATCH_END_SECTION()
536 :
537 18 : CATCH_START_SECTION("reporter_lexer: integer tokens")
538 : {
539 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("integers.rprtr",
540 2 : white_spaces()
541 4 : + "0\n"
542 4 : + white_spaces()
543 4 : + "1001\n"
544 4 : + white_spaces()
545 4 : + "-34\n"
546 4 : + white_spaces()
547 4 : + "+99\n"
548 5 : + white_spaces());
549 :
550 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
551 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
552 1 : CATCH_REQUIRE(t.get_integer() == 0);
553 1 : t = l.next_token();
554 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
555 1 : CATCH_REQUIRE(t.get_integer() == 1001);
556 1 : t = l.next_token();
557 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_MINUS);
558 1 : t = l.next_token();
559 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
560 1 : CATCH_REQUIRE(t.get_integer() == 34);
561 1 : t = l.next_token();
562 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_PLUS);
563 1 : t = l.next_token();
564 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_INTEGER);
565 1 : CATCH_REQUIRE(t.get_integer() == 99);
566 1 : t = l.next_token();
567 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
568 1 : }
569 18 : CATCH_END_SECTION()
570 :
571 18 : CATCH_START_SECTION("reporter_lexer: floating point tokens")
572 : {
573 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("floating-points.rprtr",
574 2 : white_spaces()
575 4 : + "3.\n"
576 4 : + white_spaces()
577 4 : + ".7\n"
578 4 : + white_spaces()
579 4 : + "10.01\n"
580 4 : + white_spaces()
581 4 : + "-34e-34\n"
582 4 : + white_spaces()
583 4 : + "+99e+3\n"
584 5 : + white_spaces());
585 :
586 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
587 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
588 1 : CATCH_REQUIRE(t.get_floating_point() == 3.0);
589 1 : t = l.next_token();
590 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
591 1 : CATCH_REQUIRE(t.get_floating_point() == 0.7);
592 1 : t = l.next_token();
593 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
594 1 : CATCH_REQUIRE(t.get_floating_point() == 10.01);
595 1 : t = l.next_token();
596 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_MINUS);
597 1 : t = l.next_token();
598 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
599 1 : CATCH_REQUIRE(t.get_floating_point() == 34e-34);
600 1 : t = l.next_token();
601 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_PLUS);
602 1 : t = l.next_token();
603 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_FLOATING_POINT);
604 1 : CATCH_REQUIRE(t.get_floating_point() == 99e+3);
605 1 : t = l.next_token();
606 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
607 1 : }
608 18 : CATCH_END_SECTION()
609 :
610 18 : CATCH_START_SECTION("reporter_lexer: identifier tokens")
611 : {
612 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("identifiers.rprtr",
613 2 : white_spaces()
614 4 : + "simple\n"
615 4 : + white_spaces()
616 4 : + "TEST\n"
617 4 : + white_spaces()
618 4 : + "_underscore\n"
619 4 : + white_spaces()
620 4 : + "Number123\n"
621 4 : + white_spaces()
622 4 : + "Inside_Underscore\n"
623 4 : + white_spaces()
624 4 : + "End_\n"
625 5 : + white_spaces());
626 :
627 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
628 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
629 1 : CATCH_REQUIRE(t.get_string() == "simple");
630 1 : t = l.next_token();
631 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
632 1 : CATCH_REQUIRE(t.get_string() == "TEST");
633 1 : t = l.next_token();
634 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
635 1 : CATCH_REQUIRE(t.get_string() == "_underscore");
636 1 : t = l.next_token();
637 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
638 1 : CATCH_REQUIRE(t.get_string() == "Number123");
639 1 : t = l.next_token();
640 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
641 1 : CATCH_REQUIRE(t.get_string() == "Inside_Underscore");
642 1 : t = l.next_token();
643 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
644 1 : CATCH_REQUIRE(t.get_string() == "End_");
645 1 : t = l.next_token();
646 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
647 1 : }
648 18 : CATCH_END_SECTION()
649 18 : }
650 :
651 :
652 3 : CATCH_TEST_CASE("reporter_lexer_file", "[lexer][reporter][file]")
653 : {
654 3 : CATCH_START_SECTION("reporter_lexer_file: file does not exist")
655 : {
656 3 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer("unknown.rprtr"));
657 1 : CATCH_REQUIRE(l == nullptr);
658 1 : }
659 3 : CATCH_END_SECTION()
660 :
661 3 : CATCH_START_SECTION("reporter_lexer_file: exact filename")
662 : {
663 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
664 1 : std::string const filename(source_dir + "/tests/rprtr/test_load_with_create_lexer.rprtr"); // include the extension
665 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
666 1 : CATCH_REQUIRE(l != nullptr);
667 :
668 : // print(message: "it worked.")
669 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l->next_token());
670 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
671 1 : CATCH_REQUIRE(t.get_string() == "print");
672 1 : t = l->next_token();
673 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_OPEN_PARENTHESIS);
674 1 : t = l->next_token();
675 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
676 1 : CATCH_REQUIRE(t.get_string() == "message");
677 1 : t = l->next_token();
678 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_COLON);
679 1 : t = l->next_token();
680 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
681 1 : CATCH_REQUIRE(t.get_string() == "it worked.");
682 1 : t = l->next_token();
683 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_CLOSE_PARENTHESIS);
684 1 : t = l->next_token();
685 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
686 1 : }
687 3 : CATCH_END_SECTION()
688 :
689 3 : CATCH_START_SECTION("reporter_lexer_file: filename without extension")
690 : {
691 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
692 1 : std::string const filename(source_dir + "/tests/rprtr/test_load_with_create_lexer"); // exclude the extension
693 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
694 1 : CATCH_REQUIRE(l != nullptr);
695 :
696 : // print(message: "it worked.")
697 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l->next_token());
698 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
699 1 : CATCH_REQUIRE(t.get_string() == "print");
700 1 : t = l->next_token();
701 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_OPEN_PARENTHESIS);
702 1 : t = l->next_token();
703 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
704 1 : CATCH_REQUIRE(t.get_string() == "message");
705 1 : t = l->next_token();
706 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_COLON);
707 1 : t = l->next_token();
708 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_DOUBLE_STRING);
709 1 : CATCH_REQUIRE(t.get_string() == "it worked.");
710 1 : t = l->next_token();
711 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_CLOSE_PARENTHESIS);
712 1 : t = l->next_token();
713 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
714 1 : }
715 3 : CATCH_END_SECTION()
716 3 : }
717 :
718 :
719 20 : CATCH_TEST_CASE("reporter_lexer_error", "[lexer][reporter][error]")
720 : {
721 20 : CATCH_START_SECTION("reporter_lexer_error: unterminated string")
722 : {
723 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-string.rprtr", "\"unterminated");
724 :
725 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
726 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
727 1 : t = l.next_token();
728 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
729 1 : }
730 20 : CATCH_END_SECTION()
731 :
732 20 : CATCH_START_SECTION("reporter_lexer_error: multi-line string")
733 : {
734 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("multi-line-string.rprtr", "\"multi\nline\"");
735 :
736 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
737 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
738 1 : t = l.next_token();
739 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
740 1 : CATCH_REQUIRE(t.get_string() == "line");
741 1 : t = l.next_token();
742 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
743 1 : t = l.next_token();
744 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
745 1 : }
746 20 : CATCH_END_SECTION()
747 :
748 20 : CATCH_START_SECTION("reporter_lexer_error: unterminated string in backslash case")
749 : {
750 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-backslash.rprtr",
751 5 : "\"string with \\");
752 :
753 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
754 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
755 1 : t = l.next_token();
756 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
757 1 : }
758 20 : CATCH_END_SECTION()
759 :
760 20 : CATCH_START_SECTION("reporter_lexer_error: empty unquoted variable")
761 : {
762 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("empty-variable.rprtr", "empty $ variable name");
763 :
764 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
765 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
766 1 : CATCH_REQUIRE(t.get_string() == "empty");
767 1 : t = l.next_token();
768 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
769 1 : t = l.next_token();
770 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
771 1 : CATCH_REQUIRE(t.get_string() == "variable");
772 1 : t = l.next_token();
773 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
774 1 : CATCH_REQUIRE(t.get_string() == "name");
775 1 : t = l.next_token();
776 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
777 1 : }
778 20 : CATCH_END_SECTION()
779 :
780 20 : CATCH_START_SECTION("reporter_lexer_error: empty quoted variable")
781 : {
782 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("empty-quoted-variable.rprtr", "empty ${} quoted variable name");
783 :
784 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
785 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
786 1 : CATCH_REQUIRE(t.get_string() == "empty");
787 1 : t = l.next_token();
788 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
789 1 : t = l.next_token();
790 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
791 1 : CATCH_REQUIRE(t.get_string() == "quoted");
792 1 : t = l.next_token();
793 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
794 1 : CATCH_REQUIRE(t.get_string() == "variable");
795 1 : t = l.next_token();
796 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
797 1 : CATCH_REQUIRE(t.get_string() == "name");
798 1 : t = l.next_token();
799 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
800 1 : }
801 20 : CATCH_END_SECTION()
802 :
803 20 : CATCH_START_SECTION("reporter_lexer_error: invalid quoted variable name")
804 : {
805 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("invalid-variable-name.rprtr", "${bad name}");
806 :
807 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
808 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
809 1 : t = l.next_token();
810 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
811 1 : CATCH_REQUIRE(t.get_string() == "name");
812 1 : t = l.next_token();
813 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_CLOSE_CURLY_BRACE);
814 1 : t = l.next_token();
815 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
816 1 : }
817 20 : CATCH_END_SECTION()
818 :
819 20 : CATCH_START_SECTION("reporter_lexer_error: empty date (double quote)")
820 : {
821 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-date.rprtr", "@\"\"");
822 :
823 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
824 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
825 1 : t = l.next_token();
826 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
827 1 : }
828 20 : CATCH_END_SECTION()
829 :
830 20 : CATCH_START_SECTION("reporter_lexer_error: empty date (single quote)")
831 : {
832 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-date.rprtr", "@''");
833 :
834 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
835 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
836 1 : t = l.next_token();
837 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
838 1 : }
839 20 : CATCH_END_SECTION()
840 :
841 20 : CATCH_START_SECTION("reporter_lexer_error: unterminated date")
842 : {
843 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-date.rprtr", "@\"unterminated");
844 :
845 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
846 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
847 1 : t = l.next_token();
848 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
849 1 : }
850 20 : CATCH_END_SECTION()
851 :
852 20 : CATCH_START_SECTION("reporter_lexer_error: unterminated IP")
853 : {
854 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-ip.rprtr", "<128.71.3.227");
855 :
856 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
857 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
858 1 : t = l.next_token();
859 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
860 1 : }
861 20 : CATCH_END_SECTION()
862 :
863 20 : CATCH_START_SECTION("reporter_lexer_error: bad IP (bad name)")
864 : {
865 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unterminated-ip.rprtr", "<some bad IP address>");
866 :
867 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
868 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
869 1 : t = l.next_token();
870 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
871 1 : }
872 20 : CATCH_END_SECTION()
873 :
874 20 : CATCH_START_SECTION("reporter_lexer_error: empty IP")
875 : {
876 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("empty-ip.rprtr", "<>");
877 :
878 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
879 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
880 1 : t = l.next_token();
881 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
882 1 : }
883 20 : CATCH_END_SECTION()
884 :
885 20 : CATCH_START_SECTION("reporter_lexer_error: IP range is not available")
886 : {
887 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("ip-range.rprtr", "<10.0.1.0-10.0.1.255>");
888 :
889 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
890 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
891 1 : t = l.next_token();
892 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
893 1 : }
894 20 : CATCH_END_SECTION()
895 :
896 20 : CATCH_START_SECTION("reporter_lexer_error: no from IP")
897 : {
898 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("no-from-ip.rprtr", "<-10.0.1.255>");
899 :
900 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
901 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
902 1 : t = l.next_token();
903 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
904 1 : }
905 20 : CATCH_END_SECTION()
906 :
907 20 : CATCH_START_SECTION("reporter_lexer_error: bad integer")
908 : {
909 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("bad-integers.rprtr",
910 : "10000000000000000000\n"
911 : "1-1\n"
912 5 : "1+1\n");
913 :
914 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
915 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
916 3 : for(int i(0); i < 2; ++i)
917 : {
918 2 : t = l.next_token();
919 2 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
920 : }
921 1 : t = l.next_token();
922 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
923 1 : }
924 20 : CATCH_END_SECTION()
925 :
926 20 : CATCH_START_SECTION("reporter_lexer_error: bad floating points")
927 : {
928 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("bad-floating-points.rprtr",
929 : "3.3e+\n"
930 : "3.3e++5\n"
931 : "3.3ee+5\n"
932 : "3.3EE+5\n"
933 : "3.3EE++5\n"
934 : "3e++5\n"
935 : "3ee+5\n"
936 : "3EE+5\n"
937 : "3EE++5\n"
938 : "3.3e-\n"
939 : "3.3e--5\n"
940 : "3.3ee-5\n"
941 : "3.3EE-5\n"
942 : "3.3EE--5\n"
943 : "3e--5\n"
944 : "3ee-5\n"
945 : "3EE-5\n"
946 : "3EE--5\n"
947 : "3..3e-3\n"
948 : "3.3.e-5\n"
949 : "3.3e.+6\n"
950 : "3.3e-.5\n"
951 5 : "3.3e9.\n");
952 :
953 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
954 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
955 23 : for(int i(0); i < 22; ++i)
956 : {
957 22 : t = l.next_token();
958 22 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
959 : }
960 1 : t = l.next_token();
961 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
962 1 : }
963 20 : CATCH_END_SECTION()
964 :
965 20 : CATCH_START_SECTION("reporter_lexer_error: variable name cannot start with digit")
966 : {
967 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unexpected-digit.rprtr",
968 : "$5var\n"
969 5 : "${0digits_allowed}\n");
970 :
971 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
972 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
973 2 : for(int i(0); i < 1; ++i)
974 : {
975 1 : t = l.next_token();
976 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
977 : }
978 1 : t = l.next_token();
979 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
980 1 : }
981 20 : CATCH_END_SECTION()
982 :
983 20 : CATCH_START_SECTION("reporter_lexer_error: unexpected character")
984 : {
985 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("unexpected-character.rprtr",
986 : "\\\n"
987 5 : "#\n");
988 :
989 1 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
990 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
991 2 : for(int i(0); i < 1; ++i)
992 : {
993 1 : t = l.next_token();
994 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR);
995 : }
996 1 : t = l.next_token();
997 1 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_EOF);
998 1 : }
999 20 : CATCH_END_SECTION()
1000 :
1001 20 : CATCH_START_SECTION("reporter_lexer_error: unsupported backslash tokens")
1002 : {
1003 : // there are likely never going to ever be supported
1004 : //
1005 1 : char unimplemented[] = {
1006 : 'q', 'z',
1007 : };
1008 3 : for(auto const c : unimplemented)
1009 : {
1010 10 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("backslashes.rprtr", std::string("test: \"\\") + c + "5\"");
1011 2 : SNAP_CATCH2_NAMESPACE::reporter::token t(l.next_token());
1012 2 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER);
1013 2 : CATCH_REQUIRE(t.get_string() == "test");
1014 2 : t = l.next_token();
1015 2 : CATCH_REQUIRE(t.get_token() == SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_COLON);
1016 8 : CATCH_REQUIRE_THROWS_MATCHES(
1017 : l.next_token()
1018 : , ed::runtime_error
1019 : , Catch::Matchers::ExceptionMessage(std::string("event_dispatcher_exception: invalid escape character '") + c + "'."));
1020 2 : }
1021 : }
1022 20 : CATCH_END_SECTION()
1023 :
1024 20 : CATCH_START_SECTION("reporter_lexer_error: invalid hexadecimal number")
1025 : {
1026 : {
1027 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("backslashes.rprtr", "0x");
1028 4 : CATCH_REQUIRE_THROWS_MATCHES(
1029 : l.next_token()
1030 : , ed::runtime_error
1031 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: invalid hexadecimal number, at least one digits was expected."));
1032 1 : }
1033 : {
1034 5 : SNAP_CATCH2_NAMESPACE::reporter::lexer l("backslashes.rprtr", "0X");
1035 4 : CATCH_REQUIRE_THROWS_MATCHES(
1036 : l.next_token()
1037 : , ed::runtime_error
1038 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: invalid hexadecimal number, at least one digits was expected."));
1039 1 : }
1040 : }
1041 20 : CATCH_END_SECTION()
1042 20 : }
1043 :
1044 :
1045 : // vim: ts=4 sw=4 et
|