+static void
+test_gbytes (void)
+{
+ GVariant *a;
+ GVariant *tuple;
+ GBytes *bytes;
+ GBytes *bytes2;
+ const guint8 values[5] = { 1, 2, 3, 4, 5 };
+ const guint8 *elts;
+ gsize n_elts;
+ gint i;
+
+ bytes = g_bytes_new (&values, 5);
+ a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
+ g_bytes_unref (bytes);
+ n_elts = 0;
+ elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8));
+ g_assert (n_elts == 5);
+ for (i = 0; i < 5; i++)
+ g_assert_cmpint (elts[i], ==, i + 1);
+
+ bytes2 = g_variant_get_data_as_bytes (a);
+ g_variant_unref (a);
+
+ bytes = g_bytes_new (&values, 5);
+ g_assert (g_bytes_equal (bytes, bytes2));
+ g_bytes_unref (bytes);
+ g_bytes_unref (bytes2);
+
+ tuple = g_variant_new_parsed ("['foo', 'bar']");
+ bytes = g_variant_get_data_as_bytes (tuple); /* force serialisation */
+ a = g_variant_get_child_value (tuple, 1);
+ bytes2 = g_variant_get_data_as_bytes (a);
+ g_assert (!g_bytes_equal (bytes, bytes2));
+
+ g_bytes_unref (bytes);
+ g_bytes_unref (bytes2);
+ g_variant_unref (a);
+ g_variant_unref (tuple);
+}
+
+typedef struct {
+ const GVariantType *type;
+ const gchar *in;
+ const gchar *out;
+} ContextTest;
+
+static void
+test_print_context (void)
+{
+ ContextTest tests[] = {
+ { NULL, "(1, 2, 3, 'abc", " ^^^^" },
+ { NULL, "[1, 2, 3, 'str']", " ^ ^^^^^" },
+ { G_VARIANT_TYPE_UINT16, "{ 'abc':'def' }", " ^^^^^^^^^^^^^^^" },
+ { NULL, "<5", " ^" },
+ { NULL, "'ab\\ux'", " ^^^^^^^" },
+ { NULL, "'ab\\U00efx'", " ^^^^^^^^^^^" }
+ };
+ GVariant *v;
+ gchar *s;
+ gint i;
+ GError *error = NULL;
+
+ for (i = 0; i < G_N_ELEMENTS (tests); i++)
+ {
+ v = g_variant_parse (tests[i].type, tests[i].in, NULL, NULL, &error);
+ g_assert_null (v);
+ s = g_variant_parse_error_print_context (error, tests[i].in);
+ g_assert (strstr (s, tests[i].out) != NULL);
+ g_free (s);
+ g_clear_error (&error);
+ }
+}
+
+static void
+test_error_quark (void)
+{
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ g_assert (g_variant_parser_get_error_quark () == g_variant_parse_error_quark ());
+G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
+static GByteArray *
+flatten_vectors (GVariantVectors *v)
+{
+ GByteArray *result;
+ guint i;
+
+ result = g_byte_array_new ();
+
+ for (i = 0; i < v->vectors->len; i++)
+ {
+ GVariantVector vec = g_array_index (v->vectors, GVariantVector, i);
+
+ if (vec.gbytes)
+ g_byte_array_append (result, vec.data.pointer, vec.size);
+ else
+ g_byte_array_append (result, v->extra_bytes->data + vec.data.offset, vec.size);
+ }
+
+ return result;
+}
+
+static void
+test_vector_serialiser (void)
+{
+ GVariantVectors vectors;
+ GByteArray *flattened;
+ GVariant *value;
+ guint i;
+
+ for (i = 0; i < 100; i++)
+ {
+ value = create_random_gvariant (4);
+
+ GLIB_PRIVATE_CALL(g_variant_to_vectors) (value, &vectors);
+ flattened = flatten_vectors (&vectors);
+ g_byte_array_free (vectors.extra_bytes, TRUE);
+ g_byte_array_free (vectors.offsets, TRUE);
+ g_array_free (vectors.vectors, TRUE);
+
+#if 0
+ if (flattened->len != g_variant_get_size (value) ||
+ memcmp (flattened->data, g_variant_get_data (value), flattened->len) != 0)
+ {
+ g_file_set_contents ("flattened", flattened->data, flattened->len, NULL);
+ g_file_set_contents ("serialised", g_variant_get_data (value), g_variant_get_size (value), NULL);
+ g_print ("type is %s\n", g_variant_get_type_string (value));
+ g_assert_not_reached ();
+ }
+#endif
+
+ g_assert_cmpint (flattened->len, ==, g_variant_get_size (value));
+ g_assert (memcmp (flattened->data, g_variant_get_data (value), flattened->len) == 0);
+
+ g_byte_array_free (flattened, TRUE);
+ g_variant_unref (value);
+ }
+}
+