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

Last change on this file since 14241 was 14241, checked in by jordan, 7 years ago

Copyedit the license's revised text: (1) remove unnecessary repitition use of the word 'license' from the top of the header and source files (2) add the standard 'we hope it's useful, but no warranty' clause to COPYING (3) make explicit that linking OpenSSL is allowed (see https://people.gnome.org/~markmc/openssl-and-the-gpl.html for background) (4) sync the Qt and GTK+ clients' license popups with COPYING's revised text

  • 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 14241 2014-01-21 03:10:30Z jordan $
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.