1 #include <stdio.h>
2 #include <string.h>
3 #include "lib/minunit.h"
4 #include "lib/mlr_globals.h"
5 #include "lib/mlrutil.h"
6 #include "containers/lrec.h"
7 #include "containers/sllv.h"
8 #include "input/lrec_readers.h"
9
10 int tests_run = 0;
11 int tests_failed = 0;
12 int assertions_run = 0;
13 int assertions_failed = 0;
14
15 // ----------------------------------------------------------------
test_lrec_unbacked_api()16 static char* test_lrec_unbacked_api() {
17 lrec_t* prec = lrec_unbacked_alloc();
18 mu_assert_lf(prec->field_count == 0);
19
20 lrec_put(prec, "x", "3", NO_FREE);
21 mu_assert_lf(prec->field_count == 1);
22 mu_assert_lf(streq(lrec_get(prec, "x"), "3"));
23
24 lrec_put(prec, "y", "4", NO_FREE);
25 mu_assert_lf(prec->field_count == 2);
26 mu_assert_lf(streq(lrec_get(prec, "x"), "3"));
27 mu_assert_lf(streq(lrec_get(prec, "y"), "4"));
28
29 lrec_put(prec, "x", "5", NO_FREE);
30 mu_assert_lf(prec->field_count == 2);
31 mu_assert_lf(streq(lrec_get(prec, "x"), "5"));
32 mu_assert_lf(streq(lrec_get(prec, "y"), "4"));
33
34 lrec_remove(prec, "x");
35 mu_assert_lf(prec->field_count == 1);
36 mu_assert_lf(lrec_get(prec, "x") == NULL);
37
38 // Non-replacing-rename case
39 //lrec_dump_titled("Before rename", prec);
40 lrec_rename(prec, "y", "z", FALSE);
41 //lrec_dump_titled("After rename", prec);
42 mu_assert_lf(prec->field_count == 1);
43 mu_assert_lf(lrec_get(prec, "x") == NULL);
44 mu_assert_lf(lrec_get(prec, "y") == NULL);
45 mu_assert_lf(streq(lrec_get(prec, "z"), "4"));
46
47 lrec_free(prec);
48
49 // Replacing-rename case
50 prec = lrec_unbacked_alloc();
51
52 lrec_put(prec, "x", "3", NO_FREE);
53 lrec_put(prec, "y", "4", NO_FREE);
54 lrec_put(prec, "z", "5", NO_FREE);
55 mu_assert_lf(prec->field_count == 3);
56
57 //lrec_dump_titled("Before rename", prec);
58 lrec_rename(prec, "y", "z", FALSE);
59 //lrec_dump_titled("After rename", prec);
60
61 mu_assert_lf(prec->field_count == 2);
62 mu_assert_lf(streq(lrec_get(prec, "x"), "3"));
63 mu_assert_lf(lrec_get(prec, "y") == NULL);
64 mu_assert_lf(streq(lrec_get(prec, "z"), "4"));
65
66 lrec_free(prec);
67
68 return NULL;
69 }
70
71 // ----------------------------------------------------------------
test_lrec_dkvp_api()72 static char* test_lrec_dkvp_api() {
73 char* line = mlr_strdup_or_die("w=2,x=3,y=4,z=5");
74
75 lrec_t* prec = lrec_parse_stdio_dkvp_single_sep(line, ',', '=', FALSE);
76 mu_assert_lf(prec->field_count == 4);
77
78 mu_assert_lf(streq(lrec_get(prec, "w"), "2"));
79 mu_assert_lf(streq(lrec_get(prec, "x"), "3"));
80 mu_assert_lf(streq(lrec_get(prec, "y"), "4"));
81 mu_assert_lf(streq(lrec_get(prec, "z"), "5"));
82
83 lrec_remove(prec, "w");
84 mu_assert_lf(prec->field_count == 3);
85 mu_assert_lf(lrec_get(prec, "w") == NULL);
86
87 // Non-replacing-rename case
88 //lrec_dump_titled("Before rename", prec);
89 lrec_rename(prec, "x", "u", FALSE);
90 //lrec_dump_titled("After rename", prec);
91 mu_assert_lf(prec->field_count == 3);
92 mu_assert_lf(lrec_get(prec, "x") == NULL);
93 mu_assert_lf(streq(lrec_get(prec, "u"), "3"));
94
95 // Replacing-rename case
96 //lrec_dump_titled("Before rename", prec);
97 lrec_rename(prec, "y", "z", FALSE);
98 //lrec_dump_titled("After rename", prec);
99
100 mu_assert_lf(prec->field_count == 2);
101 mu_assert_lf(streq(lrec_get(prec, "u"), "3"));
102 mu_assert_lf(lrec_get(prec, "y") == NULL);
103 mu_assert_lf(streq(lrec_get(prec, "z"), "4"));
104
105 lrec_free(prec);
106
107 return NULL;
108 }
109
110 // ----------------------------------------------------------------
test_lrec_nidx_api()111 static char* test_lrec_nidx_api() {
112 char* line = mlr_strdup_or_die("a,b,c,d");
113 lrec_t* prec = lrec_parse_stdio_nidx_single_sep(line, ',', FALSE);
114 mu_assert_lf(prec->field_count == 4);
115
116 mu_assert_lf(streq(lrec_get(prec, "1"), "a"));
117 mu_assert_lf(streq(lrec_get(prec, "2"), "b"));
118 mu_assert_lf(streq(lrec_get(prec, "3"), "c"));
119 mu_assert_lf(streq(lrec_get(prec, "4"), "d"));
120
121 lrec_remove(prec, "1");
122 mu_assert_lf(prec->field_count == 3);
123 mu_assert_lf(lrec_get(prec, "1") == NULL);
124
125 // Non-replacing-rename case
126 lrec_dump_titled("Before rename", prec);
127 lrec_rename(prec, "2", "u", FALSE);
128 lrec_dump_titled("After rename", prec);
129 mu_assert_lf(prec->field_count == 3);
130 mu_assert_lf(lrec_get(prec, "2") == NULL);
131 mu_assert_lf(streq(lrec_get(prec, "u"), "b"));
132
133 // Replacing-rename case
134 lrec_dump_titled("Before rename", prec);
135 lrec_rename(prec, "3", "4", FALSE);
136 lrec_dump_titled("After rename", prec);
137
138 mu_assert_lf(prec->field_count == 2);
139 mu_assert_lf(streq(lrec_get(prec, "u"), "b"));
140 mu_assert_lf(lrec_get(prec, "3") == NULL);
141 mu_assert_lf(streq(lrec_get(prec, "4"), "c"));
142
143 lrec_free(prec);
144
145 return NULL;
146 }
147
148 // ----------------------------------------------------------------
test_lrec_csv_api()149 static char* test_lrec_csv_api() {
150 char* hdr_line = mlr_strdup_or_die("w,x,y,z");
151 slls_t* hdr_fields = split_csvlite_header_line_single_ifs(hdr_line, ',', FALSE);
152 header_keeper_t* pheader_keeper = header_keeper_alloc(hdr_line, hdr_fields);
153
154 char* data_line_1 = mlr_strdup_or_die("2,3,4,5");
155 lrec_t* prec_1 = lrec_parse_stdio_csvlite_data_line_single_ifs(pheader_keeper, "test-file", 999,
156 data_line_1, ',', FALSE, FALSE);
157
158 char* data_line_2 = mlr_strdup_or_die("6,7,8,9");
159 lrec_t* prec_2 = lrec_parse_stdio_csvlite_data_line_single_ifs(pheader_keeper, "test-file", 999,
160 data_line_2, ',', FALSE, FALSE);
161
162 mu_assert_lf(prec_1->field_count == 4);
163 mu_assert_lf(prec_2->field_count == 4);
164
165 mu_assert_lf(streq(lrec_get(prec_1, "w"), "2"));
166 mu_assert_lf(streq(lrec_get(prec_1, "x"), "3"));
167 mu_assert_lf(streq(lrec_get(prec_1, "y"), "4"));
168 mu_assert_lf(streq(lrec_get(prec_1, "z"), "5"));
169
170 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
171 mu_assert_lf(streq(lrec_get(prec_2, "x"), "7"));
172 mu_assert_lf(streq(lrec_get(prec_2, "y"), "8"));
173 mu_assert_lf(streq(lrec_get(prec_2, "z"), "9"));
174
175 lrec_remove(prec_1, "w");
176 mu_assert_lf(prec_1->field_count == 3);
177 mu_assert_lf(prec_2->field_count == 4);
178 mu_assert_lf(lrec_get(prec_1, "w") == NULL);
179 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
180
181 // Non-replacing-rename case
182 //lrec_dump_titled("Before rename", prec_1);
183 lrec_rename(prec_1, "x", "u", FALSE);
184 //lrec_dump_titled("After rename", prec_1);
185 mu_assert_lf(prec_1->field_count == 3);
186 mu_assert_lf(lrec_get(prec_1, "x") == NULL);
187 mu_assert_lf(streq(lrec_get(prec_1, "u"), "3"));
188
189 // Replacing-rename case
190 //lrec_dump_titled("Before rename", prec_2);
191 lrec_rename(prec_2, "y", "z", FALSE);
192 //lrec_dump_titled("After rename", prec_2);
193
194 mu_assert_lf(prec_2->field_count == 3);
195 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
196 mu_assert_lf(streq(lrec_get(prec_2, "x"), "7"));
197 mu_assert_lf(lrec_get(prec_2, "y") == NULL);
198 mu_assert_lf(streq(lrec_get(prec_2, "z"), "8"));
199
200 lrec_free(prec_1);
201 lrec_free(prec_2);
202
203 return NULL;
204 }
205
206 // ----------------------------------------------------------------
test_lrec_csv_api_disjoint_allocs()207 static char* test_lrec_csv_api_disjoint_allocs() {
208 char* hdr_line = mlr_strdup_or_die("w,x,y,z");
209 slls_t* hdr_fields = split_csvlite_header_line_single_ifs(hdr_line, ',', FALSE);
210 header_keeper_t* pheader_keeper = header_keeper_alloc(hdr_line, hdr_fields);
211
212
213 char* data_line_1 = mlr_strdup_or_die("2,3,4,5");
214 lrec_t* prec_1 = lrec_parse_stdio_csvlite_data_line_single_ifs(pheader_keeper, "test-file", 999,
215 data_line_1, ',', FALSE, FALSE);
216
217 mu_assert_lf(prec_1->field_count == 4);
218
219 mu_assert_lf(streq(lrec_get(prec_1, "w"), "2"));
220 mu_assert_lf(streq(lrec_get(prec_1, "x"), "3"));
221 mu_assert_lf(streq(lrec_get(prec_1, "y"), "4"));
222 mu_assert_lf(streq(lrec_get(prec_1, "z"), "5"));
223
224 lrec_remove(prec_1, "w");
225 mu_assert_lf(prec_1->field_count == 3);
226 mu_assert_lf(lrec_get(prec_1, "w") == NULL);
227
228 lrec_rename(prec_1, "x", "u", FALSE);
229 mu_assert_lf(prec_1->field_count == 3);
230 mu_assert_lf(lrec_get(prec_1, "x") == NULL);
231 mu_assert_lf(streq(lrec_get(prec_1, "u"), "3"));
232
233 lrec_free(prec_1);
234
235
236 char* data_line_2 = mlr_strdup_or_die("6,7,8,9");
237 lrec_t* prec_2 = lrec_parse_stdio_csvlite_data_line_single_ifs(pheader_keeper, "test-file", 999,
238 data_line_2, ',', FALSE, FALSE);
239
240 mu_assert_lf(prec_2->field_count == 4);
241
242 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
243 mu_assert_lf(streq(lrec_get(prec_2, "x"), "7"));
244 mu_assert_lf(streq(lrec_get(prec_2, "y"), "8"));
245 mu_assert_lf(streq(lrec_get(prec_2, "z"), "9"));
246
247 mu_assert_lf(prec_2->field_count == 4);
248 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
249
250 lrec_rename(prec_2, "y", "z", FALSE);
251
252 mu_assert_lf(prec_2->field_count == 3);
253 mu_assert_lf(streq(lrec_get(prec_2, "w"), "6"));
254 mu_assert_lf(streq(lrec_get(prec_2, "x"), "7"));
255 mu_assert_lf(lrec_get(prec_2, "y") == NULL);
256 mu_assert_lf(streq(lrec_get(prec_2, "z"), "8"));
257
258 lrec_free(prec_2);
259
260 return NULL;
261 }
262
263 // ----------------------------------------------------------------
test_lrec_xtab_api()264 static char* test_lrec_xtab_api() {
265 char* line_1 = mlr_strdup_or_die("w 2");
266 char* line_2 = mlr_strdup_or_die("x 3");
267 char* line_3 = mlr_strdup_or_die("y 4");
268 char* line_4 = mlr_strdup_or_die("z 5");
269 slls_t* pxtab_lines = slls_alloc();
270 slls_append_with_free(pxtab_lines, line_1);
271 slls_append_with_free(pxtab_lines, line_2);
272 slls_append_with_free(pxtab_lines, line_3);
273 slls_append_with_free(pxtab_lines, line_4);
274
275 lrec_t* prec = lrec_parse_stdio_xtab_single_ips(pxtab_lines, ' ', TRUE);
276 mu_assert_lf(prec->field_count == 4);
277
278 mu_assert_lf(streq(lrec_get(prec, "w"), "2"));
279 mu_assert_lf(streq(lrec_get(prec, "x"), "3"));
280 mu_assert_lf(streq(lrec_get(prec, "y"), "4"));
281 mu_assert_lf(streq(lrec_get(prec, "z"), "5"));
282
283 lrec_remove(prec, "w");
284 mu_assert_lf(prec->field_count == 3);
285 mu_assert_lf(lrec_get(prec, "w") == NULL);
286
287 // Non-replacing-rename case
288 //lrec_dump_titled("Before rename", prec);
289 lrec_rename(prec, "x", "u", FALSE);
290 //lrec_dump_titled("After rename", prec);
291 mu_assert_lf(prec->field_count == 3);
292 mu_assert_lf(lrec_get(prec, "x") == NULL);
293 mu_assert_lf(streq(lrec_get(prec, "u"), "3"));
294
295 // Replacing-rename case
296 //lrec_dump_titled("Before rename", prec);
297 lrec_rename(prec, "y", "z", FALSE);
298 //lrec_dump_titled("After rename", prec);
299
300 mu_assert_lf(prec->field_count == 2);
301 mu_assert_lf(streq(lrec_get(prec, "u"), "3"));
302 mu_assert_lf(lrec_get(prec, "y") == NULL);
303 mu_assert_lf(streq(lrec_get(prec, "z"), "4"));
304
305 lrec_free(prec);
306
307 return NULL;
308 }
309
310 // ----------------------------------------------------------------
test_lrec_put_after()311 static char* test_lrec_put_after() {
312 printf("TEST_LREC_PUT_AFTER ENTER\n");
313
314 lrec_t* prec = lrec_literal_1("a", "1");
315 lrece_t* pe = NULL;
316
317 printf("BEFORE: "); lrec_print(prec);
318 mu_assert_lf(prec->field_count == 1);
319 char* value = lrec_get_ext(prec, "nosuch", &pe);
320 mu_assert_lf(value == NULL);
321 mu_assert_lf(pe == NULL);
322
323 value = lrec_get_ext(prec, "a", &pe);
324 mu_assert_lf(value != NULL);
325 mu_assert_lf(pe != NULL);
326 mu_assert_lf(streq(value, "1"));
327 lrec_put_after(prec, pe, "a", "2", NO_FREE);
328 printf("AFTER : "); lrec_print(prec);
329 mu_assert_lf(prec->field_count == 1);
330 value = lrec_get_ext(prec, "a", &pe);
331 mu_assert_lf(value != NULL);
332 mu_assert_lf(pe != NULL);
333 mu_assert_lf(streq(value, "2"));
334 lrec_free(prec);
335
336 prec = lrec_literal_1("a", "1");
337 printf("BEFORE: "); lrec_print(prec);
338 value = lrec_get_ext(prec, "a", &pe);
339 mu_assert_lf(pe != NULL);
340 mu_assert_lf(streq(value, "1"));
341
342 lrec_put_after(prec, pe, "b", "3", NO_FREE);
343 printf("AFTER : "); lrec_print(prec);
344 mu_assert_lf(prec->field_count == 2);
345 value = lrec_get(prec, "a");
346 mu_assert_lf(value != NULL);
347 mu_assert_lf(streq(value, "1"));
348 value = lrec_get(prec, "b");
349 mu_assert_lf(value != NULL);
350 mu_assert_lf(streq(value, "3"));
351 mu_assert_lf(streq(prec->phead->key, "a"));
352 mu_assert_lf(streq(prec->phead->pnext->key, "b"));
353 mu_assert_lf(streq(prec->phead->value, "1"));
354 mu_assert_lf(streq(prec->phead->pnext->value, "3"));
355 mu_assert_lf(prec->phead->pnext->pnext == NULL);
356 lrec_free(prec);
357
358
359 prec = lrec_literal_2("a", "1", "b", "2");
360 printf("BEFORE: "); lrec_print(prec);
361 mu_assert_lf(prec->field_count == 2);
362 value = lrec_get_ext(prec, "a", &pe);
363 mu_assert_lf(value != NULL);
364 mu_assert_lf(pe != NULL);
365 mu_assert_lf(streq(value, "1"));
366
367 lrec_put_after(prec, pe, "z", "9", NO_FREE);
368 printf("AFTER : "); lrec_print(prec);
369 mu_assert_lf(prec->field_count == 3);
370 mu_assert_lf(streq(prec->phead->key, "a"));
371 mu_assert_lf(streq(prec->phead->pnext->key, "z"));
372 mu_assert_lf(streq(prec->phead->pnext->pnext->key, "b"));
373 mu_assert_lf(streq(prec->phead->value, "1"));
374 mu_assert_lf(streq(prec->phead->pnext->value, "9"));
375 mu_assert_lf(streq(prec->phead->pnext->pnext->value, "2"));
376 mu_assert_lf(prec->phead->pnext->pnext->pnext == NULL);
377 lrec_free(prec);
378
379
380 prec = lrec_literal_2("a", "1", "b", "2");
381 printf("BEFORE: "); lrec_print(prec);
382 mu_assert_lf(prec->field_count == 2);
383 value = lrec_get_ext(prec, "b", &pe);
384 mu_assert_lf(value != NULL);
385 mu_assert_lf(pe != NULL);
386 mu_assert_lf(streq(value, "2"));
387
388 lrec_put_after(prec, pe, "z", "9", NO_FREE);
389 printf("AFTER : "); lrec_print(prec);
390 mu_assert_lf(prec->field_count == 3);
391 mu_assert_lf(streq(prec->phead->key, "a"));
392 mu_assert_lf(streq(prec->phead->pnext->key, "b"));
393 mu_assert_lf(streq(prec->phead->pnext->pnext->key, "z"));
394 mu_assert_lf(streq(prec->phead->value, "1"));
395 mu_assert_lf(streq(prec->phead->pnext->value, "2"));
396 mu_assert_lf(streq(prec->phead->pnext->pnext->value, "9"));
397 mu_assert_lf(prec->phead->pnext->pnext->pnext == NULL);
398 lrec_free(prec);
399
400 printf("TEST_LREC_PUT_AFTER EXIT\n");
401 return NULL;
402 }
403
404 // ================================================================
run_all_tests()405 static char * run_all_tests() {
406 mu_run_test(test_lrec_unbacked_api);
407 mu_run_test(test_lrec_dkvp_api);
408 mu_run_test(test_lrec_nidx_api);
409 mu_run_test(test_lrec_csv_api);
410 mu_run_test(test_lrec_csv_api_disjoint_allocs);
411 mu_run_test(test_lrec_xtab_api);
412 mu_run_test(test_lrec_put_after);
413 return 0;
414 }
415
main(int argc,char ** argv)416 int main(int argc, char **argv) {
417 mlr_global_init(argv[0], NULL);
418 printf("TEST_LREC ENTER\n");
419 char *result = run_all_tests();
420 printf("\n");
421 if (result != 0) {
422 printf("Not all unit tests passed\n");
423 }
424 else {
425 printf("TEST_LREC: ALL UNIT TESTS PASSED\n");
426 }
427 printf("Tests passed: %d of %d\n", tests_run - tests_failed, tests_run);
428 printf("Assertions passed: %d of %d\n", assertions_run - assertions_failed, assertions_run);
429
430 return result != 0;
431 }
432