coverage and test: Add tests
[src/app-framework-binder.git] / src / tests / wrap-json / test-wrap-json.c
1 /*
2  Copyright (C) 2016, 2017, 2018 "IoT.bzh"
3
4  author: José Bollo <jose.bollo@iot.bzh>
5
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 #include <string.h>
20 #include <limits.h>
21 #include <stdio.h>
22
23 #include "wrap-json.h"
24
25
26 void tclone(struct json_object *object)
27 {
28         struct json_object *o;
29
30         o = wrap_json_clone(object);
31         if (!wrap_json_equal(object, o))
32                 printf("ERROR in clone or equal: %s VERSUS %s\n", json_object_to_json_string(object), json_object_to_json_string(o));
33         json_object_put(o);
34
35         o = wrap_json_clone_deep(object);
36         if (!wrap_json_equal(object, o))
37                 printf("ERROR in clone_deep or equal: %s VERSUS %s\n", json_object_to_json_string(object), json_object_to_json_string(o));
38         json_object_put(o);
39 }
40
41 void p(const char *desc, ...)
42 {
43         int rc;
44         va_list args;
45         struct json_object *result;
46
47         va_start(args, desc);
48         rc = wrap_json_vpack(&result, desc, args);
49         va_end(args);
50         if (!rc)
51                 printf("  SUCCESS %s\n\n", json_object_to_json_string(result));
52         else
53                 printf("  ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
54         tclone(result);
55         json_object_put(result);
56 }
57
58 const char *xs[10];
59 int *xi[10];
60 int64_t *xI[10];
61 double *xf[10];
62 struct json_object *xo[10];
63 size_t xz[10];
64 uint8_t *xy[10];
65
66 void u(const char *value, const char *desc, ...)
67 {
68         unsigned m, k;
69         int rc;
70         va_list args;
71         struct json_object *object, *o;
72
73         memset(xs, 0, sizeof xs);
74         memset(xi, 0, sizeof xi);
75         memset(xI, 0, sizeof xI);
76         memset(xf, 0, sizeof xf);
77         memset(xo, 0, sizeof xo);
78         memset(xy, 0, sizeof xy);
79         memset(xz, 0, sizeof xz);
80         object = json_tokener_parse(value);
81         va_start(args, desc);
82         rc = wrap_json_vunpack(object, desc, args);
83         va_end(args);
84         if (rc)
85                 printf("  ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
86         else {
87                 value = NULL;
88                 printf("  SUCCESS");
89                 va_start(args, desc);
90                 k = m = 0;
91                 while(*desc) {
92                         switch(*desc) {
93                         case '{': m = (m << 1) | 1; k = 1; break;
94                         case '}': m = m >> 1; k = m&1; break;
95                         case '[': m = m << 1; k = 0; break;
96                         case ']': m = m >> 1; k = m&1; break;
97                         case 's': printf(" s:%s", k ? va_arg(args, const char*) : *(va_arg(args, const char**)?:&value)); k ^= m&1; break;
98                         case '%': printf(" %%:%zu", *va_arg(args, size_t*)); k = m&1; break;
99                         case 'n': printf(" n"); k = m&1; break;
100                         case 'b': printf(" b:%d", *va_arg(args, int*)); k = m&1; break;
101                         case 'i': printf(" i:%d", *va_arg(args, int*)); k = m&1; break;
102                         case 'I': printf(" I:%lld", *va_arg(args, int64_t*)); k = m&1; break;
103                         case 'f': printf(" f:%f", *va_arg(args, double*)); k = m&1; break;
104                         case 'F': printf(" F:%f", *va_arg(args, double*)); k = m&1; break;
105                         case 'o': printf(" o:%s", json_object_to_json_string(*va_arg(args, struct json_object**))); k = m&1; break;
106                         case 'O': o = *va_arg(args, struct json_object**); printf(" O:%s", json_object_to_json_string(o)); json_object_put(o); k = m&1; break;
107                         case 'y':
108                         case 'Y': {
109                                 uint8_t *p = *va_arg(args, uint8_t**);
110                                 size_t s = *va_arg(args, size_t*);
111                                 printf(" y/%d:%.*s", (int)s, (int)s, (char*)p);
112                                 k ^= m&1;
113                                 break;
114                                 }
115                         default: break;
116                         }
117                         desc++;
118                 }
119                 va_end(args);
120                 printf("\n\n");
121         }
122         tclone(object);
123         json_object_put(object);
124 }
125
126 void c(const char *sx, const char *sy, int e, int c)
127 {
128         int re, rc;
129         struct json_object *jx, *jy;
130
131         jx = json_tokener_parse(sx);
132         jy = json_tokener_parse(sy);
133
134         re = wrap_json_cmp(jx, jy);
135         rc = wrap_json_contains(jx, jy);
136
137         printf("compare(%s)(%s)\n", sx, sy);
138         printf("   -> %d / %d\n", re, rc);
139
140         if (!re != !!e)
141                 printf("  ERROR should be %s\n", e ? "equal" : "different");
142         if (!rc != !c)
143                 printf("  ERROR should %scontain\n", c ? "" : "not ");
144
145         printf("\n");
146 }
147
148 #define P(...) do{ printf("pack(%s)\n",#__VA_ARGS__); p(__VA_ARGS__); } while(0)
149 #define U(...) do{ printf("unpack(%s)\n",#__VA_ARGS__); u(__VA_ARGS__); } while(0)
150
151 int main()
152 {
153         char buffer[4] = {'t', 'e', 's', 't'};
154
155         P("n");
156         P("b", 1);
157         P("b", 0);
158         P("i", 1);
159         P("I", (uint64_t)0x123456789abcdef);
160         P("f", 3.14);
161         P("s", "test");
162         P("s?", "test");
163         P("s?", NULL);
164         P("s#", "test asdf", 4);
165         P("s%", "test asdf", (size_t)4);
166         P("s#", buffer, 4);
167         P("s%", buffer, (size_t)4);
168         P("s++", "te", "st", "ing");
169         P("s#+#+", "test", 1, "test", 2, "test");
170         P("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
171         P("{}", 1.0);
172         P("[]", 1.0);
173         P("o", json_object_new_int(1));
174         P("o?", json_object_new_int(1));
175         P("o?", NULL);
176         P("O", json_object_new_int(1));
177         P("O?", json_object_new_int(1));
178         P("O?", NULL);
179         P("{s:[]}", "foo");
180         P("{s+#+: []}", "foo", "barbar", 3, "baz");
181         P("{s:s,s:o,s:O}", "a", NULL, "b", NULL, "c", NULL);
182         P("{s:**}", "a", NULL);
183         P("{s:s*,s:o*,s:O*}", "a", NULL, "b", NULL, "c", NULL);
184         P("[i,i,i]", 0, 1, 2);
185         P("[s,o,O]", NULL, NULL, NULL);
186         P("[**]", NULL);
187         P("[s*,o*,O*]", NULL, NULL, NULL);
188         P(" s ", "test");
189         P("[ ]");
190         P("[ i , i,  i ] ", 1, 2, 3);
191         P("{\n\n1");
192         P("[}");
193         P("{]");
194         P("[");
195         P("{");
196         P("[i]a", 42);
197         P("ia", 42);
198         P("s", NULL);
199         P("+", NULL);
200         P(NULL);
201         P("{s:i}", NULL, 1);
202         P("{ {}: s }", "foo");
203         P("{ s: {},  s:[ii{} }", "foo", "bar", 12, 13);
204         P("[[[[[   [[[[[  [[[[ }]]]] ]]]] ]]]]]");
205         P("y", "???????hello>>>>>>>", (size_t)19);
206         P("Y", "???????hello>>>>>>>", (size_t)19);
207         P("{sy?}", "foo", "hi", (size_t)2);
208         P("{sy?}", "foo", NULL, 0);
209         P("{sy*}", "foo", "hi", (size_t)2);
210         P("{sy*}", "foo", NULL, 0);
211
212         U("true", "b", &xi[0]);
213         U("false", "b", &xi[0]);
214         U("null", "n");
215         U("42", "i", &xi[0]);
216         U("123456789", "I", &xI[0]);
217         U("3.14", "f", &xf[0]);
218         U("12345", "F", &xf[0]);
219         U("3.14", "F", &xf[0]);
220         U("\"foo\"", "s", &xs[0]);
221         U("\"foo\"", "s%", &xs[0], &xz[0]);
222         U("{}", "{}");
223         U("[]", "[]");
224         U("{}", "o", &xo[0]);
225         U("{}", "O", &xo[0]);
226         U("{\"foo\":42}", "{si}", "foo", &xi[0]);
227         U("[1,2,3]", "[i,i,i]", &xi[0], &xi[1], &xi[2]);
228         U("{\"a\":1,\"b\":2,\"c\":3}", "{s:i, s:i, s:i}", "a", &xi[0], "b", &xi[1], "c", &xi[2]);
229         U("42", "z");
230         U("null", "[i]");
231         U("[]", "[}");
232         U("{}", "{]");
233         U("[]", "[");
234         U("{}", "{");
235         U("[42]", "[i]a", &xi[0]);
236         U("42", "ia", &xi[0]);
237         U("[]", NULL);
238         U("\"foo\"", "s", NULL);
239         U("42", "s", NULL);
240         U("42", "n");
241         U("42", "b", NULL);
242         U("42", "f", NULL);
243         U("42", "[i]", NULL);
244         U("42", "{si}", "foo", NULL);
245         U("\"foo\"", "n");
246         U("\"foo\"", "b", NULL);
247         U("\"foo\"", "i", NULL);
248         U("\"foo\"", "I", NULL);
249         U("\"foo\"", "f", NULL);
250         U("\"foo\"", "F", NULL);
251         U("true", "s", NULL);
252         U("true", "n");
253         U("true", "i", NULL);
254         U("true", "I", NULL);
255         U("true", "f", NULL);
256         U("true", "F", NULL);
257         U("[42]", "[ii]", &xi[0], &xi[1]);
258         U("{\"foo\":42}", "{si}", NULL, &xi[0]);
259         U("{\"foo\":42}", "{si}", "baz", &xi[0]);
260         U("[1,2,3]", "[iii!]", &xi[0], &xi[1], &xi[2]);
261         U("[1,2,3]", "[ii!]", &xi[0], &xi[1]);
262         U("[1,2,3]", "[ii]", &xi[0], &xi[1]);
263         U("[1,2,3]", "[ii*]", &xi[0], &xi[1]);
264         U("{\"foo\":42,\"baz\":45}", "{sisi}", "baz", &xi[0], "foo", &xi[1]);
265         U("{\"foo\":42,\"baz\":45}", "{sisi*}", "baz", &xi[0], "foo", &xi[1]);
266         U("{\"foo\":42,\"baz\":45}", "{sisi!}", "baz", &xi[0], "foo", &xi[1]);
267         U("{\"foo\":42,\"baz\":45}", "{si}", "baz", &xi[0], "foo", &xi[1]);
268         U("{\"foo\":42,\"baz\":45}", "{si*}", "baz", &xi[0], "foo", &xi[1]);
269         U("{\"foo\":42,\"baz\":45}", "{si!}", "baz", &xi[0], "foo", &xi[1]);
270         U("[1,{\"foo\":2,\"bar\":null},[3,4]]", "[i{sisn}[ii]]", &xi[0], "foo", &xi[1], "bar", &xi[2], &xi[3]);
271         U("[1,2,3]", "[ii!i]", &xi[0], &xi[1], &xi[2]);
272         U("[1,2,3]", "[ii*i]", &xi[0], &xi[1], &xi[2]);
273         U("{\"foo\":1,\"bar\":2}", "{si!si}", "foo", &xi[1], "bar", &xi[2]);
274         U("{\"foo\":1,\"bar\":2}", "{si*si}", "foo", &xi[1], "bar", &xi[2]);
275         U("{\"foo\":{\"baz\":null,\"bar\":null}}", "{s{sn!}}", "foo", "bar");
276         U("[[1,2,3]]", "[[ii!]]", &xi[0], &xi[1]);
277         U("{}", "{s?i}", "foo", &xi[0]);
278         U("{\"foo\":1}", "{s?i}", "foo", &xi[0]);
279         U("{}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
280         U("{\"foo\":[1,2]}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
281         U("{\"bar\":{\"baz\":{\"quux\":15}}}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
282         U("{\"foo\":{\"bar\":4}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
283         U("{\"foo\":{}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
284         U("{}", "{s?{s?i}}", "foo", "bar", &xi[0]);
285         U("{\"foo\":42,\"baz\":45}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
286         U("{\"foo\":42}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
287
288         U("\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"", "y", &xy[0], &xz[0]);
289         U("\"\"", "y", &xy[0], &xz[0]);
290         U("null", "y", &xy[0], &xz[0]);
291         U("{\"foo\":\"Pz8_Pz8_P2hlbGxvPj4-Pj4-Pg\"}", "{s?y}", "foo", &xy[0], &xz[0]);
292         U("{\"foo\":\"\"}", "{s?y}", "foo", &xy[0], &xz[0]);
293         U("{}", "{s?y}", "foo", &xy[0], &xz[0]);
294
295         c("null", "null", 1, 1);
296         c("true", "true", 1, 1);
297         c("false", "false", 1, 1);
298         c("1", "1", 1, 1);
299         c("1.0", "1.0", 1, 1);
300         c("\"\"", "\"\"", 1, 1);
301         c("\"hi\"", "\"hi\"", 1, 1);
302         c("{}", "{}", 1, 1);
303         c("{\"a\":true,\"b\":false}", "{\"b\":false,\"a\":true}", 1, 1);
304         c("[]", "[]", 1, 1);
305         c("[1,true,null]", "[1,true,null]", 1, 1);
306
307         c("null", "true", 0, 0);
308         c("null", "false", 0, 0);
309         c("0", "1", 0, 0);
310         c("1", "0", 0, 0);
311         c("0", "true", 0, 0);
312         c("0", "false", 0, 0);
313         c("0", "null", 0, 0);
314
315         c("\"hi\"", "\"hello\"", 0, 0);
316         c("\"hello\"", "\"hi\"", 0, 0);
317
318         c("{}", "null", 0, 0);
319         c("{}", "true", 0, 0);
320         c("{}", "1", 0, 0);
321         c("{}", "1.0", 0, 0);
322         c("{}", "[]", 0, 0);
323         c("{}", "\"x\"", 0, 0);
324
325         c("[1,true,null]", "[1,true]", 0, 1);
326         c("{\"a\":true,\"b\":false}", "{\"a\":true}", 0, 1);
327         c("{\"a\":true,\"b\":false}", "{\"a\":true,\"c\":false}", 0, 0);
328         c("{\"a\":true,\"c\":false}", "{\"a\":true,\"b\":false}", 0, 0);
329         return 0;
330 }
331