Initial Import
[profile/ivi/json-glib.git] / json-glib / tests / serialize-complex.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include <glib-object.h>
6
7 #include <json-glib/json-glib.h>
8 #include <json-glib/json-gobject.h>
9
10 #define TEST_TYPE_BOXED                 (test_boxed_get_type ())
11 #define TEST_TYPE_OBJECT                (test_object_get_type ())
12 #define TEST_OBJECT(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
13 #define TEST_IS_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
14 #define TEST_OBJECT_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
15 #define TEST_IS_OBJECT_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
16 #define TEST_OBJECT_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
17
18 typedef struct _TestBoxed               TestBoxed;
19 typedef struct _TestObject              TestObject;
20 typedef struct _TestObjectClass         TestObjectClass;
21
22 struct _TestBoxed
23 {
24   gint foo;
25   gboolean bar;
26 };
27
28 struct _TestObject
29 {
30   GObject parent_instance;
31
32   gint foo;
33   gboolean bar;
34   gchar *baz;
35   TestBoxed blah;
36   gdouble meh;
37 };
38
39 struct _TestObjectClass
40 {
41   GObjectClass parent_class;
42 };
43
44 GType test_object_get_type (void);
45
46 /*** implementation ***/
47
48 static TestBoxed *
49 test_boxed_copy (const TestBoxed *src)
50 {
51   TestBoxed *copy = g_slice_new (TestBoxed);
52
53   *copy = *src;
54
55   return copy;
56 }
57
58 static void
59 test_boxed_free (TestBoxed *boxed)
60 {
61   if (G_LIKELY (boxed))
62     {
63       g_slice_free (TestBoxed, boxed);
64     }
65 }
66
67 GType
68 test_boxed_get_type (void)
69 {
70   static GType b_type = 0;
71
72   if (G_UNLIKELY (b_type == 0))
73     b_type = g_boxed_type_register_static ("TestBoxed",
74                                            (GBoxedCopyFunc) test_boxed_copy,
75                                            (GBoxedFreeFunc) test_boxed_free);
76
77   return b_type;
78 }
79
80 enum
81 {
82   PROP_0,
83
84   PROP_FOO,
85   PROP_BAR,
86   PROP_BAZ,
87   PROP_BLAH,
88   PROP_MEH
89 };
90
91 static JsonSerializableIface *serializable_iface = NULL;
92
93 static void json_serializable_iface_init (gpointer g_iface);
94
95 G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT,
96                          G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE,
97                                                 json_serializable_iface_init));
98
99 static JsonNode *
100 test_object_serialize_property (JsonSerializable *serializable,
101                                 const gchar      *name,
102                                 const GValue     *value,
103                                 GParamSpec       *pspec)
104 {
105   JsonNode *retval = NULL;
106
107   if (strcmp (name, "blah") == 0)
108     {
109       TestBoxed *boxed;
110       JsonObject *obj;
111       JsonNode *val;
112
113       retval = json_node_new (JSON_NODE_OBJECT);
114       obj = json_object_new ();
115       
116       boxed = g_value_get_boxed (value);
117
118       val = json_node_new (JSON_NODE_VALUE);
119       json_node_set_int (val, boxed->foo);
120       json_object_set_member (obj, "foo", val);
121
122       val = json_node_new (JSON_NODE_VALUE);
123       json_node_set_boolean (val, boxed->bar);
124       json_object_set_member (obj, "bar", val);
125
126       json_node_take_object (retval, obj);
127     }
128   else
129     retval = serializable_iface->serialize_property (serializable,
130                                                      name,
131                                                      value, pspec);
132
133   return retval;
134 }
135
136 static void
137 json_serializable_iface_init (gpointer g_iface)
138 {
139   JsonSerializableIface *iface = g_iface;
140
141   serializable_iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
142
143   iface->serialize_property = test_object_serialize_property;
144 }
145
146 static void
147 test_object_finalize (GObject *gobject)
148 {
149   g_free (TEST_OBJECT (gobject)->baz);
150
151   G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
152 }
153
154 static void
155 test_object_set_property (GObject      *gobject,
156                           guint         prop_id,
157                           const GValue *value,
158                           GParamSpec   *pspec)
159 {
160   switch (prop_id)
161     {
162     case PROP_FOO:
163       TEST_OBJECT (gobject)->foo = g_value_get_int (value);
164       break;
165     case PROP_BAR:
166       TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
167       break;
168     case PROP_BAZ:
169       g_free (TEST_OBJECT (gobject)->baz);
170       TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
171       break;
172     case PROP_MEH:
173       TEST_OBJECT (gobject)->meh = g_value_get_double (value);
174       break;
175     default:
176       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
177     }
178 }
179
180 static void
181 test_object_get_property (GObject    *gobject,
182                           guint       prop_id,
183                           GValue     *value,
184                           GParamSpec *pspec)
185 {
186   switch (prop_id)
187     {
188     case PROP_FOO:
189       g_value_set_int (value, TEST_OBJECT (gobject)->foo);
190       break;
191     case PROP_BAR:
192       g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
193       break;
194     case PROP_BAZ:
195       g_value_set_string (value, TEST_OBJECT (gobject)->baz);
196       break;
197     case PROP_BLAH:
198       g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
199       break;
200     case PROP_MEH:
201       g_value_set_double (value, TEST_OBJECT (gobject)->meh);
202       break;
203     default:
204       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
205     }
206 }
207
208 static void
209 test_object_class_init (TestObjectClass *klass)
210 {
211   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
212
213   gobject_class->set_property = test_object_set_property;
214   gobject_class->get_property = test_object_get_property;
215   gobject_class->finalize = test_object_finalize;
216
217   g_object_class_install_property (gobject_class,
218                                    PROP_FOO,
219                                    g_param_spec_int ("foo", "Foo", "Foo",
220                                                      0, G_MAXINT, 42,
221                                                      G_PARAM_READWRITE));
222   g_object_class_install_property (gobject_class,
223                                    PROP_BAR,
224                                    g_param_spec_boolean ("bar", "Bar", "Bar",
225                                                          TRUE,
226                                                          G_PARAM_READWRITE));
227   g_object_class_install_property (gobject_class,
228                                    PROP_BAZ,
229                                    g_param_spec_string ("baz", "Baz", "Baz",
230                                                         NULL,
231                                                         G_PARAM_READWRITE));
232   g_object_class_install_property (gobject_class,
233                                    PROP_BLAH,
234                                    g_param_spec_boxed ("blah", "Blah", "Blah",
235                                                        TEST_TYPE_BOXED,
236                                                        G_PARAM_READABLE));
237   g_object_class_install_property (gobject_class,
238                                    PROP_MEH,
239                                    g_param_spec_double ("meh", "Meh", "Meh",
240                                                         0.0, 1.0, 0.0,
241                                                         G_PARAM_READWRITE |
242                                                         G_PARAM_CONSTRUCT));
243 }
244
245 static void
246 test_object_init (TestObject *object)
247 {
248   object->foo = 42;
249   object->bar = TRUE;
250   object->baz = g_strdup ("Test");
251   object->meh = 0.0;
252
253   object->blah.foo = object->foo;
254   object->blah.bar = object->bar;
255 }
256
257 static void
258 test_serialize (void)
259 {
260   TestObject *obj = g_object_new (TEST_TYPE_OBJECT,
261                                   "foo", 47,
262                                   "bar", FALSE,
263                                   "baz", "Hello, World!",
264                                   "meh", 0.5,
265                                   NULL);
266   JsonParser *parser = json_parser_new ();
267   GError *error = NULL;
268   JsonObject *object;
269   JsonNode *node;
270   gchar *data;
271   gsize len;
272
273   data = json_gobject_to_data (G_OBJECT (obj), &len);
274
275   g_assert_cmpint (len, >, 0);
276   if (g_test_verbose ())
277     g_print ("TestObject:\n%s\n", data);
278
279   parser = json_parser_new ();
280   json_parser_load_from_data (parser, data, -1, &error);
281   g_assert (error == NULL);
282
283   node = json_parser_get_root (parser);
284   g_assert (json_node_get_node_type (node) == JSON_NODE_OBJECT);
285
286   object = json_node_get_object (node);
287   g_assert_cmpint (json_object_get_int_member (object, "foo"), ==, 47);
288   g_assert (!json_object_get_boolean_member (object, "bar"));
289   g_assert_cmpstr (json_object_get_string_member (object, "baz"), ==, "Hello, World!");
290   g_assert_cmpfloat (json_object_get_double_member (object, "meh"), ==, 0.5);
291
292   /* blah is read-only */
293   g_assert (json_object_has_member (object, "blah"));
294
295   g_free (data);
296   g_object_unref (parser);
297   g_object_unref (obj);
298 }
299
300 int
301 main (int   argc,
302       char *argv[])
303 {
304   g_type_init ();
305   g_test_init (&argc, &argv, NULL);
306
307   g_test_add_func ("/serialize/gobject-boxed", test_serialize);
308
309   return g_test_run ();
310 }