Line data Source code
1 : /***************************************************************************
2 : * testmod_ni.c - Test suite for nickel ini parser
3 : ****************************************************************************/
4 :
5 : /******************************************************************************
6 : * Nickel - a library for hierarchical maps and .ini files
7 : * Part of the Bohr Game Libraries (see chaoslizard.org/devel/bohr)
8 : * Copyright (C) 2008 Charles Lindsay. Some rights reserved; see COPYING.
9 : * $Id: ni.c 349 2008-01-19 18:18:22Z chaz $
10 : ******************************************************************************/
11 :
12 : #ifdef HAVE_KDBCONFIG_H
13 : #include "kdbconfig.h"
14 : #endif
15 :
16 : #include <stdio.h>
17 : #ifdef HAVE_STDLIB_H
18 : #include <stdlib.h>
19 : #endif
20 : #ifdef HAVE_STRING_H
21 : #include <string.h>
22 : #endif
23 :
24 : #include <bohr/ni.h>
25 : #include <stdint.h>
26 : #include <stdio.h>
27 : #include <string.h>
28 : #undef NDEBUG
29 : #include <assert.h>
30 : #include <tests_plugin.h>
31 :
32 : #define BEGIN_TEST(x) \
33 : void x (void) \
34 : { \
35 : int test_fail = 0;
36 :
37 : #define TEST_COND(cond) \
38 : if (!(cond) && (test_fail = 1)) printf ("%s: %s: '%s' FAILED (%s:%d)\n", argv0, __func__, #cond, __FILE__, __LINE__)
39 :
40 : #define END_TEST() \
41 : printf ("%s: %s: %s\n", argv0, __func__, (test_fail ? "FAIL" : "pass")); \
42 : if (test_fail) any_fail = 1; \
43 : }
44 : #define TEST(x) x ()
45 :
46 :
47 : char * argv0 = NULL;
48 : int any_fail = 0;
49 :
50 :
51 2 : BEGIN_TEST (ver)
52 2 : uint32_t lib_version = elektraNi_GetVersion ();
53 2 : TEST_COND (lib_version == elektraNi_VERSION);
54 2 : END_TEST ()
55 :
56 2 : BEGIN_TEST (new)
57 2 : elektraNi_node node = elektraNi_New ();
58 2 : assert (node != NULL);
59 :
60 2 : const char * name = elektraNi_GetName (node, NULL);
61 2 : TEST_COND (name == NULL);
62 :
63 2 : elektraNi_node root = elektraNi_GetRoot (node);
64 2 : TEST_COND (root == node);
65 :
66 2 : elektraNi_node parent = elektraNi_GetParent (node);
67 2 : TEST_COND (parent == NULL);
68 :
69 2 : int children = elektraNi_GetNumChildren (node);
70 2 : TEST_COND (children == 0);
71 :
72 2 : int modified = elektraNi_GetModified (node);
73 2 : TEST_COND (modified == 0);
74 :
75 2 : const char * value = elektraNi_GetValue (node, NULL);
76 2 : TEST_COND (value == NULL);
77 :
78 2 : int error = elektraNi_SetValue (node, "", 0);
79 2 : TEST_COND (error < 0);
80 :
81 2 : elektraNi_Free (node);
82 2 : END_TEST ()
83 :
84 2 : BEGIN_TEST (tree)
85 2 : elektraNi_node node = elektraNi_New ();
86 2 : assert (node != NULL);
87 :
88 2 : elektraNi_node child = elektraNi_GetChild (node, "a", -1, 1, NULL);
89 2 : assert (child != NULL);
90 :
91 2 : int children = elektraNi_GetNumChildren (node);
92 2 : TEST_COND (children == 1);
93 :
94 2 : elektraNi_node child2 = elektraNi_GetChild (child, "b", -1, 1, NULL);
95 2 : assert (child2 != NULL);
96 :
97 2 : int children2 = elektraNi_GetNumChildren (child);
98 2 : TEST_COND (children2 == 1);
99 :
100 2 : elektraNi_node child3 = elektraNi_GetChild (node, "a", -1, 1, NULL);
101 2 : TEST_COND (child3 == child);
102 :
103 2 : elektraNi_node child4 = elektraNi_GetChild (child, "b", -1, 1, NULL);
104 2 : TEST_COND (child4 == child2);
105 :
106 2 : elektraNi_Free (node);
107 2 : END_TEST ()
108 :
109 2 : BEGIN_TEST (test_values)
110 2 : elektraNi_node node = elektraNi_New ();
111 2 : assert (node != NULL);
112 :
113 2 : elektraNi_node child = elektraNi_GetChild (node, "", 0, 1, NULL);
114 2 : assert (child != NULL);
115 :
116 2 : int len = elektraNi_SetValue (child, "1", 1);
117 2 : assert (len >= 0);
118 2 : TEST_COND (len == 1);
119 :
120 2 : len = 0;
121 2 : const char * value = elektraNi_GetValue (child, &len);
122 2 : TEST_COND (!strcmp (value, "1"));
123 2 : TEST_COND (len == 1);
124 :
125 2 : long ivalue = elektraNi_GetValueInt (child);
126 2 : TEST_COND (ivalue == 1);
127 :
128 2 : double fvalue = elektraNi_GetValueFloat (child);
129 2 : TEST_COND (fvalue <= 1.01);
130 2 : TEST_COND (fvalue >= 0.99);
131 :
132 2 : int bvalue = elektraNi_GetValueBool (child);
133 2 : TEST_COND (bvalue != 0);
134 :
135 : int scanned_ivalue;
136 2 : len = elektraNi_ValueScan (child, "%i", &scanned_ivalue);
137 2 : TEST_COND (len == 1);
138 2 : TEST_COND (scanned_ivalue == 1);
139 :
140 2 : len = elektraNi_ValuePrint (child, "%.3f", 3.333);
141 2 : assert (len >= 0);
142 2 : TEST_COND (len == 5);
143 :
144 2 : value = elektraNi_GetValue (child, &len);
145 2 : TEST_COND (!strcmp (value, "3.333"));
146 2 : TEST_COND (len == 5);
147 :
148 2 : ivalue = elektraNi_GetValueInt (child);
149 2 : TEST_COND (ivalue == 3);
150 :
151 2 : fvalue = elektraNi_GetValueFloat (child);
152 2 : TEST_COND (fvalue >= 3.332);
153 2 : TEST_COND (fvalue <= 3.334);
154 :
155 2 : bvalue = elektraNi_GetValueBool (child);
156 2 : TEST_COND (bvalue != 0);
157 :
158 : float scanned_fvalue;
159 2 : len = elektraNi_ValueScan (child, "%f", &scanned_fvalue);
160 2 : TEST_COND (len == 1);
161 2 : TEST_COND (scanned_fvalue >= 3.332f);
162 2 : TEST_COND (scanned_fvalue <= 3.334f);
163 :
164 2 : len = elektraNi_SetValueInt (child, 23);
165 2 : assert (len >= 0);
166 2 : TEST_COND (len == 2);
167 :
168 2 : len = 0;
169 2 : value = elektraNi_GetValue (child, &len);
170 2 : TEST_COND (!strcmp (value, "23"));
171 2 : TEST_COND (len == 2);
172 :
173 2 : len = elektraNi_SetValueFloat (child, 4.5);
174 2 : assert (len >= 0);
175 2 : TEST_COND (len == 3);
176 :
177 2 : len = 0;
178 2 : value = elektraNi_GetValue (child, &len);
179 2 : TEST_COND (!strcmp (value, "4.5"));
180 2 : TEST_COND (len == 3);
181 :
182 2 : len = elektraNi_SetValueBool (child, 1);
183 2 : assert (len >= 0);
184 2 : TEST_COND (len == 4);
185 :
186 2 : len = 0;
187 2 : value = elektraNi_GetValue (child, &len);
188 2 : TEST_COND (!strcmp (value, "true"));
189 2 : TEST_COND (len == 4);
190 :
191 2 : len = elektraNi_ValuePrint (child, "%s", "WHOAH!");
192 2 : assert (len >= 0);
193 2 : TEST_COND (len == 6);
194 :
195 : char sval[7];
196 2 : len = elektraNi_ValueScan (child, "%6s", sval);
197 2 : TEST_COND (len == 1);
198 2 : TEST_COND (!strcmp (sval, "WHOAH!"));
199 :
200 2 : elektraNi_Free (node);
201 2 : END_TEST ()
202 :
203 2 : BEGIN_TEST (parse_spaces_quotes)
204 :
205 2 : elektraNi_node node = elektraNi_New ();
206 2 : assert (node != NULL);
207 :
208 2 : elektraNi_Free (node);
209 2 : END_TEST ()
210 :
211 2 : BEGIN_TEST (output)
212 2 : char desired[] = {
213 : ";Ni1\n"
214 : "; Generated by Nickel Plugin using Elektra (see libelektra.org).\n\n"
215 : "1 = 1's value\n\n"
216 : "[1]\n\n"
217 : " [[2]]\n"
218 : " 3 = 3's value\n"
219 : };
220 :
221 2 : elektraNi_node node = elektraNi_New ();
222 2 : assert (node != NULL);
223 :
224 2 : elektraNi_node child = elektraNi_GetChild (node, "1", -1, 1, NULL);
225 2 : assert (child != NULL);
226 :
227 2 : int len = elektraNi_SetValue (child, "1's value", -1);
228 2 : assert (len >= 0);
229 :
230 2 : elektraNi_node child2 = elektraNi_GetChild (child, "2", -1, 1, NULL);
231 2 : assert (child2 != NULL);
232 :
233 2 : elektraNi_node child3 = elektraNi_GetChild (child2, "3", -1, 1, NULL);
234 2 : assert (child3 != NULL);
235 :
236 2 : len = elektraNi_SetValue (child3, "3's value", -1);
237 2 : assert (len >= 0);
238 :
239 2 : elektraNi_node child4 = elektraNi_GetChild (node, "back to 1", -1, 1, NULL);
240 2 : assert (child4 != NULL);
241 :
242 2 : FILE * temp = tmpfile ();
243 2 : assert (temp != NULL);
244 :
245 2 : int error = elektraNi_WriteStream (node, temp, 0);
246 2 : assert (error != 0);
247 :
248 2 : rewind (temp);
249 :
250 : char buf[1024];
251 2 : len = fread (buf, sizeof (char), 1023, temp);
252 2 : assert (len <= 1023);
253 2 : buf[len] = '\0';
254 :
255 2 : TEST_COND (len * sizeof (char) == sizeof (desired) - sizeof (char) && !strcmp (buf, desired));
256 :
257 2 : fclose (temp);
258 2 : elektraNi_Free (node);
259 2 : END_TEST ()
260 :
261 2 : BEGIN_TEST (output_modified)
262 : // FIXME: this won't be correct depending on what version of Nickel's in use
263 2 : char desired[] = {
264 : ";Ni1\n"
265 : "; Generated by Nickel Plugin using Elektra (see libelektra.org).\n\n"
266 : "3 = 3's value\n"
267 : };
268 :
269 2 : elektraNi_node node = elektraNi_New ();
270 2 : assert (node != NULL);
271 :
272 2 : elektraNi_node child = elektraNi_GetChild (node, "1", -1, 1, NULL);
273 2 : assert (child != NULL);
274 :
275 2 : int len = elektraNi_SetValue (child, "1's value", -1);
276 2 : assert (len >= 0);
277 :
278 2 : elektraNi_node child2 = elektraNi_GetChild (node, "2", -1, 1, NULL);
279 2 : assert (child2 != NULL);
280 :
281 2 : elektraNi_node child3 = elektraNi_GetChild (node, "3", -1, 1, NULL);
282 2 : assert (child3 != NULL);
283 :
284 2 : len = elektraNi_SetValue (child3, "3's value", -1);
285 2 : assert (len >= 0);
286 :
287 2 : elektraNi_node child4 = elektraNi_GetChild (node, "4", -1, 1, NULL);
288 2 : assert (child4 != NULL);
289 :
290 2 : elektraNi_SetModified (node, 0, 1);
291 2 : elektraNi_SetModified (child3, 1, 0);
292 2 : elektraNi_SetModified (child4, 1, 0);
293 :
294 2 : FILE * temp = tmpfile ();
295 2 : assert (temp != NULL);
296 :
297 2 : int error = elektraNi_WriteStream (node, temp, 1);
298 2 : assert (error != 0);
299 :
300 2 : rewind (temp);
301 :
302 : char buf[1024];
303 2 : len = fread (buf, sizeof (char), 1023, temp);
304 2 : assert (len <= 1023);
305 2 : buf[len] = '\0';
306 :
307 2 : TEST_COND (len * sizeof (char) == sizeof (desired) - sizeof (char) && !strcmp (buf, desired));
308 :
309 2 : fclose (temp);
310 2 : elektraNi_Free (node);
311 2 : END_TEST ()
312 :
313 2 : BEGIN_TEST (parse_output)
314 : // clang-format off
315 2 : char * names[] = {
316 : "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooon\xc2"
317 : "\xa9",
318 : "\xc2\xa9valid UTF-8",
319 : "valid \xc2\xa9UTF-8",
320 : "valid UTF-8\xc2\xa9",
321 : "\xc3invalid UTF-8",
322 : "invalid \xc3UTF-8",
323 : "invalid UTF-8\xc3",
324 : ";asdf",
325 : "\\asdf",
326 : "[asdf",
327 : "]asdf",
328 : "=asdf",
329 : "\"asdf",
330 : "as;df",
331 : "as\\df",
332 : "as[df",
333 : "as]df",
334 : "as=df",
335 : "as\"df",
336 : " ;asdf",
337 : "\\asdf ",
338 : " [asdf",
339 : "]asdf ",
340 : " =asdf",
341 : "\"asdf ",
342 : " as;df",
343 : "as\\df ",
344 : " as[df",
345 : "as]df ",
346 : " as=df",
347 : "as\"df ",
348 : "\a\b\f\n\r\t\v"
349 : };
350 2 : char * values[] = { "truncated",
351 : "\xc2\xa9valid UTF-8",
352 : "valid \xc2\xa9UTF-8",
353 : "valid UTF-8\xc2\xa9",
354 : "\xc3invalid UTF-8",
355 : "invalid \xc3UTF-8",
356 : "invalid UTF-8\xc3",
357 : ";asdf",
358 : "\\asdf",
359 : "[asdf",
360 : "]asdf",
361 : "=asdf",
362 : "\"asdf",
363 : "as;df",
364 : "as\\df",
365 : "as[df",
366 : "as]df",
367 : "as=df",
368 : "as\"df",
369 : " ;asdf",
370 : "\\asdf ",
371 : " [asdf",
372 : "]asdf ",
373 : " =asdf",
374 : "\"asdf ",
375 : " as;df",
376 : "as\\df ",
377 : " as[df",
378 : "as]df ",
379 : " as=df",
380 : "as\"df ",
381 : "\a\b\f\n\r\t\v" };
382 : // clang-format on
383 : #define NUM_parse_output_NODES (sizeof (names) / sizeof (names[0]))
384 :
385 2 : const char * stored_name0 =
386 : "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooon"
387 : "\xc2";
388 :
389 : assert (sizeof (values) / sizeof (values[0]) == NUM_parse_output_NODES);
390 :
391 2 : elektraNi_node node = elektraNi_New ();
392 2 : assert (node != NULL);
393 :
394 : size_t i;
395 64 : for (i = 0; i < NUM_parse_output_NODES; ++i)
396 : {
397 64 : elektraNi_node child = elektraNi_GetChild (node, names[i], -1, 1, NULL);
398 64 : assert (child != NULL);
399 :
400 64 : int len = elektraNi_SetValue (child, values[i], -1);
401 64 : assert (len >= 0);
402 : }
403 :
404 : // FILE * temp = fopen("temp1.ini", "w+");
405 2 : FILE * temp = tmpfile ();
406 2 : assert (temp != NULL);
407 :
408 2 : int error = elektraNi_WriteStream (node, temp, 0);
409 2 : assert (error != 0);
410 :
411 2 : rewind (temp);
412 2 : elektraNi_Free (node);
413 :
414 2 : node = elektraNi_New ();
415 2 : assert (node != NULL);
416 :
417 2 : error = elektraNi_ReadStream (node, temp, 0);
418 2 : assert (error != 0);
419 :
420 2 : int children = elektraNi_GetNumChildren (node);
421 2 : TEST_COND (children == NUM_parse_output_NODES);
422 :
423 64 : for (i = 0; i < NUM_parse_output_NODES; ++i)
424 : {
425 64 : elektraNi_node child = elektraNi_GetChild (node, names[i], -1, 0, NULL);
426 64 : TEST_COND (child != NULL);
427 :
428 64 : const char * name = elektraNi_GetName (child, NULL);
429 64 : TEST_COND (name && !strcmp (name, (i == 0 ? stored_name0 : names[i])));
430 :
431 64 : const char * value = elektraNi_GetValue (child, NULL);
432 64 : TEST_COND (value && !strcmp (value, values[i]));
433 : }
434 :
435 : // elektraNi_WriteFile(node, "temp2.ini", 0);
436 2 : fclose (temp);
437 2 : elektraNi_Free (node);
438 : #undef NUM_parse_output_NODES
439 2 : END_TEST ()
440 :
441 2 : int main (int argc, char ** argv)
442 : {
443 2 : if (argc >= 1)
444 : {
445 2 : argv0 = argv[0];
446 : }
447 2 : printf ("NICKEL TESTS\n");
448 2 : printf ("==================\n\n");
449 :
450 2 : TEST (ver);
451 2 : TEST (new);
452 2 : TEST (tree);
453 2 : TEST (test_values);
454 2 : TEST (parse_spaces_quotes);
455 2 : TEST (output);
456 2 : TEST (output_modified);
457 2 : TEST (parse_output);
458 :
459 2 : print_result ("testmod_ni");
460 2 : return any_fail;
461 : }
|