tests/test_properties.c

changeset 924
3c90dfc35f06
equal deleted inserted replaced
923:45da884269c8 924:3c90dfc35f06
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "cx/test.h"
30
31 #include "cx/properties.h"
32
33 CX_TEST(test_cx_properties_init) {
34 CxProperties prop;
35 CX_TEST_DO {
36 cxPropertiesInitDefault(&prop);
37
38 CX_TEST_ASSERT(prop.config.delimiter == '=');
39 CX_TEST_ASSERT(prop.config.comment1 == '#');
40 CX_TEST_ASSERT(prop.config.comment2 == 0);
41 CX_TEST_ASSERT(prop.config.comment3 == 0);
42 CX_TEST_ASSERT(prop.flags == 0);
43 CX_TEST_ASSERT(prop.text == NULL);
44 CX_TEST_ASSERT(prop.buf == NULL);
45
46 cxPropertiesDestroy(&prop);
47 }
48 }
49
50 CX_TEST(test_cx_properties_next) {
51 const char *tests[] = {
52 "name = value\n",
53 "name=value\n",
54 "n=value\n",
55 "name=v\n",
56 "n=v\n",
57 "name = value # comment\n",
58 "#comment\nn=v\n",
59 "# comment1\n# comment2\n\n \n\nname = value\n",
60 " name = value\n",
61 "name = value\n\n"
62 };
63
64 const char *keys[] = {
65 "name",
66 "name",
67 "n",
68 "name",
69 "n",
70 "name",
71 "n",
72 "name",
73 "name",
74 "name"
75 };
76
77 const char *values[] = {
78 "value",
79 "value",
80 "value",
81 "v",
82 "v",
83 "value",
84 "v",
85 "value",
86 "value",
87 "value"
88 };
89
90 CxProperties prop;
91 cxPropertiesInitDefault(&prop);
92 enum cx_properties_status result;
93 cxstring key;
94 cxstring value;
95 CX_TEST_DO {
96 for (int i = 0; i < 10; i++) {
97 cxPropertiesInput(&prop, tests[i], strlen(tests[i]));
98 CX_TEST_ASSERT(prop.text == tests[i]);
99 CX_TEST_ASSERT(prop.text_size == strlen(tests[i]));
100 CX_TEST_ASSERT(prop.text_pos == 0);
101
102 result = cxPropertiesNext(&prop, &key, &value);
103 cxstring k = cx_str(keys[i]);
104 cxstring v = cx_str(values[i]);
105 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
106 CX_TEST_ASSERT(0 == cx_strcmp(key, k));
107 CX_TEST_ASSERT(0 == cx_strcmp(value, v));
108
109 result = cxPropertiesNext(&prop, &key, &value);
110 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
111 }
112 }
113 cxPropertiesDestroy(&prop);
114 }
115
116 CX_TEST(test_cx_properties_next_multi) {
117 const char *keys[] = {
118 "a",
119 "b",
120 "c",
121 "uap",
122 "name",
123 "key1",
124 "key2",
125 "key3"
126 };
127
128 const char *values[] = {
129 "a value",
130 "b value",
131 "core",
132 "core",
133 "ucx",
134 "value1",
135 "value2",
136 "value3"
137 };
138
139 const char *str = "#\n"
140 "# properties\n"
141 "# contains key/value pairs\n"
142 "#\n"
143 "a = a value\n"
144 "b = b value\n"
145 "c = core\n"
146 "\n# test\n"
147 "uap = core\n"
148 "name = ucx\n"
149 "# no = property\n"
150 "key1 = value1\n"
151 "#key1 = wrong value\n"
152 "#key2 = not value 2\n"
153 "key2 = value2\n"
154 "\n\n\n \n key3=value3\n";
155
156 CxProperties prop;
157 cxPropertiesInitDefault(&prop);
158 enum cx_properties_status result;
159 cxstring key;
160 cxstring value;
161
162 CX_TEST_DO {
163 result = cxPropertiesNext(&prop, &key, &value);
164 CX_TEST_ASSERT(result == CX_PROPERTIES_NULL_INPUT);
165 cxPropertiesInput(&prop, str, strlen(str));
166 for (int i = 0; i < 8; i++) {
167 result = cxPropertiesNext(&prop, &key, &value);
168 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
169 CX_TEST_ASSERT(!cx_strcmp(key, cx_str(keys[i])));
170 CX_TEST_ASSERT(!cx_strcmp(value, cx_str(values[i])));
171 }
172 result = cxPropertiesNext(&prop, &key, &value);
173 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
174 }
175 cxPropertiesDestroy(&prop);
176 }
177
178 CX_TEST(test_cx_properties_next_part) {
179 CxProperties prop;
180 cxPropertiesInitDefault(&prop);
181 enum cx_properties_status result;
182 cxstring key;
183 cxstring value;
184 const char *str;
185
186 CX_TEST_DO {
187 str = "";
188 cxPropertiesFill(&prop, str, strlen(str));
189 result = cxPropertiesNext(&prop, &key, &value);
190 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
191
192 str = " \n";
193 cxPropertiesFill(&prop, str, strlen(str));
194 result = cxPropertiesNext(&prop, &key, &value);
195 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
196
197 str = "name";
198 cxPropertiesFill(&prop, str, strlen(str));
199 result = cxPropertiesNext(&prop, &key, &value);
200 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
201
202 str = " ";
203 cxPropertiesFill(&prop, str, strlen(str));
204 result = cxPropertiesNext(&prop, &key, &value);
205 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
206
207 // call fill twice in a row
208 str = "= ";
209 cxPropertiesFill(&prop, str, strlen(str));
210 str = "value";
211 cxPropertiesFill(&prop, str, strlen(str));
212 result = cxPropertiesNext(&prop, &key, &value);
213 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
214
215 str = "\n";
216 cxPropertiesFill(&prop, str, strlen(str));
217 result = cxPropertiesNext(&prop, &key, &value);
218 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
219 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("name")));
220 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value")));
221
222 // second round
223 str = "#comment\n";
224 cxPropertiesFill(&prop, str, strlen(str));
225 result = cxPropertiesNext(&prop, &key, &value);
226 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
227
228 str = "#comment\nname2 = ";
229 cxPropertiesFill(&prop, str, strlen(str));
230 result = cxPropertiesNext(&prop, &key, &value);
231 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
232
233 str = "value2\na = b\n";
234 cxPropertiesFill(&prop, str, strlen(str));
235 result = cxPropertiesNext(&prop, &key, &value);
236 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
237 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("name2")));
238 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value2")));
239
240 result = cxPropertiesNext(&prop, &key, &value);
241 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
242 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("a")));
243 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("b")));
244
245 str = "# comment\n#\n#\ntests = ";
246 cxPropertiesFill(&prop, str, strlen(str));
247 result = cxPropertiesNext(&prop, &key, &value);
248 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
249
250 str = "test1 ";
251 cxPropertiesFill(&prop, str, strlen(str));
252 result = cxPropertiesNext(&prop, &key, &value);
253 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
254
255 str = "test2 test3 test4\n";
256 cxPropertiesFill(&prop, str, strlen(str));
257 result = cxPropertiesNext(&prop, &key, &value);
258 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
259 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("tests")));
260 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("test1 test2 test3 test4")));
261
262 // test if cxPropertiesNext finds a name/value after a comment
263 str = "# just a comment";
264 cxPropertiesFill(&prop, str, strlen(str));
265 result = cxPropertiesNext(&prop, &key, &value);
266 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
267
268 str = " in 3";
269 cxPropertiesFill(&prop, str, strlen(str));
270 result = cxPropertiesNext(&prop, &key, &value);
271 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
272
273 str = " parts\nx = 1\n";
274 cxPropertiesFill(&prop, str, strlen(str));
275 result = cxPropertiesNext(&prop, &key, &value);
276 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
277 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("x")));
278 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("1")));
279
280 // finally we are done
281 result = cxPropertiesNext(&prop, &key, &value);
282 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
283 }
284 cxPropertiesDestroy(&prop);
285 }
286
287 CX_TEST(test_ucx_properties_next_long_lines) {
288 CxProperties prop;
289 cxPropertiesInitDefault(&prop);
290 enum cx_properties_status result;
291 cxstring key;
292 cxstring value;
293
294 size_t key_len = 512;
295 char *long_key = (char*)malloc(key_len);
296 memset(long_key, 'a', 70);
297 memset(long_key + 70, 'b', 242);
298 memset(long_key + 312, 'c', 200);
299
300 size_t value_len = 2048;
301 char *long_value = (char*)malloc(value_len);
302 memset(long_value, 'x', 1024);
303 memset(long_value+1024, 'y', 1024);
304
305 CX_TEST_DO {
306 cxPropertiesFill(&prop, long_key, 10);
307 result = cxPropertiesNext(&prop, &key, &value);
308 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
309
310 cxPropertiesFill(&prop, long_key + 10, 202);
311 result = cxPropertiesNext(&prop, &key, &value);
312 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
313
314 cxPropertiesFill(&prop, long_key + 212, 200);
315 result = cxPropertiesNext(&prop, &key, &value);
316 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
317
318 cxPropertiesFill(&prop, long_key + 412, 100);
319 result = cxPropertiesNext(&prop, &key, &value);
320 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
321
322 const char *str = " = ";
323 cxPropertiesFill(&prop, str, strlen(str));
324 result = cxPropertiesNext(&prop, &key, &value);
325 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
326
327 cxPropertiesFill(&prop, long_value, 512);
328 result = cxPropertiesNext(&prop, &key, &value);
329 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
330
331 cxPropertiesFill(&prop, long_value + 512, 1024);
332 result = cxPropertiesNext(&prop, &key, &value);
333 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
334
335 cxPropertiesFill(&prop, long_value + 1536, 512);
336 result = cxPropertiesNext(&prop, &key, &value);
337 CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA);
338
339 str = "\n#comment\nkey = value\n";
340 cxPropertiesFill(&prop, str, strlen(str));
341 result = cxPropertiesNext(&prop, &key, &value);
342 cxstring k = cx_strn(long_key, key_len);
343 cxstring v = cx_strn(long_value, value_len);
344 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
345 CX_TEST_ASSERT(0 == cx_strcmp(key, k));
346 CX_TEST_ASSERT(0 == cx_strcmp(value, v));
347
348 result = cxPropertiesNext(&prop, &key, &value);
349 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR);
350 CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key")));
351 CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value")));
352
353 result = cxPropertiesNext(&prop, &key, &value);
354 CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA);
355
356 CX_TEST_ASSERT(prop.buf != NULL);
357 CX_TEST_ASSERT(prop.buf_capacity > 0);
358 CX_TEST_ASSERT(prop.buf_size == 0);
359 cxPropertiesDestroy(&prop);
360
361 CX_TEST_ASSERT(prop.buf == NULL);
362 CX_TEST_ASSERT(prop.buf_capacity == 0);
363 CX_TEST_ASSERT(prop.buf_size == 0);
364 }
365
366 free(long_key);
367 free(long_value);
368 }
369
370 CxTestSuite *cx_test_suite_properties(void) {
371 CxTestSuite *suite = cx_test_suite_new("properties");
372
373 cx_test_register(suite, test_cx_properties_init);
374 cx_test_register(suite, test_cx_properties_next);
375 cx_test_register(suite, test_cx_properties_next_multi);
376 cx_test_register(suite, test_cx_properties_next_part);
377 cx_test_register(suite, test_ucx_properties_next_long_lines);
378
379 return suite;
380 }

mercurial