source: trunk/libtransmission/json-test.c @ 14522

Last change on this file since 14522 was 14522, checked in by mikedld, 6 years ago

Cut internal macro names to have equal number of underscores on each side (take two)

  • Property svn:keywords set to Date Rev Author Id
File size: 7.7 KB
Line 
1/*
2 * This file Copyright (C) 2013-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: json-test.c 14522 2015-05-04 20:06:05Z mikedld $
8 */
9
10#include <string.h> /* strlen () */
11
12#include <locale.h> /* setlocale() */
13
14#define __LIBTRANSMISSION_VARIANT_MODULE__
15#include "transmission.h"
16#include "utils.h" /* tr_free */
17#include "variant.h"
18#include "variant-common.h"
19#include "libtransmission-test.h"
20
21static inline tr_quark
22toQuark (const char * str)
23{
24  return tr_quark_new (str, strlen(str));
25}
26
27static int
28test_elements (void)
29{
30    const char * in;
31    tr_variant top;
32    const char * str;
33    bool f;
34    double d;
35    int64_t i;
36    int err = 0;
37    tr_quark key;
38
39    in = "{ \"string\": \"hello world\","
40         \"escaped\": \"bell \\b formfeed \\f linefeed \\n carriage return \\r tab \\t\","
41         \"int\": 5, "
42         \"float\": 6.5, "
43         \"true\": true, "
44         \"false\": false, "
45         \"null\": null }";
46
47    err = tr_variantFromJson (&top, in, strlen(in));
48    check_int_eq (0, err);
49    check (tr_variantIsDict (&top));
50    str = NULL;
51    key = tr_quark_new ("string", 6);
52    check (tr_variantDictFindStr (&top, key, &str, NULL));
53    check_streq ("hello world", str);
54    check (tr_variantDictFindStr (&top, tr_quark_new("escaped",7), &str, NULL));
55    check_streq ("bell \b formfeed \f linefeed \n carriage return \r tab \t", str);
56    i = 0;
57    check (tr_variantDictFindInt (&top, tr_quark_new("int",3), &i));
58    check_int_eq (5, i);
59    d = 0;
60    check (tr_variantDictFindReal (&top, tr_quark_new("float",5), &d));
61    check_int_eq (65, ((int)(d*10)));
62    f = false;
63    check (tr_variantDictFindBool (&top, tr_quark_new("true",4), &f));
64    check_int_eq (true, f);
65    check (tr_variantDictFindBool (&top, tr_quark_new("false",5), &f));
66    check_int_eq (false, f);
67    check (tr_variantDictFindStr (&top, tr_quark_new("null",4), &str, NULL));
68    check_streq ("", str);
69
70    if (!err)
71        tr_variantFree (&top);
72
73    return 0;
74}
75static int
76test_utf8 (void)
77{
78    const char      * in = "{ \"key\": \"Letöltések\" }";
79    tr_variant           top;
80    const char      * str;
81    char            * json;
82    int               err;
83    const tr_quark key = tr_quark_new ("key", 3);
84
85    err = tr_variantFromJson (&top, in, strlen(in));
86    check (!err);
87    check (tr_variantIsDict (&top));
88    check (tr_variantDictFindStr (&top, key, &str, NULL));
89    check_streq ("Letöltések", str);
90    if (!err)
91        tr_variantFree (&top);
92
93    in = "{ \"key\": \"\\u005C\" }";
94    err = tr_variantFromJson (&top, in, strlen(in));
95    check (!err);
96    check (tr_variantIsDict (&top));
97    check (tr_variantDictFindStr (&top, key, &str, NULL));
98    check_streq ("\\", str);
99    if (!err)
100        tr_variantFree (&top);
101
102    /**
103     * 1. Feed it JSON-escaped nonascii to the JSON decoder.
104     * 2. Confirm that the result is UTF-8.
105     * 3. Feed the same UTF-8 back into the JSON encoder.
106     * 4. Confirm that the result is JSON-escaped.
107     * 5. Dogfood that result back into the parser.
108     * 6. Confirm that the result is UTF-8.
109     */
110    in = "{ \"key\": \"Let\\u00f6lt\\u00e9sek\" }";
111    err = tr_variantFromJson (&top, in, strlen(in));
112    check (!err);
113    check (tr_variantIsDict (&top));
114    check (tr_variantDictFindStr (&top, key, &str, NULL));
115    check_streq ("Letöltések", str);
116    json = tr_variantToStr (&top, TR_VARIANT_FMT_JSON, NULL);
117    if (!err)
118        tr_variantFree (&top);
119    check (json);
120    check (strstr (json, "\\u00f6") != NULL);
121    check (strstr (json, "\\u00e9") != NULL);
122    err = tr_variantFromJson (&top, json, strlen(json));
123    check (!err);
124    check (tr_variantIsDict (&top));
125    check (tr_variantDictFindStr (&top, key, &str, NULL));
126    check_streq ("Letöltések", str);
127    if (!err)
128        tr_variantFree (&top);
129    tr_free (json);
130
131    return 0;
132}
133
134static int
135test1 (void)
136{
137    const char * in =
138        "{\n"
139        "    \"headers\": {\n"
140        "        \"type\": \"request\",\n"
141        "        \"tag\": 666\n"
142        "    },\n"
143        "    \"body\": {\n"
144        "        \"name\": \"torrent-info\",\n"
145        "        \"arguments\": {\n"
146        "            \"ids\": [ 7, 10 ]\n"
147        "        }\n"
148        "    }\n"
149        "}\n";
150    tr_variant      top, *headers, *body, *args, *ids;
151    const char * str;
152    int64_t      i;
153    const int    err = tr_variantFromJson (&top, in, strlen(in));
154
155    check (!err);
156    check (tr_variantIsDict (&top));
157    check ((headers = tr_variantDictFind (&top, tr_quark_new("headers",7))));
158    check (tr_variantIsDict (headers));
159    check (tr_variantDictFindStr (headers, tr_quark_new("type",4), &str, NULL));
160    check_streq ("request", str);
161    check (tr_variantDictFindInt (headers, TR_KEY_tag, &i));
162    check_int_eq (666, i);
163    check ((body = tr_variantDictFind (&top, tr_quark_new("body",4))));
164    check (tr_variantDictFindStr (body, TR_KEY_name, &str, NULL));
165    check_streq ("torrent-info", str);
166    check ((args = tr_variantDictFind (body, tr_quark_new("arguments",9))));
167    check (tr_variantIsDict (args));
168    check ((ids = tr_variantDictFind (args, TR_KEY_ids)));
169    check (tr_variantIsList (ids));
170    check_int_eq (2, tr_variantListSize (ids));
171    check (tr_variantGetInt (tr_variantListChild (ids, 0), &i));
172    check_int_eq (7, i);
173    check (tr_variantGetInt (tr_variantListChild (ids, 1), &i));
174    check_int_eq (10, i);
175
176    tr_variantFree (&top);
177    return 0;
178}
179
180static int
181test2 (void)
182{
183    tr_variant top;
184    const char * in = " ";
185    int err;
186
187    top.type = 0;
188    err = tr_variantFromJson (&top, in, strlen(in));
189
190    check (err);
191    check (!tr_variantIsDict (&top));
192
193    return 0;
194}
195
196static int
197test3 (void)
198{
199    const char * in = "{ \"error\": 2,"
200                      \"errorString\": \"torrent not registered with this tracker 6UHsVW'*C\","
201                      \"eta\": 262792,"
202                      \"id\": 25,"
203                      \"leftUntilDone\": 2275655680 }";
204    tr_variant top;
205    const char * str;
206
207    const int err = tr_variantFromJson (&top, in, strlen(in));
208    check (!err);
209    check (tr_variantDictFindStr (&top, TR_KEY_errorString, &str, NULL));
210    check_streq ("torrent not registered with this tracker 6UHsVW'*C", str);
211
212    tr_variantFree (&top);
213    return 0;
214}
215
216static int
217test_unescape (void)
218{
219    const char * in = "{ \"string-1\": \"\\/usr\\/lib\" }";
220    tr_variant top;
221    const char * str;
222
223    const int err = tr_variantFromJson (&top, in, strlen(in));
224    check_int_eq (0, err);
225    check (tr_variantDictFindStr (&top, tr_quark_new("string-1",8), &str, NULL));
226    check_streq ("/usr/lib", str);
227
228    tr_variantFree (&top);
229    return 0;
230}
231
232int
233main (void)
234{
235  int i;
236  int n;
237  int rv;
238
239  const char * comma_locales[] = { "da_DK.UTF-8",
240                                   "fr_FR.UTF-8",
241                                   "ru_RU.UTF-8"};
242
243  const testFunc tests[] = { test_elements,
244                             test_utf8,
245                             test1,
246                             test2,
247                             test3,
248                             test_unescape };
249
250  /* run the tests in a locale with a decimal point of '.' */
251  setlocale (LC_NUMERIC, "C");
252  if ((rv = runTests (tests, NUM_TESTS (tests))))
253    return rv;
254
255  /* run the tests in a locale with a decimal point of ',' */
256  n = sizeof(comma_locales) / sizeof(comma_locales[0]);
257  for (i=0; i<n; ++i)
258    if (setlocale (LC_NUMERIC, comma_locales[i]) != NULL)
259      break;
260  if (i==n)
261    fprintf (stderr, "WARNING: unable to run locale-specific json tests. add a locale like %s or %s\n",
262             comma_locales[0],
263             comma_locales[1]);
264  else if ((rv = runTests (tests, NUM_TESTS(tests))))
265    return rv;
266
267  /* success */
268  return 0;
269}
Note: See TracBrowser for help on using the repository browser.