1 /**
2 * @file
3 * @brief Test cases for code about shared parser
4 */
5
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18 See the GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 */
25
26 #include "test_shared.h"
27 #include "test_parser.h"
28 #include "../shared/ufotypes.h"
29 #include "../shared/parse.h"
30
31 /**
32 * The suite initialization function.
33 * Returns zero on success, non-zero otherwise.
34 */
UFO_InitSuiteParser(void)35 static int UFO_InitSuiteParser (void)
36 {
37 TEST_Init();
38 return 0;
39 }
40
41 /**
42 * The suite cleanup function.
43 * Returns zero on success, non-zero otherwise.
44 */
UFO_CleanSuiteParser(void)45 static int UFO_CleanSuiteParser (void)
46 {
47 TEST_Shutdown();
48 return 0;
49 }
50
51 /**
52 * @brief unittest around default use of parser
53 */
testParser(void)54 static void testParser (void)
55 {
56 const char* string = "aa \t\n {\"bbb(bbb bbb)bbb {\"{a}\n/* foooo { } \n { } */\n// fooooo\naaaa";
57 const char* cursor = string;
58 const char* token;
59
60 token = Com_Parse(&cursor);
61 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
62 CU_ASSERT_STRING_EQUAL(token, "aa");
63
64 token = Com_Parse(&cursor);
65 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
66 CU_ASSERT_STRING_EQUAL(token, "{");
67
68 token = Com_Parse(&cursor);
69 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
70 CU_ASSERT_STRING_EQUAL(token, "bbb(bbb bbb)bbb {");
71
72 token = Com_Parse(&cursor);
73 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
74 CU_ASSERT_STRING_EQUAL(token, "{");
75
76 token = Com_Parse(&cursor);
77 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
78 CU_ASSERT_STRING_EQUAL(token, "a");
79
80 token = Com_Parse(&cursor);
81 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
82 CU_ASSERT_STRING_EQUAL(token, "}");
83
84 token = Com_Parse(&cursor);
85 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
86 CU_ASSERT_STRING_EQUAL(token, "aaaa");
87
88 token = Com_Parse(&cursor);
89 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_EOF);
90 CU_ASSERT_STRING_EQUAL(token, "\0");
91 }
92
93 /**
94 * @brief unittest to check back slash entity conversion
95 */
testParserWithEntity(void)96 static void testParserWithEntity (void)
97 {
98 const char* string = "\n\taaaa \" \\n \\t \\\" \"";
99 const char* cursor = string;
100 const char* token;
101
102 token = Com_Parse(&cursor);
103 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
104 CU_ASSERT_STRING_EQUAL(token, "aaaa");
105
106 token = Com_Parse(&cursor);
107 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
108 CU_ASSERT_STRING_EQUAL(token, " \n \t \" ");
109 }
110
111 /**
112 * @brief unittest around default use of parser
113 */
testParserWithUnParse(void)114 static void testParserWithUnParse (void)
115 {
116 const char* string = "aaaaa\n\tbbbbb \"ccccc\"";
117 const char* cursor = string;
118 const char* token;
119
120 token = Com_Parse(&cursor);
121 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
122 CU_ASSERT_STRING_EQUAL(token, "aaaaa");
123
124 Com_UnParseLastToken();
125
126 token = Com_Parse(&cursor);
127 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
128 CU_ASSERT_STRING_EQUAL(token, "aaaaa");
129
130 Com_UnParseLastToken();
131
132 token = Com_Parse(&cursor);
133 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
134 CU_ASSERT_STRING_EQUAL(token, "aaaaa");
135
136 token = Com_Parse(&cursor);
137 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
138 CU_ASSERT_STRING_EQUAL(token, "bbbbb");
139
140 Com_UnParseLastToken();
141
142 token = Com_Parse(&cursor);
143 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
144 CU_ASSERT_STRING_EQUAL(token, "bbbbb");
145
146 Com_UnParseLastToken();
147
148 token = Com_Parse(&cursor);
149 CU_ASSERT_NOT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
150 CU_ASSERT_STRING_EQUAL(token, "bbbbb");
151
152 token = Com_Parse(&cursor);
153 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
154 CU_ASSERT_STRING_EQUAL(token, "ccccc");
155
156 Com_UnParseLastToken();
157
158 token = Com_Parse(&cursor);
159 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
160 CU_ASSERT_STRING_EQUAL(token, "ccccc");
161
162 Com_UnParseLastToken();
163
164 token = Com_Parse(&cursor);
165 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
166 CU_ASSERT_STRING_EQUAL(token, "ccccc");
167 }
168
169 /**
170 * @brief unittest around default use of parser
171 */
testParserWithFunctionScriptToken(void)172 static void testParserWithFunctionScriptToken (void)
173 {
174 const char* string = "aa \t\n aa,({\"bbb(bbb bbb)bbb {\"{a}\n/* foooo { } \n { } */\n// fooooo\naaaa)";
175 const char* cursor = string;
176 const char* token;
177
178 token = Com_Parse(&cursor);
179 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_WORD);
180 CU_ASSERT_STRING_EQUAL(token, "aa");
181
182 token = Com_Parse(&cursor);
183 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_WORD);
184 CU_ASSERT_STRING_EQUAL(token, "aa");
185
186 token = Com_Parse(&cursor);
187 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_COMMA);
188 CU_ASSERT_STRING_EQUAL(token, ",");
189
190 token = Com_Parse(&cursor);
191 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_BEGIN_LIST);
192 CU_ASSERT_STRING_EQUAL(token, "(");
193
194 token = Com_Parse(&cursor);
195 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_BEGIN_BLOCK);
196 CU_ASSERT_STRING_EQUAL(token, "{");
197
198 token = Com_Parse(&cursor);
199 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_QUOTED_WORD);
200 CU_ASSERT_STRING_EQUAL(token, "bbb(bbb bbb)bbb {");
201
202 token = Com_Parse(&cursor);
203 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_BEGIN_BLOCK);
204 CU_ASSERT_STRING_EQUAL(token, "{");
205
206 token = Com_Parse(&cursor);
207 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_WORD);
208 CU_ASSERT_STRING_EQUAL(token, "a");
209
210 token = Com_Parse(&cursor);
211 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_END_BLOCK);
212 CU_ASSERT_STRING_EQUAL(token, "}");
213
214 token = Com_Parse(&cursor);
215 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_WORD);
216 CU_ASSERT_STRING_EQUAL(token, "aaaa");
217
218 token = Com_Parse(&cursor);
219 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_END_LIST);
220 CU_ASSERT_STRING_EQUAL(token, ")");
221
222 token = Com_Parse(&cursor);
223 CU_ASSERT_EQUAL(Com_GetType(&cursor), TT_EOF);
224 CU_ASSERT_STRING_EQUAL(token, "\0");
225 }
226
227 /**
228 * @brief unittest around common type
229 */
testParserCommonType(void)230 static void testParserCommonType (void)
231 {
232 int ivalue;
233 bool bvalue;
234 float fvalue;
235 align_t align;
236 blend_t blend;
237 style_t style;
238 fade_t fade;
239 size_t bytes;
240 int result;
241
242 /* boolean */
243
244 bytes = 0;
245 result = Com_ParseValue (&bvalue, "true", V_BOOL, 0, sizeof(bool), &bytes);
246 CU_ASSERT_EQUAL(result, RESULT_OK);
247 CU_ASSERT_EQUAL(bvalue, 1);
248 CU_ASSERT_EQUAL(bytes, sizeof(bool));
249
250 bytes = 0;
251 result = Com_ParseValue (&bvalue, "false", V_BOOL, 0, sizeof(bool), &bytes);
252 CU_ASSERT_EQUAL(result, RESULT_OK);
253 CU_ASSERT_EQUAL(bvalue, 0);
254 CU_ASSERT_EQUAL(bytes, sizeof(bool));
255
256 bytes = 0;
257 result = Com_ParseValue (&bvalue, "foo", V_BOOL, 0, sizeof(int), &bytes);
258 CU_ASSERT_EQUAL(result, RESULT_ERROR);
259 CU_ASSERT_EQUAL(bytes, 0);
260
261 /* int */
262
263 bytes = 0;
264 result = Com_ParseValue (&ivalue, "10", V_INT, 0, sizeof(int), &bytes);
265 CU_ASSERT_EQUAL(result, RESULT_OK);
266 CU_ASSERT_EQUAL(ivalue, 10);
267 CU_ASSERT_EQUAL(bytes, sizeof(int));
268
269 bytes = 0;
270 result = Com_ParseValue (&ivalue, "abc", V_INT, 0, sizeof(int), &bytes);
271 CU_ASSERT_EQUAL(result, RESULT_ERROR);
272 CU_ASSERT_EQUAL(bytes, 0);
273
274 /* float */
275
276 bytes = 0;
277 result = Com_ParseValue (&fvalue, "1.1", V_FLOAT, 0, sizeof(float), &bytes);
278 CU_ASSERT_EQUAL(result, RESULT_OK);
279 CU_ASSERT_EQUAL(fvalue, 1.1f);
280 CU_ASSERT_EQUAL(bytes, sizeof(float));
281
282 bytes = 0;
283 result = Com_ParseValue (&fvalue, "9.8", V_FLOAT, 0, sizeof(float), &bytes);
284 CU_ASSERT_EQUAL(result, RESULT_OK);
285 CU_ASSERT_EQUAL(fvalue, 9.8f);
286 CU_ASSERT_EQUAL(bytes, sizeof(float));
287
288 bytes = 0;
289 result = Com_ParseValue (&fvalue, "abc", V_FLOAT, 0, sizeof(float), &bytes);
290 CU_ASSERT_EQUAL(result, RESULT_ERROR);
291 CU_ASSERT_EQUAL(bytes, 0);
292
293 /** @todo V_POS */
294 /** @todo V_VECTOR */
295 /** @todo V_COLOR */
296 /** @todo V_STRING */
297 /** @todo V_TRANSLATION_STRING */
298 /** @todo V_LONGSTRING */
299
300 /* align */
301
302 bytes = 0;
303 result = Com_ParseValue (&align, "cc", V_ALIGN, 0, sizeof(align_t), &bytes);
304 CU_ASSERT_EQUAL(result, RESULT_OK);
305 CU_ASSERT_EQUAL(align, ALIGN_CC);
306 CU_ASSERT_EQUAL(bytes, sizeof(align_t));
307
308 bytes = 0;
309 result = Com_ParseValue (&align, "abc", V_ALIGN, 0, sizeof(align_t), &bytes);
310 CU_ASSERT_EQUAL(result, RESULT_ERROR);
311 CU_ASSERT_EQUAL(bytes, 0);
312
313 /* blend */
314
315 bytes = 0;
316 result = Com_ParseValue (&blend, "blend", V_BLEND, 0, sizeof(blend_t), &bytes);
317 CU_ASSERT_EQUAL(result, RESULT_OK);
318 CU_ASSERT_EQUAL(blend, BLEND_BLEND);
319 CU_ASSERT_EQUAL(bytes, sizeof(blend_t));
320
321 bytes = 0;
322 result = Com_ParseValue (&blend, "abc", V_BLEND, 0, sizeof(blend_t), &bytes);
323 CU_ASSERT_EQUAL(result, RESULT_ERROR);
324 CU_ASSERT_EQUAL(bytes, 0);
325
326 /* style */
327
328 bytes = 0;
329 result = Com_ParseValue (&style, "rotated", V_STYLE, 0, sizeof(style_t), &bytes);
330 CU_ASSERT_EQUAL(result, RESULT_OK);
331 CU_ASSERT_EQUAL(style, STYLE_ROTATED);
332 CU_ASSERT_EQUAL(bytes, sizeof(style_t));
333
334 bytes = 0;
335 result = Com_ParseValue (&style, "abc", V_STYLE, 0, sizeof(style_t), &bytes);
336 CU_ASSERT_EQUAL(result, RESULT_ERROR);
337 CU_ASSERT_EQUAL(bytes, 0);
338
339 /* fade */
340
341 bytes = 0;
342 result = Com_ParseValue (&fade, "sin", V_FADE, 0, sizeof(fade_t), &bytes);
343 CU_ASSERT_EQUAL(result, RESULT_OK);
344 CU_ASSERT_EQUAL(fade, FADE_SIN);
345 CU_ASSERT_EQUAL(bytes, sizeof(fade_t));
346
347 bytes = 0;
348 result = Com_ParseValue (&fade, "abc", V_FADE, 0, sizeof(fade_t), &bytes);
349 CU_ASSERT_EQUAL(result, RESULT_ERROR);
350 CU_ASSERT_EQUAL(bytes, 0);
351
352 }
353
354 /**
355 * @brief unittest to check well formed list
356 */
testParserListOk(void)357 static void testParserListOk (void)
358 {
359 const char* string = " ( aaa \n \"bbb\" \t ccc \n \n ) ";
360 const char* cursor = string;
361 linkedList_t* list;
362
363 if (!Com_ParseList(&cursor, &list)) {
364 CU_FAIL_FATAL("List parsing failed");
365 }
366
367 CU_ASSERT_EQUAL_FATAL(LIST_Count(list), 3);
368
369 CU_ASSERT_STRING_EQUAL(list->data, "aaa");
370 CU_ASSERT_STRING_EQUAL(list->next->data, "bbb");
371 CU_ASSERT_STRING_EQUAL(list->next->next->data, "ccc");
372
373 LIST_Delete(&list);
374 }
375
376
377 /**
378 * @brief unittest to check well formed empty list
379 */
testParserListOkEmpty(void)380 static void testParserListOkEmpty (void)
381 {
382 const char* string = " ( \n ) ()";
383 const char* cursor = string;
384 linkedList_t* list;
385
386 if (!Com_ParseList(&cursor, &list)) {
387 CU_FAIL_FATAL("List parsing failed");
388 }
389
390 CU_ASSERT_EQUAL_FATAL(LIST_Count(list), 0);
391
392 if (!Com_ParseList(&cursor, &list)) {
393 CU_FAIL_FATAL("List parsing failed");
394 }
395
396 CU_ASSERT_EQUAL_FATAL(LIST_Count(list), 0);
397 }
398
399 /**
400 * @brief unittest to check wrong list with EOF
401 */
testParserListKoEOF(void)402 static void testParserListKoEOF (void)
403 {
404 const char* string = " ( aaa \n bbb \t ccc \n \n";
405 const char* cursor = string;
406 linkedList_t* list;
407
408 if (Com_ParseList(&cursor, &list)) {
409 CU_FAIL_FATAL("List parsing succeed, which is wrong");
410 }
411 }
412
413 /**
414 * @brief unittest to check wrong list with unexpected token
415 */
testParserListKoWrongToken(void)416 static void testParserListKoWrongToken (void)
417 {
418 const char* string = " ( aaa \n bbb \t ccc \n \n } ";
419 const char* cursor = string;
420
421 linkedList_t* list;
422 if (Com_ParseList(&cursor, &list)) {
423 CU_FAIL_FATAL("List parsing succeed, which is wrong");
424 }
425 }
426
427 /**
428 * @brief unittest to check wrong list which contains another sublist
429 */
testParserListKoNewList(void)430 static void testParserListKoNewList (void)
431 {
432 const char* string = " ( aaa \n bbb \t ccc \n \n ( ";
433 const char* cursor = string;
434 linkedList_t* list;
435
436 if (Com_ParseList(&cursor, &list)) {
437 CU_FAIL_FATAL("List parsing succeed, which is wrong");
438 }
439 }
440
UFO_AddParserTests(void)441 int UFO_AddParserTests (void)
442 {
443 /* add a suite to the registry */
444 CU_pSuite ParserSuite = CU_add_suite("ParserTests", UFO_InitSuiteParser, UFO_CleanSuiteParser);
445
446 if (ParserSuite == nullptr)
447 return CU_get_error();
448
449 /* add the tests to the suite */
450 #if PARSER_XX > 0
451 if (CU_ADD_TEST(ParserSuite, testParserXX) == nullptr)
452 return CU_get_error();
453 #else
454 if (CU_ADD_TEST(ParserSuite, testParser) == nullptr)
455 return CU_get_error();
456 if (CU_ADD_TEST(ParserSuite, testParserWithFunctionScriptToken) == nullptr)
457 return CU_get_error();
458 if (CU_ADD_TEST(ParserSuite, testParserWithUnParse) == nullptr)
459 return CU_get_error();
460 if (CU_ADD_TEST(ParserSuite, testParserWithEntity) == nullptr)
461 return CU_get_error();
462 if (CU_ADD_TEST(ParserSuite, testParserCommonType) == nullptr)
463 return CU_get_error();
464
465 if (CU_ADD_TEST(ParserSuite, testParserListOk) == nullptr)
466 return CU_get_error();
467 if (CU_ADD_TEST(ParserSuite, testParserListOkEmpty) == nullptr)
468 return CU_get_error();
469 if (CU_ADD_TEST(ParserSuite, testParserListKoEOF) == nullptr)
470 return CU_get_error();
471 if (CU_ADD_TEST(ParserSuite, testParserListKoWrongToken) == nullptr)
472 return CU_get_error();
473 if (CU_ADD_TEST(ParserSuite, testParserListKoNewList) == nullptr)
474 return CU_get_error();
475 #endif
476 return CUE_SUCCESS;
477 }
478