1 /*
2 This file is part of Magnum.
3
4 Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
5 Vladimír Vondruš <mosra@centrum.cz>
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 and/or sell copies of the Software, and to permit persons to whom the
12 Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 DEALINGS IN THE SOFTWARE.
24 */
25
26 #include <tuple>
27 #include <Corrade/TestSuite/Tester.h>
28 #include <Corrade/Utility/DebugStl.h>
29
30 #include "Magnum/OpenDdl/Document.h"
31 #include "Magnum/OpenDdl/Property.h"
32 #include "Magnum/OpenDdl/Implementation/Parsers.h"
33
34 namespace Magnum { namespace OpenDdl { namespace Test { namespace {
35
36 struct ParsersTest: TestSuite::Tester {
37 explicit ParsersTest();
38
39 void equals();
40 void findLastOf();
41 void whitespace();
42 void onelineComment();
43 void multilineComment();
44
45 void escapedCharInvalid();
46 void escapedChar();
47 void escapedCharHex();
48
49 void escapedUnicodeInvalid();
50 void escapedUnicode4();
51 void escapedUnicode6();
52
53 void identifierInvalid();
54 void identifier();
55
56 void boolLiteralInvalid();
57 void boolLiteral();
58
59 void characterLiteralInvalid();
60 void characterLiteral();
61 void characterLiteralEscaped();
62
63 void integerLiteralInvalid();
64 void integerLiteral();
65 void integerLiteralChar();
66 void integerLiteralBinary();
67
68 void floatLiteralInvalid();
69 void floatLiteral();
70 void floatLiteralBinary();
71
72 void stringLiteralInvalid();
73 void stringLiteralEmpty();
74 void stringLiteral();
75 void stringLiteralEscaped();
76 void stringLiteralConcatenated();
77
78 void nameLiteralInvalid();
79 void nameLiteral();
80
81 void referenceLiteralInvalid();
82 void referenceLiteralNull();
83 void referenceLiteral();
84
85 void typeLiteralInvalid();
86 void typeLiteral();
87
88 void propertyValueInvalid();
89 void propertyValueBool();
90 void propertyValueIntegral();
91 void propertyValueCharacter();
92 void propertyValueBinary();
93 void propertyValueFloatingPoint();
94 void propertyValueString();
95 void propertyValueReference();
96 void propertyValueReferenceNull();
97 void propertyValueType();
98 };
99
ParsersTest()100 ParsersTest::ParsersTest() {
101 addTests({&ParsersTest::equals,
102 &ParsersTest::findLastOf,
103 &ParsersTest::whitespace,
104 &ParsersTest::onelineComment,
105 &ParsersTest::multilineComment,
106
107 &ParsersTest::escapedCharInvalid,
108 &ParsersTest::escapedChar,
109 &ParsersTest::escapedCharHex,
110
111 &ParsersTest::escapedUnicodeInvalid,
112 &ParsersTest::escapedUnicode4,
113 &ParsersTest::escapedUnicode6,
114
115 &ParsersTest::identifierInvalid,
116 &ParsersTest::identifier,
117
118 &ParsersTest::boolLiteralInvalid,
119 &ParsersTest::boolLiteral,
120
121 &ParsersTest::characterLiteralInvalid,
122 &ParsersTest::characterLiteral,
123 &ParsersTest::characterLiteralEscaped,
124
125 &ParsersTest::integerLiteralInvalid,
126 &ParsersTest::integerLiteral,
127 &ParsersTest::integerLiteralChar,
128 &ParsersTest::integerLiteralBinary,
129
130 &ParsersTest::floatLiteralInvalid,
131 &ParsersTest::floatLiteral,
132 &ParsersTest::floatLiteralBinary,
133
134 &ParsersTest::stringLiteralInvalid,
135 &ParsersTest::stringLiteralEmpty,
136 &ParsersTest::stringLiteral,
137 &ParsersTest::stringLiteralEscaped,
138 &ParsersTest::stringLiteralConcatenated,
139
140 &ParsersTest::nameLiteralInvalid,
141 &ParsersTest::nameLiteral,
142
143 &ParsersTest::referenceLiteralInvalid,
144 &ParsersTest::referenceLiteralNull,
145 &ParsersTest::referenceLiteral,
146
147 &ParsersTest::typeLiteralInvalid,
148 &ParsersTest::typeLiteral,
149
150 &ParsersTest::propertyValueInvalid,
151 &ParsersTest::propertyValueBool,
152 &ParsersTest::propertyValueIntegral,
153 &ParsersTest::propertyValueCharacter,
154 &ParsersTest::propertyValueBinary,
155 &ParsersTest::propertyValueFloatingPoint,
156 &ParsersTest::propertyValueString,
157 &ParsersTest::propertyValueReference,
158 &ParsersTest::propertyValueReferenceNull,
159 &ParsersTest::propertyValueType});
160 }
161
162 #define VERIFY_PARSED(e, data, i, parsed) \
163 CORRADE_COMPARE(e.error, Implementation::ParseErrorType::NoError); \
164 CORRADE_VERIFY(i >= data.begin()); \
165 CORRADE_COMPARE((std::string{data.begin(), std::size_t(i - data.begin())}), parsed);
166
equals()167 void ParsersTest::equals() {
168 CharacterLiteral a{"HelloWorld"};
169 CharacterLiteral b{"Hello"};
170
171 CORRADE_VERIFY(Implementation::equals(a, a));
172 CORRADE_VERIFY(!Implementation::equals(a, b));
173 CORRADE_VERIFY(!Implementation::equals(b, a));
174 }
175
findLastOf()176 void ParsersTest::findLastOf() {
177 /* I'm too lazy to create another VERIFY_SUFFIX_PARSED(), so I'll test to
178 prefix instead */
179 CharacterLiteral a{"$hello%world"};
180 auto ai = Implementation::findLastOf(a, "$%");
181 VERIFY_PARSED(Implementation::ParseError{}, a, ai, "$hello");
182
183 CharacterLiteral b{"%hello$world"};
184 auto bi = Implementation::findLastOf(b, "$%");
185 VERIFY_PARSED(Implementation::ParseError{}, b, bi, "%hello");
186
187 Containers::ArrayView<const char> c{"%", 0};
188 auto ci = Implementation::findLastOf({c, 0}, "$%");
189 VERIFY_PARSED(Implementation::ParseError{}, c, ci, "");
190 }
191
whitespace()192 void ParsersTest::whitespace() {
193 CharacterLiteral a{""};
194 auto ai = Implementation::whitespace(a);
195 VERIFY_PARSED(Implementation::ParseError{}, a, ai, "");
196
197 /* Just whitespace */
198 CharacterLiteral b{"\n "};
199 auto bi = Implementation::whitespace(b);
200 VERIFY_PARSED(Implementation::ParseError{}, b, bi, "\n ");
201
202 /* Whitespace and something after */
203 CharacterLiteral c{" \b \t \n X"};
204 auto ci = Implementation::whitespace(c);
205 VERIFY_PARSED(Implementation::ParseError{}, c, ci, " \b \t \n ");
206 }
207
onelineComment()208 void ParsersTest::onelineComment() {
209 CharacterLiteral a{" \b \t // comment \nX"};
210 auto ai = Implementation::whitespace(a);
211 VERIFY_PARSED(Implementation::ParseError{}, a, ai, " \b \t // comment \n");
212
213 CharacterLiteral b{" \b \t // comment /* other comment \n*/ \nX"};
214 auto bi = Implementation::whitespace(b);
215 VERIFY_PARSED(Implementation::ParseError{}, b, bi, " \b \t // comment /* other comment \n");
216 }
217
multilineComment()218 void ParsersTest::multilineComment() {
219 CharacterLiteral a{" \b \t /* comment \n bla \n comment */X"};
220 auto ai = Implementation::whitespace(a);
221 VERIFY_PARSED(Implementation::ParseError{}, a, ai, " \b \t /* comment \n bla \n comment */");
222
223 CharacterLiteral b{" \b \t /* comment \n // bla \n comment */X"};
224 auto bi = Implementation::whitespace(b);
225 VERIFY_PARSED(Implementation::ParseError{}, b, bi, " \b \t /* comment \n // bla \n comment */");
226 }
227
escapedCharInvalid()228 void ParsersTest::escapedCharInvalid() {
229 Implementation::ParseError error;
230
231 CORRADE_VERIFY(!Implementation::escapedChar(CharacterLiteral{"\\"}, error).first);
232 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
233
234 CORRADE_VERIFY(!Implementation::escapedChar(CharacterLiteral{"\\h"}, error).first);
235 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
236
237 CORRADE_VERIFY(!Implementation::escapedChar(CharacterLiteral{"\\x1"}, error).first);
238 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
239 }
240
escapedChar()241 void ParsersTest::escapedChar() {
242 CharacterLiteral a{"\\nX"};
243
244 Implementation::ParseError error;
245 const char* ai;
246 char c;
247 std::tie(ai, c) = Implementation::escapedChar(a, error);
248 VERIFY_PARSED(error, a, ai, "\\n");
249 CORRADE_COMPARE(c, '\n');
250 }
251
escapedCharHex()252 void ParsersTest::escapedCharHex() {
253 CharacterLiteral a{"\\x0AX"};
254
255 Implementation::ParseError error;
256 const char* ai;
257 char c;
258 std::tie(ai, c) = Implementation::escapedChar(a, error);
259 VERIFY_PARSED(error, a, ai, "\\x0A");
260 CORRADE_COMPARE(c, '\n');
261 }
262
escapedUnicodeInvalid()263 void ParsersTest::escapedUnicodeInvalid() {
264 Implementation::ParseError error;
265 std::string s;
266
267 CORRADE_VERIFY(!Implementation::escapedUnicode(CharacterLiteral{"\\"}, s, error));
268 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
269
270 CORRADE_VERIFY(!Implementation::escapedUnicode(CharacterLiteral{"\\u123"}, s, error));
271 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
272
273 CORRADE_VERIFY(!Implementation::escapedUnicode(CharacterLiteral{"\\U12345"}, s, error));
274 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidEscapeSequence);
275 }
276
escapedUnicode4()277 void ParsersTest::escapedUnicode4() {
278 CharacterLiteral a{"\\u006dX"};
279 Implementation::ParseError error;
280 std::string s;
281 const char* ai = Implementation::escapedUnicode(a, s, error);
282 VERIFY_PARSED(error, a, ai, "\\u006d");
283 CORRADE_EXPECT_FAIL("Not yet implemented.");
284 CORRADE_COMPARE(s, "m");
285 }
286
escapedUnicode6()287 void ParsersTest::escapedUnicode6() {
288 CharacterLiteral a{"\\U00006DX"};
289 Implementation::ParseError error;
290 std::string s;
291 const char* ai = Implementation::escapedUnicode(a, s, error);
292 VERIFY_PARSED(error, a, ai, "\\U00006D");
293 CORRADE_EXPECT_FAIL("Not yet implemented.");
294 CORRADE_COMPARE(s, "m");
295 }
296
identifierInvalid()297 void ParsersTest::identifierInvalid() {
298 Implementation::ParseError error;
299
300 CORRADE_VERIFY(!Implementation::identifier(CharacterLiteral{""}, error));
301 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedIdentifier);
302
303 CORRADE_VERIFY(!Implementation::identifier(CharacterLiteral{"0"}, error));
304 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidIdentifier);
305 }
306
identifier()307 void ParsersTest::identifier() {
308 CharacterLiteral a{"my_mesh,"};
309 Implementation::ParseError error;
310 const char* ai = Implementation::identifier(a, error);
311 VERIFY_PARSED(error, a, ai, "my_mesh");
312 }
313
boolLiteralInvalid()314 void ParsersTest::boolLiteralInvalid() {
315 Implementation::ParseError error;
316
317 CORRADE_VERIFY(!Implementation::boolLiteral(CharacterLiteral{""}, error).first);
318 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
319
320 CORRADE_VERIFY(!Implementation::boolLiteral(CharacterLiteral{"TRUE"}, error).first);
321 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
322 }
323
boolLiteral()324 void ParsersTest::boolLiteral() {
325 CharacterLiteral a{"trueX"};
326
327 Implementation::ParseError error;
328 const char* ai;
329 bool value;
330 std::tie(ai, value) = Implementation::boolLiteral(a, error);
331 VERIFY_PARSED(error, a, ai, "true");
332 CORRADE_COMPARE(value, true);
333 }
334
characterLiteralInvalid()335 void ParsersTest::characterLiteralInvalid() {
336 Implementation::ParseError error;
337
338 CORRADE_VERIFY(!Implementation::characterLiteral(CharacterLiteral{""}, error).first);
339 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidCharacterLiteral);
340
341 CORRADE_VERIFY(!Implementation::characterLiteral(CharacterLiteral{"'"}, error).first);
342 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidCharacterLiteral);
343
344 CORRADE_VERIFY(!Implementation::characterLiteral(CharacterLiteral{"'a"}, error).first);
345 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidCharacterLiteral);
346
347 CORRADE_VERIFY(!Implementation::characterLiteral(CharacterLiteral{"'\n"}, error).first);
348 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidCharacterLiteral);
349 }
350
characterLiteral()351 void ParsersTest::characterLiteral() {
352 CharacterLiteral a{"'a'X"};
353
354 Implementation::ParseError error;
355 const char* ai;
356 char value;
357 std::tie(ai, value) = Implementation::characterLiteral(a, error);
358 VERIFY_PARSED(error, a, ai, "'a'");
359 CORRADE_COMPARE(value, 'a');
360 }
361
characterLiteralEscaped()362 void ParsersTest::characterLiteralEscaped() {
363 CharacterLiteral a{"'\\n'X"};
364
365 Implementation::ParseError error;
366 const char* ai;
367 char value;
368 std::tie(ai, value) = Implementation::characterLiteral(a, error);
369 VERIFY_PARSED(error, a, ai, "'\\n'");
370 CORRADE_COMPARE(value, '\n');
371 }
372
integerLiteralInvalid()373 void ParsersTest::integerLiteralInvalid() {
374 Implementation::ParseError error;
375 std::string buffer;
376
377 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{""}, buffer, error)));
378 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedLiteral);
379
380 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{"+"}, buffer, error)));
381 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
382
383 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{"A"}, buffer, error)));
384 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
385
386 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{"_1"}, buffer, error)));
387 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
388
389 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{"0b_1"}, buffer, error)));
390 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
391
392 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<Short>(CharacterLiteral{"32768"}, buffer, error)));
393 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::LiteralOutOfRange);
394
395 CORRADE_VERIFY(!std::get<0>(Implementation::integralLiteral<UnsignedShort>(CharacterLiteral{"-1"}, buffer, error)));
396 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::LiteralOutOfRange);
397 }
398
integerLiteral()399 void ParsersTest::integerLiteral() {
400 CharacterLiteral a{"-3_7X"};
401
402 Implementation::ParseError error;
403 std::string buffer;
404 const char* ai;
405 Short value;
406 Int base;
407 std::tie(ai, value, base) = Implementation::integralLiteral<Short>(a, buffer, error);
408 VERIFY_PARSED(error, a, ai, "-3_7");
409 CORRADE_COMPARE(value, -37);
410 CORRADE_COMPARE(base, 10);
411 }
412
integerLiteralChar()413 void ParsersTest::integerLiteralChar() {
414 CharacterLiteral a{"+'a'X"};
415
416 Implementation::ParseError error;
417 std::string buffer;
418 const char* ai;
419 Short value;
420 Int base;
421 std::tie(ai, value, base) = Implementation::integralLiteral<Short>(a, buffer, error);
422 VERIFY_PARSED(error, a, ai, "+'a'");
423 CORRADE_COMPARE(value, 'a');
424 CORRADE_COMPARE(base, 256);
425 }
426
integerLiteralBinary()427 void ParsersTest::integerLiteralBinary() {
428 CharacterLiteral a{"-0o7_5"};
429
430 Implementation::ParseError error;
431 std::string buffer;
432 const char* ai;
433 Short value;
434 Int base;
435 std::tie(ai, value, base) = Implementation::integralLiteral<Short>(a, buffer, error);
436 VERIFY_PARSED(error, a, ai, "-0o7_5");
437 CORRADE_COMPARE(value, -075);
438 CORRADE_COMPARE(base, 8);
439 }
440
floatLiteralInvalid()441 void ParsersTest::floatLiteralInvalid() {
442 Implementation::ParseError error;
443 std::string buffer;
444
445 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{""}, buffer, error).first);
446 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedLiteral);
447
448 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{"+"}, buffer, error).first);
449 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
450
451 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{"A"}, buffer, error).first);
452 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
453
454 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{"_1"}, buffer, error).first);
455 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
456
457 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{"."}, buffer, error).first);
458 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
459
460 CORRADE_VERIFY(!Implementation::floatingPointLiteral<Float>(CharacterLiteral{"0.e-"}, buffer, error).first);
461 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
462 }
463
floatLiteral()464 void ParsersTest::floatLiteral() {
465 CharacterLiteral a{"-1_.0_0e+5X"};
466
467 Implementation::ParseError error;
468 std::string buffer;
469 const char* ai;
470 Float value;
471 std::tie(ai, value) = Implementation::floatingPointLiteral<Float>(a, buffer, error);
472 VERIFY_PARSED(error, a, ai, "-1_.0_0e+5");
473 CORRADE_COMPARE(value, -1.0e+5);
474 }
475
floatLiteralBinary()476 void ParsersTest::floatLiteralBinary() {
477 CharacterLiteral a{"-0xbad_cafe_X"};
478
479 Implementation::ParseError error;
480 std::string buffer;
481 const char* ai;
482 Float value;
483 std::tie(ai, value) = Implementation::floatingPointLiteral<Float>(a, buffer, error);
484 VERIFY_PARSED(error, a, ai, "-0xbad_cafe_");
485 UnsignedInt v = 0xbadcafe;
486 CORRADE_COMPARE(value, -reinterpret_cast<Float&>(v));
487 }
488
stringLiteralInvalid()489 void ParsersTest::stringLiteralInvalid() {
490 Implementation::ParseError error;
491
492 CORRADE_VERIFY(!Implementation::stringLiteral(CharacterLiteral{""}, error).first);
493 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedLiteral);
494
495 CORRADE_VERIFY(!Implementation::stringLiteral(CharacterLiteral{"\""}, error).first);
496 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::LiteralOutOfRange);
497
498 CORRADE_VERIFY(!Implementation::stringLiteral(CharacterLiteral{"\"\n\""}, error).first);
499 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
500 }
501
stringLiteralEmpty()502 void ParsersTest::stringLiteralEmpty() {
503 CharacterLiteral a{"\"\"X"};
504
505 Implementation::ParseError error;
506 const char* ai;
507 std::string value;
508 std::tie(ai, value) = Implementation::stringLiteral(a, error);
509 VERIFY_PARSED(error, a, ai, "\"\"");
510 CORRADE_COMPARE(value, "");
511 }
512
stringLiteral()513 void ParsersTest::stringLiteral() {
514 CharacterLiteral a{"\"abc ěšč\"X"};
515
516 Implementation::ParseError error;
517 const char* ai;
518 std::string value;
519 std::tie(ai, value) = Implementation::stringLiteral(a, error);
520 VERIFY_PARSED(error, a, ai, "\"abc ěšč\"");
521 CORRADE_COMPARE(value, "abc ěšč");
522 }
523
stringLiteralEscaped()524 void ParsersTest::stringLiteralEscaped() {
525 CharacterLiteral a{"\"abc \\n0\\\" heh\"X"};
526
527 Implementation::ParseError error;
528 const char* ai;
529 std::string value;
530 std::tie(ai, value) = Implementation::stringLiteral(a, error);
531 VERIFY_PARSED(error, a, ai, "\"abc \\n0\\\" heh\"");
532 CORRADE_COMPARE(value, "abc \n0\" heh");
533 }
534
stringLiteralConcatenated()535 void ParsersTest::stringLiteralConcatenated() {
536 CharacterLiteral a{"\"abc\" /* comment */ \" ěšč\"X"};
537
538 Implementation::ParseError error;
539 const char* ai;
540 std::string value;
541 std::tie(ai, value) = Implementation::stringLiteral(a, error);
542 VERIFY_PARSED(error, a, ai, "\"abc\" /* comment */ \" ěšč\"");
543 CORRADE_COMPARE(value, "abc ěšč");
544 }
545
nameLiteralInvalid()546 void ParsersTest::nameLiteralInvalid() {
547 Implementation::ParseError error;
548
549 CORRADE_VERIFY(!Implementation::nameLiteral(CharacterLiteral{""}, error).first);
550 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedName);
551
552 CORRADE_VERIFY(!Implementation::nameLiteral(CharacterLiteral{"a"}, error).first);
553 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidName);
554
555 CORRADE_VERIFY(!Implementation::nameLiteral(CharacterLiteral{"$"}, error).first);
556 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedIdentifier);
557 }
558
nameLiteral()559 void ParsersTest::nameLiteral() {
560 CharacterLiteral a{"%my_array,"};
561
562 Implementation::ParseError error;
563 const char* ai;
564 std::string value;
565 std::tie(ai, value) = Implementation::nameLiteral(a, error);
566 VERIFY_PARSED(error, a, ai, "%my_array");
567 CORRADE_COMPARE(value, "%my_array");
568 }
569
referenceLiteralInvalid()570 void ParsersTest::referenceLiteralInvalid() {
571 Implementation::ParseError error;
572
573 CORRADE_VERIFY(!Implementation::referenceLiteral(CharacterLiteral{""}, error).first);
574 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedLiteral);
575
576 CORRADE_VERIFY(!Implementation::referenceLiteral(CharacterLiteral{"a"}, error).first);
577 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
578
579 CORRADE_VERIFY(!Implementation::referenceLiteral(CharacterLiteral{"%"}, error).first);
580 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedIdentifier);
581
582 CORRADE_VERIFY(!Implementation::referenceLiteral(CharacterLiteral{"$%a"}, error).first);
583 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidIdentifier);
584 }
585
referenceLiteralNull()586 void ParsersTest::referenceLiteralNull() {
587 CharacterLiteral a{"null,"};
588
589 Implementation::ParseError error;
590 const char* ai;
591 Containers::ArrayView<const char> value;
592 std::tie(ai, value) = Implementation::referenceLiteral(a, error);
593 VERIFY_PARSED(error, a, ai, "null");
594 CORRADE_VERIFY(value.empty());
595 }
596
referenceLiteral()597 void ParsersTest::referenceLiteral() {
598 CharacterLiteral a{"$my_mesh%my_array,"};
599
600 Implementation::ParseError error;
601 const char* ai;
602 Containers::ArrayView<const char> value;
603 std::tie(ai, value) = Implementation::referenceLiteral(a, error);
604 VERIFY_PARSED(error, a, ai, "$my_mesh%my_array");
605 CORRADE_COMPARE((std::string{value, value.size()}), "$my_mesh%my_array");
606 }
607
typeLiteralInvalid()608 void ParsersTest::typeLiteralInvalid() {
609 Implementation::ParseError error;
610
611 CORRADE_VERIFY(!Implementation::typeLiteral(CharacterLiteral{""}, error).first);
612 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedLiteral);
613
614 CORRADE_VERIFY(!Implementation::typeLiteral(CharacterLiteral{"boo"}, error).first);
615 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidLiteral);
616 }
617
typeLiteral()618 void ParsersTest::typeLiteral() {
619 CharacterLiteral a{"unsigned_int16,"};
620
621 Implementation::ParseError error;
622 const char* ai;
623 Type value;
624 std::tie(ai, value) = Implementation::typeLiteral(a, error);
625 VERIFY_PARSED(error, a, ai, "unsigned_int16");
626 CORRADE_COMPARE(value, Type::UnsignedShort);
627 }
628
propertyValueInvalid()629 void ParsersTest::propertyValueInvalid() {
630 Implementation::ParseError error;
631 std::string buffer;
632
633 bool boolValue = {};
634 Int integerValue = {};
635 Float floatingPointValue = {};
636 std::string stringValue;
637 Containers::ArrayView<const char> referenceValue;
638 Type typeValue = {};
639
640 CORRADE_VERIFY(!Implementation::propertyValue(CharacterLiteral{""}, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error).first);
641 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::ExpectedPropertyValue);
642
643 CORRADE_VERIFY(!Implementation::propertyValue(CharacterLiteral{"bleh"}, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error).first);
644 CORRADE_COMPARE(error.error, Implementation::ParseErrorType::InvalidPropertyValue);
645 }
646
propertyValueBool()647 void ParsersTest::propertyValueBool() {
648 CharacterLiteral a{"true,"};
649
650 Implementation::ParseError error;
651 std::string buffer;
652 bool boolValue = {};
653 Int integerValue = {};
654 Float floatingPointValue = {};
655 std::string stringValue;
656 Containers::ArrayView<const char> referenceValue;
657 Type typeValue = {};
658 const char* ai;
659 Implementation::InternalPropertyType type;
660 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
661 VERIFY_PARSED(error, a, ai, "true");
662 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Bool);
663 CORRADE_COMPARE(boolValue, true);
664 }
665
propertyValueIntegral()666 void ParsersTest::propertyValueIntegral() {
667 CharacterLiteral a{"17, 0.0"};
668
669 Implementation::ParseError error;
670 std::string buffer;
671 bool boolValue = {};
672 Int integerValue = {};
673 Float floatingPointValue = {};
674 std::string stringValue;
675 Containers::ArrayView<const char> referenceValue;
676 Type typeValue = {};
677 const char* ai;
678 Implementation::InternalPropertyType type;
679 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
680 VERIFY_PARSED(error, a, ai, "17");
681 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Integral);
682 CORRADE_COMPARE(integerValue, 17);
683 }
684
propertyValueCharacter()685 void ParsersTest::propertyValueCharacter() {
686 CharacterLiteral a{"'a', 0.0"};
687
688 Implementation::ParseError error;
689 std::string buffer;
690 bool boolValue = {};
691 Int integerValue = {};
692 Float floatingPointValue = {};
693 std::string stringValue;
694 Containers::ArrayView<const char> referenceValue;
695 Type typeValue = {};
696 const char* ai;
697 Implementation::InternalPropertyType type;
698 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
699 VERIFY_PARSED(error, a, ai, "'a'");
700 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Character);
701 CORRADE_COMPARE(integerValue, 'a');
702 }
703
propertyValueBinary()704 void ParsersTest::propertyValueBinary() {
705 CharacterLiteral a{"0xff, 0.0"};
706
707 Implementation::ParseError error;
708 std::string buffer;
709 bool boolValue = {};
710 Int integerValue = {};
711 Float floatingPointValue = {};
712 std::string stringValue;
713 Containers::ArrayView<const char> referenceValue;
714 Type typeValue = {};
715 const char* ai;
716 Implementation::InternalPropertyType type;
717 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
718 VERIFY_PARSED(error, a, ai, "0xff");
719 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Binary);
720 CORRADE_COMPARE(integerValue, 0xff);
721 }
722
propertyValueFloatingPoint()723 void ParsersTest::propertyValueFloatingPoint() {
724 CharacterLiteral a{"15.0_0,"};
725
726 Implementation::ParseError error;
727 std::string buffer;
728 bool boolValue = {};
729 Int integerValue = {};
730 Float floatingPointValue = {};
731 std::string stringValue;
732 Containers::ArrayView<const char> referenceValue;
733 Type typeValue = {};
734 const char* ai;
735 Implementation::InternalPropertyType type;
736 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
737 VERIFY_PARSED(error, a, ai, "15.0_0");
738 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Float);
739 CORRADE_COMPARE(floatingPointValue, 15.0f);
740 }
741
propertyValueString()742 void ParsersTest::propertyValueString() {
743 CharacterLiteral a{"\"hello\","};
744
745 Implementation::ParseError error;
746 std::string buffer;
747 bool boolValue = {};
748 Int integerValue = {};
749 Float floatingPointValue = {};
750 std::string stringValue;
751 Containers::ArrayView<const char> referenceValue;
752 Type typeValue = {};
753 const char* ai;
754 Implementation::InternalPropertyType type;
755 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
756 VERIFY_PARSED(error, a, ai, "\"hello\"");
757 CORRADE_COMPARE(type, Implementation::InternalPropertyType::String);
758 CORRADE_COMPARE(stringValue, "hello");
759 }
760
propertyValueReference()761 void ParsersTest::propertyValueReference() {
762 CharacterLiteral a{"%my_array2,"};
763
764 Implementation::ParseError error;
765 std::string buffer;
766 bool boolValue = {};
767 Int integerValue = {};
768 Float floatingPointValue = {};
769 std::string stringValue;
770 Containers::ArrayView<const char> referenceValue;
771 Type typeValue = {};
772 const char* ai;
773 Implementation::InternalPropertyType type;
774 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
775 VERIFY_PARSED(error, a, ai, "%my_array2");
776 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Reference);
777 CORRADE_COMPARE((std::string{referenceValue, referenceValue.size()}), "%my_array2");
778 }
779
propertyValueReferenceNull()780 void ParsersTest::propertyValueReferenceNull() {
781 CharacterLiteral a{"null,"};
782
783 Implementation::ParseError error;
784 std::string buffer;
785 bool boolValue = {};
786 Int integerValue = {};
787 Float floatingPointValue = {};
788 std::string stringValue;
789 Containers::ArrayView<const char> referenceValue;
790 Type typeValue = {};
791 const char* ai;
792 Implementation::InternalPropertyType type;
793 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
794 VERIFY_PARSED(error, a, ai, "null");
795 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Reference);
796 CORRADE_VERIFY(referenceValue.empty());
797 }
798
propertyValueType()799 void ParsersTest::propertyValueType() {
800 CharacterLiteral a{"float,"};
801
802 Implementation::ParseError error;
803 std::string buffer;
804 bool boolValue = {};
805 Int integerValue = {};
806 Float floatingPointValue = {};
807 std::string stringValue;
808 Containers::ArrayView<const char> referenceValue;
809 Type typeValue = {};
810 const char* ai;
811 Implementation::InternalPropertyType type;
812 std::tie(ai, type) = Implementation::propertyValue(a, boolValue, integerValue, floatingPointValue, stringValue, referenceValue, typeValue, buffer, error);
813 VERIFY_PARSED(error, a, ai, "float");
814 CORRADE_COMPARE(type, Implementation::InternalPropertyType::Type);
815 CORRADE_COMPARE(typeValue, Type::Float);
816 }
817
818 }}}}
819
820 CORRADE_TEST_MAIN(Magnum::OpenDdl::Test::ParsersTest)
821