1 /***********************************************************************************************************************************
2 Test Convert JSON to/from KeyValue
3 ***********************************************************************************************************************************/
4 
5 /***********************************************************************************************************************************
6 Test Run
7 ***********************************************************************************************************************************/
8 void
testRun(void)9 testRun(void)
10 {
11     FUNCTION_HARNESS_VOID();
12 
13     // *****************************************************************************************************************************
14     if (testBegin("jsonToBool() and jsonToBoolInternal()"))
15     {
16         TEST_ERROR(jsonToBool(STRDEF("z")), JsonFormatError, "expected boolean at 'z'");
17         TEST_ERROR(jsonToBool(STRDEF("falsex")), JsonFormatError, "unexpected characters after boolean at 'x'");
18 
19         TEST_RESULT_BOOL(jsonToBool(STRDEF("true")), true, "bool is true");
20         TEST_RESULT_BOOL(jsonToBool(STRDEF("false")), false, "bool is false");
21     }
22 
23     // *****************************************************************************************************************************
24     if (testBegin("jsonToInt(), jsonToInt64(), jsonToUInt(), jsonToUInt64() and jsonToIntInternal()"))
25     {
26         TEST_ERROR(jsonToUInt(STRDEF("-")), JsonFormatError, "found '-' with no integer at '-'");
27         TEST_ERROR(jsonToUInt(STRDEF(" 555555555 A")), JsonFormatError, "unexpected characters after number at 'A'");
28 
29         TEST_RESULT_INT(jsonToInt(STRDEF("-555555555 ")), -555555555, "integer");
30         TEST_RESULT_INT(jsonToInt64(STRDEF("-555555555555 ")), -555555555555, "integer");
31         TEST_RESULT_UINT(jsonToUInt(STRDEF("\t555555555\n\r")), 555555555, "unsigned integer");
32         TEST_RESULT_UINT(jsonToUInt64(STRDEF(" 555555555555 ")), 555555555555, "unsigned integer");
33     }
34 
35     // *****************************************************************************************************************************
36     if (testBegin("jsonToStr() and jsonToStrInternal()"))
37     {
38         TEST_ERROR(jsonToStr(STRDEF("\"\\j\"")), JsonFormatError, "invalid escape character 'j'");
39         TEST_ERROR(jsonToStr(STRDEF("\"\\uffff\"")), JsonFormatError, "unable to decode 'ffff'");
40         TEST_ERROR(jsonToStr(STRDEF("\"runonstring")), JsonFormatError, "expected '\"' but found null delimiter");
41         TEST_ERROR(jsonToStr(STRDEF("\"normal\"L")), JsonFormatError, "unexpected characters after string at 'L'");
42         TEST_ERROR(jsonToStr(STRDEF("nullz")), JsonFormatError, "unexpected characters after string at 'z'");
43 
44         TEST_RESULT_STR(jsonToStr(STRDEF("null")), NULL, "null string");
45         TEST_RESULT_STR_Z(jsonToStr(STRDEF(" \"test\"")), "test", "simple string");
46         TEST_RESULT_STR_Z(jsonToStr(STRDEF("\"te\\\"st\" ")), "te\"st", "string with quote");
47         TEST_RESULT_STR_Z(jsonToStr(STRDEF("\"\\\"\\\\\\/\\b\\n\\r\\t\\f\\u0026\"")), "\"\\/\b\n\r\t\f&", "string with escapes");
48     }
49 
50     // *****************************************************************************************************************************
51     if (testBegin("jsonToKv() and jsonToKvInternal()"))
52     {
53         TEST_ERROR(jsonToKv(STRDEF("[")), JsonFormatError, "expected '{' at '['");
54         TEST_ERROR(jsonToKv(STRDEF("{\"key1\"= 747}")), JsonFormatError, "expected ':' at '= 747}'");
55         TEST_ERROR(jsonToKv(STRDEF("{\"key1\" : 747'")), JsonFormatError, "expected '}' at '''");
56         TEST_ERROR(jsonToKv(STRDEF("{key1")), JsonFormatError, "expected '\"' at 'key1'");
57         TEST_ERROR(jsonToKv(STRDEF("{}BOGUS")), JsonFormatError, "unexpected characters after object at 'BOGUS'");
58 
59         KeyValue *kv = NULL;
60         TEST_ASSIGN(kv, jsonToKv(STRDEF("{\"key1\": 747, \"key2\":\"value2\",\"key3\"\t:\t[\t] }")), "object");
61         TEST_RESULT_UINT(varLstSize(kvKeyList(kv)), 3, "check key total");
62         TEST_RESULT_UINT(varUInt64(kvGet(kv, VARSTRDEF("key1"))), 747, "check object uint");
63         TEST_RESULT_STR_Z(varStr(kvGet(kv, VARSTRDEF("key2"))), "value2", "check object str");
64         TEST_RESULT_UINT(varLstSize(varVarLst(kvGet(kv, VARSTRDEF("key3")))), 0, "check empty array");
65 
66         TEST_ASSIGN(kv, jsonToKv(STRDEF("\t{\n} ")), "empty object");
67         TEST_RESULT_UINT(varLstSize(kvKeyList(kv)), 0, "check key total");
68     }
69 
70     // *****************************************************************************************************************************
71     if (testBegin("jsonToVar()"))
72     {
73         TEST_ERROR(jsonToVar(strNew()), JsonFormatError, "expected data");
74         TEST_ERROR(jsonToVar(STRDEF(" \t\r\n ")), JsonFormatError, "expected data");
75         TEST_ERROR(jsonToVar(STRDEF("z")), JsonFormatError, "invalid type at 'z'");
76         TEST_ERROR(jsonToVar(STRDEF("3 =")), JsonFormatError, "unexpected characters after JSON at '='");
77 
78         // -------------------------------------------------------------------------------------------------------------------------
79         TEST_RESULT_STR_Z(varStr(jsonToVar(STRDEF(" \"test\""))), "test", "simple string");
80         TEST_RESULT_STR_Z(varStr(jsonToVar(STRDEF("\"te\\\"st\" "))), "te\"st", "string with quote");
81         TEST_RESULT_STR_Z(varStr(jsonToVar(STRDEF("\"\\\"\\\\\\/\\b\\n\\r\\t\\f\""))), "\"\\/\b\n\r\t\f", "string with escapes");
82 
83         // -------------------------------------------------------------------------------------------------------------------------
84         TEST_ERROR(jsonToVar(STRDEF("ton")), JsonFormatError, "expected boolean at 'ton'");
85         TEST_RESULT_BOOL(varBool(jsonToVar(STRDEF(" true"))), true, "boolean true");
86         TEST_RESULT_BOOL(varBool(jsonToVar(STRDEF("false "))), false, "boolean false");
87 
88         // -------------------------------------------------------------------------------------------------------------------------
89         TEST_ERROR(jsonToVar(STRDEF("not")), JsonFormatError, "expected null at 'not'");
90         TEST_RESULT_PTR(jsonToVar(STRDEF("null")), NULL, "null value");
91 
92         // -------------------------------------------------------------------------------------------------------------------------
93         TEST_ERROR(jsonToVar(STRDEF("[1, \"test\", false")), JsonFormatError, "expected ']' at ''");
94 
95         VariantList *valueList = NULL;
96         TEST_ASSIGN(valueList, varVarLst(jsonToVar(STRDEF("[1, \"test\", false]"))), "array");
97         TEST_RESULT_UINT(varLstSize(valueList), 3, "check array size");
98         TEST_RESULT_UINT(varUInt64(varLstGet(valueList, 0)), 1, "check array int");
99         TEST_RESULT_STR_Z(varStr(varLstGet(valueList, 1)), "test", "check array str");
100         TEST_RESULT_BOOL(varBool(varLstGet(valueList, 2)), false, "check array bool");
101 
102         TEST_ASSIGN(valueList, varVarLst(jsonToVar(STRDEF("[ ]"))), "empty array");
103         TEST_RESULT_UINT(varLstSize(valueList), 0, "check array size");
104 
105         // -------------------------------------------------------------------------------------------------------------------------
106         KeyValue *kv = NULL;
107         TEST_ASSIGN(kv, varKv(jsonToVar(STRDEF("\t{\n} "))), "empty object");
108         TEST_RESULT_UINT(varLstSize(kvKeyList(kv)), 0, "check key total");
109     }
110 
111     // *****************************************************************************************************************************
112     if (testBegin("jsonToVarLst() and jsonToArrayInternal()"))
113     {
114         TEST_ERROR(jsonToVarLst(STRDEF("{")), JsonFormatError, "expected '[' at '{'");
115         TEST_ERROR(jsonToVarLst(STRDEF("[")), JsonFormatError, "expected data");
116         TEST_ERROR(jsonToVarLst(STRDEF(" [] ZZZ")), JsonFormatError, "unexpected characters after array at 'ZZZ'");
117 
118         TEST_RESULT_STRLST_Z(strLstNewVarLst(jsonToVarLst(STRDEF("[\"e1\", \"e2\"]"))), "e1\ne2\n", "json list");
119     }
120 
121     // *****************************************************************************************************************************
122     if (testBegin("jsonFromBool()"))
123     {
124         TEST_RESULT_STR_Z(jsonFromBool(true), "true", "json bool true");
125         TEST_RESULT_STR_Z(jsonFromBool(false), "false", "json bool true");
126     }
127 
128     // *****************************************************************************************************************************
129     if (testBegin("jsonFromInt(), jsonFromInt64(), jsonFromUInt() and jsonFromUInt64()"))
130     {
131         TEST_RESULT_STR_Z(jsonFromInt(-2147483648), "-2147483648", "json int");
132         TEST_RESULT_STR_Z(jsonFromInt64(-9223372036854775807L), "-9223372036854775807", "json int64");
133         TEST_RESULT_STR_Z(jsonFromUInt(4294967295), "4294967295", "json uint");
134         TEST_RESULT_STR_Z(jsonFromUInt64(18446744073709551615UL), "18446744073709551615", "json uint64");
135     }
136 
137     // *****************************************************************************************************************************
138     if (testBegin("jsonFromStr() and jsonFromStrInternal()"))
139     {
140         TEST_RESULT_STR_Z(jsonFromStr(NULL), "null", "null string");
141         TEST_RESULT_STR_Z(jsonFromStr(STRDEF("simple string")), "\"simple string\"", "simple string");
142         TEST_RESULT_STR_Z(jsonFromStr(STRDEF("\"\\/\b\n\r\t\f")), "\"\\\"\\\\/\\b\\n\\r\\t\\f\"", "string escapes");
143     }
144 
145     // *****************************************************************************************************************************
146     if (testBegin("jsonFromKv(), jsonFromKvInternal()"))
147     {
148         KeyValue *keyValue = kvNew();
149         String *json = NULL;
150 
151         TEST_ASSIGN(json, jsonFromKv(keyValue), "kvToJson - empty");
152         TEST_RESULT_STR_Z(json, "{}", "  empty curly brackets");
153 
154         kvPut(keyValue, varNewStrZ("backup"), varNewVarLst(varLstNew()));
155         TEST_ASSIGN(json, jsonFromKv(keyValue), "kvToJson - kv with empty array");
156         TEST_RESULT_STR_Z(json, "{\"backup\":[]}", "  kv with empty array brackets");
157 
158         kvPutKv(keyValue, VARSTRDEF("archive"));
159         kvPutKv(keyValue, VARSTRDEF("empty"));
160         kvPut(keyValue, varNewStrZ("bool1"), varNewBool(true));
161         kvPut(keyValue, varNewStrZ("bool2"), varNewBool(false));
162         kvPut(keyValue, varNewStrZ("null-str"), varNewStr(NULL));
163         kvPut(keyValue, varNewStrZ("checknull"), (Variant *)NULL);
164 
165         VariantList *dbList = varLstNew();
166         Variant *dbInfo = varNewKv(kvNew());
167         kvPut(varKv(dbInfo), VARSTRDEF("id"), varNewInt(1));
168         kvPut(varKv(dbInfo), VARSTRDEF("version"), VARSTRDEF("9.4"));
169         varLstAdd(dbList, dbInfo);
170         varLstAdd(dbList, NULL);
171         kvPut(keyValue, varNewStrZ("db"), varNewVarLst(dbList));
172         kvPut(keyValue, varNewStrZ("null-list"), varNewVarLst(NULL));
173 
174         TEST_ASSIGN(json, jsonFromKv(keyValue), "kvToJson - kv with empty array, kv, varList with values");
175         TEST_RESULT_STR_Z(
176             json,
177             "{"
178                 "\"archive\":{},"
179                 "\"backup\":[],"
180                 "\"bool1\":true,"
181                 "\"bool2\":false,"
182                 "\"checknull\":null,"
183                 "\"db\":["
184                     "{"
185                         "\"id\":1,"
186                         "\"version\":\"9.4\""
187                     "},"
188                     "null"
189                 "],"
190                 "\"empty\":{},"
191                 "\"null-list\":null,"
192                 "\"null-str\":null"
193             "}",
194             "  kv with empty array, kv, varList with values");
195 
196         TEST_ASSIGN(
197             keyValue,
198             varKv(
199                 jsonToVar(
200                     STRDEF(
201                     "{\"backup-info-size-delta\":1982702,\"backup-prior\":\"20161219-212741F_20161219-212803I\","
202                     "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\"],"
203                     "\"checksum-page-error\":[1,[4,6]],\"backup-timestamp-start\":1482182951}"))),
204             "multiple values with array");
205         TEST_ASSIGN(json, jsonFromKv(keyValue), "  kvToJson - sorted");
206         TEST_RESULT_STR_Z(
207             json,
208             "{\"backup-info-size-delta\":1982702,\"backup-prior\":\"20161219-212741F_20161219-212803I\","
209             "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\"],"
210             "\"backup-timestamp-start\":1482182951,\"checksum-page-error\":[1,[4,6]]}",
211             "  check string no pretty print");
212     }
213 
214     // *****************************************************************************************************************************
215     if (testBegin("jsonFromVar()"))
216     {
217         TEST_ERROR(jsonFromVar(varNewInt(1)), JsonFormatError, "variant type is invalid");
218 
219         String *json = NULL;
220         Variant *keyValue = NULL;
221 
222         TEST_ASSIGN(keyValue, varNewKv(kvNew()), "build new kv");
223         kvPut(varKv(keyValue), varNewStrZ("backup-info-size-delta"), varNewInt(1982702));
224         kvPut(varKv(keyValue), varNewStrZ("backup-prior"), varNewStrZ("20161219-212741F_20161219-212803I"));
225 
226         Variant *listVar = NULL;
227         TEST_ASSIGN(listVar, varNewVarLst(varLstNew()), "  new string array to kv");
228         varLstAdd(varVarLst(listVar), varNewStrZ("20161219-212741F"));
229         varLstAdd(varVarLst(listVar), varNewStrZ("20161219-212741F_20161219-212803I"));
230         varLstAdd(varVarLst(listVar), varNewStrZ(NULL));
231         kvPut(varKv(keyValue), varNewStrZ("backup-reference"), listVar);
232         kvPut(varKv(keyValue), varNewStrZ("backup-timestamp-start"), varNewInt(1482182951));
233 
234         Variant *listVar2 = NULL;
235         TEST_ASSIGN(listVar2, varNewVarLst(varLstNew()), "  new int array to kv");
236         varLstAdd(varVarLst(listVar2), varNewInt(1));
237         kvPut(varKv(keyValue), varNewStrZ("checksum-page-error"), listVar2);
238 
239         // Embed a keyValue section to test recursion
240         const Variant *sectionKey = VARSTRDEF("section");
241         KeyValue *sectionKv = kvPutKv(varKv(keyValue), sectionKey);
242         kvPut(sectionKv, VARSTRDEF("key1"), VARSTRDEF("value1"));
243         kvPut(sectionKv, VARSTRDEF("key2"), (Variant *)NULL);
244         kvPut(sectionKv, VARSTRDEF("key3"), VARSTRDEF("value2"));
245         kvAdd(sectionKv, VARSTRDEF("escape"), VARSTRDEF("\"\\/\b\n\r\t\f"));
246 
247         TEST_ASSIGN(json, jsonFromVar(keyValue), "KeyValue");
248         TEST_RESULT_STR_Z(
249             json,
250             "{\"backup-info-size-delta\":1982702,\"backup-prior\":\"20161219-212741F_20161219-212803I\","
251             "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\",null],"
252             "\"backup-timestamp-start\":1482182951,\"checksum-page-error\":[1],"
253             "\"section\":{\"escape\":\"\\\"\\\\/\\b\\n\\r\\t\\f\",\"key1\":\"value1\",\"key2\":null,\"key3\":\"value2\"}}",
254             "  sorted json string result, no pretty print");
255 
256         //--------------------------------------------------------------------------------------------------------------------------
257         Variant *varListOuter = NULL;
258 
259         TEST_ASSIGN(json, jsonFromVar(varNewVarLst(varLstNew())), "VariantList");
260         TEST_RESULT_STR_Z(json, "[]", "  empty list no pretty print");
261 
262         TEST_ASSIGN(varListOuter, varNewVarLst(varLstNew()), "new variant list with keyValues");
263         varLstAdd(varVarLst(varListOuter), varNewStrZ("ASTRING"));
264         varLstAdd(varVarLst(varListOuter), varNewInt64(9223372036854775807LL));
265         varLstAdd(varVarLst(varListOuter), varNewInt(2147483647));
266         varLstAdd(varVarLst(varListOuter), varNewBool(true));
267         varLstAdd(varVarLst(varListOuter), varNewVarLst(NULL));
268         varLstAdd(varVarLst(varListOuter), varNewVarLst(varLstNew()));
269         varLstAdd(varVarLst(varListOuter), NULL);
270         varLstAdd(varVarLst(varListOuter), keyValue);
271 
272         TEST_ASSIGN(json, jsonFromVar(varListOuter), "VariantList");
273         TEST_RESULT_STR_Z(
274             json,
275             "[\"ASTRING\",9223372036854775807,2147483647,true,null,[],null,{\"backup-info-size-delta\":1982702,"
276             "\"backup-prior\":\"20161219-212741F_20161219-212803I\","
277             "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\",null],"
278             "\"backup-timestamp-start\":1482182951,\"checksum-page-error\":[1],"
279             "\"section\":{\"escape\":\"\\\"\\\\/\\b\\n\\r\\t\\f\",\"key1\":\"value1\",\"key2\":null,\"key3\":\"value2\"}}]",
280             "  sorted json string result no pretty print");
281 
282         Variant *keyValue2 = varDup(keyValue);
283         varLstAdd(varVarLst(varListOuter), keyValue2);
284 
285         TEST_ASSIGN(json, jsonFromVar(varListOuter), "VariantList - multiple elements");
286         TEST_RESULT_STR_Z(
287             json,
288             "[\"ASTRING\",9223372036854775807,2147483647,true,null,[],null,{\"backup-info-size-delta\":1982702,"
289             "\"backup-prior\":\"20161219-212741F_20161219-212803I\","
290             "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\",null],"
291             "\"backup-timestamp-start\":1482182951,\"checksum-page-error\":[1],"
292             "\"section\":{\"escape\":\"\\\"\\\\/\\b\\n\\r\\t\\f\",\"key1\":\"value1\",\"key2\":null,\"key3\":\"value2\"}},"
293             "{\"backup-info-size-delta\":1982702,\"backup-prior\":\"20161219-212741F_20161219-212803I\","
294             "\"backup-reference\":[\"20161219-212741F\",\"20161219-212741F_20161219-212803I\",null],"
295             "\"backup-timestamp-start\":1482182951,\"checksum-page-error\":[1],"
296             "\"section\":{\"escape\":\"\\\"\\\\/\\b\\n\\r\\t\\f\",\"key1\":\"value1\",\"key2\":null,\"key3\":\"value2\"}}]",
297             "  sorted json string result no pretty print");
298 
299         VariantList *varList = varLstNew();
300         varLstAdd(varList, varNewUInt(32));
301         varLstAdd(varList, varNewUInt64(10000000000));
302 
303         TEST_RESULT_STR_Z(jsonFromVar(varNewVarLst(varList)), "[32,10000000000]", "list various types");
304 
305         //--------------------------------------------------------------------------------------------------------------------------
306         TEST_RESULT_STR_Z(jsonFromVar(NULL), "null", "null variant");
307         TEST_RESULT_STR_Z(jsonFromVar(varNewBool(true)), "true", "bool variant");
308         TEST_RESULT_STR_Z(jsonFromVar(varNewUInt(66)), "66", "uint variant");
309         TEST_RESULT_STR_Z(jsonFromVar(varNewUInt64(10000000001)), "10000000001", "uint64 variant");
310         TEST_RESULT_STR_Z(jsonFromVar(varNewStrZ("test \" string")), "\"test \\\" string\"", "string variant");
311     }
312 
313     FUNCTION_HARNESS_RETURN_VOID();
314 }
315