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