Imported Upstream version 1.2.4
[platform/upstream/json-glib.git] / json-glib / tests / gvariant.c
1 #include <glib.h>
2 #include <json-glib/json-glib.h>
3 #include <string.h>
4
5 typedef struct
6 {
7   gchar *test_name;
8   gchar *signature;
9   gchar *variant_data;
10   gchar *json_data;
11 } TestCase;
12
13 /* each entry in this list spawns to a GVariant-to-JSON and
14    JSON-to-GVariant test */
15 static const TestCase two_way_test_cases[] =
16   {
17     /* boolean */
18     { "/boolean", "(b)", "(true,)", "[true]" },
19
20     /* byte */
21     { "/byte", "(y)", "(byte 0xff,)", "[255]" },
22
23     /* int16 */
24     { "/int16", "(n)", "(int16 -12345,)", "[-12345]" },
25
26     /* uint16 */
27     { "/uint16", "(q)", "(uint16 40001,)", "[40001]" },
28
29     /* int32 */
30     { "/int32", "(i)", "(-7654321,)", "[-7654321]" },
31
32     /* uint32 */
33     { "/uint32", "(u)", "(uint32 12345678,)", "[12345678]" },
34
35     /* int64 */
36     { "/int64", "(x)", "(int64 -666999666999,)", "[-666999666999]" },
37
38     /* uint64 */
39     { "/uint64", "(t)", "(uint64 1999999999999999,)", "[1999999999999999]" },
40
41     /* handle */
42     { "/handle", "(h)", "(handle 1,)", "[1]" },
43
44     /* double */
45     { "/double", "(d)", "(1.23,)", "[1.23]" },
46
47     /* double */
48     { "/double-whole", "(d)", "(123.0,)", "[123.0]" },
49
50     /* string */
51     { "/string", "(s)", "('hello world!',)", "[\"hello world!\"]" },
52
53     /* object-path */
54     { "/object-path", "(o)", "(objectpath '/org/gtk/json_glib',)", "[\"/org/gtk/json_glib\"]" },
55
56     /* signature */
57     { "/signature", "(g)", "(signature '(asna{sv}i)',)", "[\"(asna{sv}i)\"]" },
58
59     /* maybe - null string */
60     { "/maybe/simple/null", "(ms)", "(@ms nothing,)", "[null]" },
61
62     /* maybe - simple string */
63     { "/maybe/simple/string", "(ms)", "(@ms 'maybe string',)", "[\"maybe string\"]" },
64
65     /* maybe - null container */
66     { "/maybe/container/null", "(m(sn))", "(@m(sn) nothing,)", "[null]" },
67
68     /* maybe - tuple container */
69     { "/maybe/container/tuple", "(m(sn))", "(@m(sn) ('foo', 0),)", "[[\"foo\",0]]" },
70
71     /* maybe - variant boolean */
72     { "/maybe/variant/boolean", "(mv)", "(@mv <true>,)", "[true]" },
73
74     /* empty array */
75     { "/array/empty", "as", "@as []", "[]" },
76
77     /* array of bytes */
78     { "/array/byte", "ay", "[byte 0x01, 0x0a, 0x03, 0xff]", "[1,10,3,255]" },
79
80     /* array of strings */
81     { "/array/string", "as", "['a', 'b', 'ab', 'ba']", "[\"a\",\"b\",\"ab\",\"ba\"]" },
82
83     /* array of array of int32 */
84     { "/array/array/int32", "aai", "[[1, 2], [3, 4], [5, 6]]", "[[1,2],[3,4],[5,6]]" },
85
86     /* array of variants */
87     { "/array/variant", "av", "[<true>, <int64 1>, <'oops'>, <int64 -2>, <0.5>]", "[true,1,\"oops\",-2,0.5]" },
88
89     /* tuple */
90     { "/tuple", "(bynqiuxthds)",
91       "(false, byte 0x00, int16 -1, uint16 1, -2, uint32 2, int64 429496729, uint64 3, handle 16, 2.48, 'end')",
92       "[false,0,-1,1,-2,2,429496729,3,16,2.48,\"end\"]" },
93
94     /* empty dictionary */
95     { "/dictionary/empty", "a{sv}", "@a{sv} {}", "{}" },
96
97     /* single dictionary entry */
98     { "/dictionary/single-entry", "{ss}", "{'hello', 'world'}", "{\"hello\":\"world\"}" },
99
100     /* dictionary - string : int32 */
101     { "/dictionary/string-int32", "a{si}", "{'foo': 1, 'bar': 2}", "{\"foo\":1,\"bar\":2}" },
102
103     /* dictionary - string : variant */
104     { "/dictionary/string-variant", "a{sv}", "{'str': <'hi!'>, 'bool': <true>}", "{\"str\":\"hi!\",\"bool\":true}" },
105
106     /* dictionary - int64 : variant */
107     { "/dictionary/int64-variant", "a{xv}",
108       "{int64 -5: <'minus five'>, 10: <'ten'>}", "{\"-5\":\"minus five\",\"10\":\"ten\"}" },
109
110     /* dictionary - uint64 : variant */
111     { "/dictionary/uint64-boolean", "a{tb}",
112       "{uint64 999888777666: true, 0: false}", "{\"999888777666\":true,\"0\":false}" },
113
114     /* dictionary - boolean : variant */
115     { "/dictionary/boolean-variant", "a{by}", "{true: byte 0x01, false: 0x00}", "{\"true\":1,\"false\":0}" },
116
117     /* dictionary - double : string */
118     { "/dictionary/double-string", "a{ds}", "{1.0: 'one point zero'}", "{\"1.000000\":\"one point zero\"}" },
119
120     /* variant - string */
121     { "/variant/string", "(v)", "(<'string within variant'>,)", "[\"string within variant\"]" },
122
123     /* variant - maybe null  */
124     { "/variant/maybe/null", "(v)", "(<@mv nothing>,)", "[null]" },
125
126     /* variant - dictionary */
127     { "/variant/dictionary", "v", "<{'foo': <'bar'>, 'hi': <int64 1024>}>", "{\"foo\":\"bar\",\"hi\":1024}" },
128
129     /* variant - variant - array */
130     { "/variant/variant/array", "v", "<[<'any'>, <'thing'>, <int64 0>, <int64 -1>]>", "[\"any\",\"thing\",0,-1]" },
131
132     /* deep-nesting */
133     { "/deep-nesting",
134       "a(a(a(a(a(a(a(a(a(a(s))))))))))",
135       "[([([([([([([([([([('sorprise',)],)],)],)],)],)],)],)],)],)]",
136       "[[[[[[[[[[[[[[[[[[[[\"sorprise\"]]]]]]]]]]]]]]]]]]]]" },
137
138     /* mixed1 */
139     { "/mixed1",
140       "a{s(syba(od))}",
141       "{'foo': ('bar', byte 0x64, true, [(objectpath '/baz', 1.3), ('/cat', -2.5)])}",
142       "{\"foo\":[\"bar\",100,true,[[\"/baz\",1.3],[\"/cat\",-2.5]]]}" },
143
144     /* mixed2 */
145     { "/mixed2",
146       "(a{by}amsvmaba{qm(sg)})",
147       "({true: byte 0x01, false: 0x00}, [@ms 'do', nothing, 'did'], <@av []>, @mab nothing, {uint16 10000: @m(sg) ('yes', 'august'), 0: nothing})",
148       "[{\"true\":1,\"false\":0},[\"do\",null,\"did\"],[],null,{\"10000\":[\"yes\",\"august\"],\"0\":null}]" },
149   };
150
151 static const TestCase json_to_gvariant_test_cases[] =
152   {
153     { "/string-to-boolean", "(b)", "(true,)", "[\"true\"]" },
154     { "/string-to-byte", "(y)", "(byte 0xff,)", "[\"255\"]" },
155     { "/string-to-int16", "(n)", "(int16 -12345,)", "[\"-12345\"]" },
156     { "/string-to-uint16", "(q)", "(uint16 40001,)", "[\"40001\"]" },
157     { "/string-to-int32", "(i)", "(-7654321,)", "[\"-7654321\"]" },
158     { "/string-to-int64", "(x)", "(int64 -666999666999,)", "[\"-666999666999\"]" },
159     { "/string-to-uint64", "(t)", "(uint64 1999999999999999,)", "[\"1999999999999999\"]" },
160     { "/string-to-double", "(d)", "(1.23,)", "[\"1.23\"]" },
161     { "/string-to-double-whole", "(d)", "(123.0,)", "[\"123.0\"]" },
162   };
163
164 static void
165 test_gvariant_to_json (gconstpointer test_data)
166 {
167   TestCase *test_case = (TestCase *) test_data;
168   GVariant *variant;
169   gchar *json_data;
170   gsize len;
171
172   variant = g_variant_parse (G_VARIANT_TYPE (test_case->signature),
173                              test_case->variant_data,
174                              NULL,
175                              NULL,
176                              NULL);
177
178   json_data = json_gvariant_serialize_data (variant, &len);
179   g_assert (json_data != NULL);
180
181   g_assert_cmpstr (test_case->json_data, ==, json_data);
182
183   g_free (json_data);
184   g_variant_unref (variant);
185 }
186
187 static void
188 test_json_to_gvariant (gconstpointer test_data)
189 {
190   TestCase *test_case = (TestCase *) test_data;
191   GVariant *variant;
192   gchar *variant_data;
193   GError *error = NULL;
194
195   variant = json_gvariant_deserialize_data (test_case->json_data,
196                                             -1,
197                                             test_case->signature,
198                                             &error);
199
200   if (variant == NULL)
201     {
202       g_assert_no_error (error);
203       g_error_free (error);
204     }
205   else
206     {
207       variant_data = g_variant_print (variant, TRUE);
208
209       g_assert_cmpstr (test_case->variant_data, ==, variant_data);
210
211       g_free (variant_data);
212       g_variant_unref (variant);
213     }
214 }
215
216 gint
217 main (gint argc, gchar *argv[])
218 {
219   gint i;
220   TestCase test_case;
221   gchar *test_name;
222
223   g_test_init (&argc, &argv, NULL);
224
225   /* GVariant to JSON */
226   for (i = 0; i < G_N_ELEMENTS (two_way_test_cases); i++)
227     {
228       test_case = two_way_test_cases[i];
229       test_name = g_strdup_printf ("/gvariant/to-json/%s", test_case.test_name);
230
231       g_test_add_data_func (test_name, &two_way_test_cases[i], test_gvariant_to_json);
232
233       g_free (test_name);
234     }
235
236   /* JSON to GVariant */
237   for (i = 0; i < G_N_ELEMENTS (two_way_test_cases); i++)
238     {
239       test_case = two_way_test_cases[i];
240       test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name);
241
242       g_test_add_data_func (test_name, &two_way_test_cases[i], test_json_to_gvariant);
243
244       g_free (test_name);
245     }
246
247   /* JSON to GVariant one way tests */
248   for (i = 0; i < G_N_ELEMENTS (json_to_gvariant_test_cases); i++)
249     {
250       test_case = json_to_gvariant_test_cases[i];
251       test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name);
252
253       g_test_add_data_func (test_name, &json_to_gvariant_test_cases[i], test_json_to_gvariant);
254
255       g_free (test_name);
256     }
257
258   return g_test_run ();
259 }