[glib/gvariant: 7/7] Add GVariant test cases



commit 00ddd213b8178f239da6b2bdfd5a444923423e70
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Apr 7 12:27:06 2009 -0400

    Add GVariant test cases
---
 glib/tests/.gitignore              |    7 +
 glib/tests/Makefile.am             |   21 ++
 glib/tests/gvariant-basic.c        |  315 ++++++++++++++++++++++++++
 glib/tests/gvariant-big.c          |  217 ++++++++++++++++++
 glib/tests/gvariant-complex.c      |  175 +++++++++++++++
 glib/tests/gvariant-constructors.c |  297 +++++++++++++++++++++++++
 glib/tests/gvariant-endian.c       |   32 +++
 glib/tests/gvariant-fuzz.c         |  428 ++++++++++++++++++++++++++++++++++++
 glib/tests/gvariant-markup.c       |  111 ++++++++++
 glib/tests/gvariant-random.c       |  334 ++++++++++++++++++++++++++++
 glib/tests/gvariant-serialiser.c   |   90 ++++++++
 glib/tests/gvariant-varargs.c      |  289 ++++++++++++++++++++++++
 12 files changed, 2316 insertions(+), 0 deletions(-)

diff --git a/glib/tests/.gitignore b/glib/tests/.gitignore
index 5e91729..523716c 100644
--- a/glib/tests/.gitignore
+++ b/glib/tests/.gitignore
@@ -9,3 +9,10 @@ strfuncs
 string
 testing
 tmpsample.xml
+gvariant-big
+gvariant-endian
+gvariant-fuzz
+gvariant-markup
+gvariant-random
+gvariant-serialiser
+gvariant-varargs
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index 3d497ac..a5bfe61 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -44,6 +44,27 @@ markup_subparser_LDADD    = $(progs_ldadd)
 TEST_PROGS         += array-test
 array_test_LDADD    = $(progs_ldadd)
 
+TEST_PROGS     += gvariant-big
+gvariant_big_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-endian
+gvariant_endian_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-fuzz
+gvariant_fuzz_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-markup
+gvariant_markup_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-random
+gvariant_random_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-serialiser
+gvariant_serialiser_LDADD    = $(progs_ldadd)
+
+TEST_PROGS     += gvariant-varargs
+gvariant_varargs_LDADD    = $(progs_ldadd)
+
 if OS_UNIX
 
 # some testing of gtester funcitonality
diff --git a/glib/tests/gvariant-basic.c b/glib/tests/gvariant-basic.c
new file mode 100644
index 0000000..30eb063
--- /dev/null
+++ b/glib/tests/gvariant-basic.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright © 2008 Philip Van Hoof, Ryan Lortie
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#include <glib.h>
+
+static void
+test_int64 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gint64 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0xffffffffffffffff) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x7fffffffffffffff) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x0000000000000000) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(4242424242424242) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x0101010101010101) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x1010101010101010) },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      gint64 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+
+static void
+test_uint64 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    guint64 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0xffffffffffffffff) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x7fffffffffffffff) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x0000000000000000) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(4242424242424242) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x0101010101010101) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x1010101010101010) },  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      guint64 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+static void
+test_double (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gdouble value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_DOUBLE, 0.123 },
+    { (const char *) G_SIGNATURE_DOUBLE, 123 },
+    { (const char *) G_SIGNATURE_DOUBLE, 0.1234 },
+    { (const char *) G_SIGNATURE_DOUBLE, 1.5567 },
+    { (const char *) G_SIGNATURE_DOUBLE, 1.5563 },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      gdouble test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+static void
+test_int32 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gint32 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_INT32, 0xffffffff },
+    { (const char *) G_SIGNATURE_INT32, 0x7fffffff },
+    { (const char *) G_SIGNATURE_INT32, 0x00000000 },
+    { (const char *) G_SIGNATURE_INT32, 42424242 },
+    { (const char *) G_SIGNATURE_INT32, 0x01010101 },
+    { (const char *) G_SIGNATURE_INT32, 0x10101010 },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      gint32 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+
+static void
+test_uint32 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    guint32 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_UINT32, 0xffffffff },
+    { (const char *) G_SIGNATURE_UINT32, 0x7fffffff },
+    { (const char *) G_SIGNATURE_UINT32, 0x00000000 },
+    { (const char *) G_SIGNATURE_UINT32, 42424242 },
+    { (const char *) G_SIGNATURE_UINT32, 0x01010101 },
+    { (const char *) G_SIGNATURE_UINT32, 0x10101010 },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      guint32 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+static void
+test_int16 (void)
+{
+  int i;
+  gint16 b;
+
+  for (b = 0xffff; b < 0x7fff; b++)
+    {
+      GVariant *variant = g_variant_new ((const char *) G_SIGNATURE_INT16, b);
+      gint16 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_INT16, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+
+static void
+test_uint16 (void)
+{
+  int i;
+  guint16 b;
+
+  for (b = 0xffff; b < 0x7fff; b++)
+    {
+      GVariant *variant = g_variant_new ((const char *) G_SIGNATURE_UINT16, b);
+      guint16 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_UINT16, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+static void
+test_byte (void)
+{
+  int i;
+  guint8 b;
+
+  for (b = 0; b < 255; b++)
+    {
+      GVariant *variant = g_variant_new ((const char *) G_SIGNATURE_BYTE, b);
+      guint8 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_BYTE, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+
+static void
+test_string (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    const char *value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_STRING, "" },
+    { (const char *) G_SIGNATURE_STRING, "the anti string" },
+    { (const char *) G_SIGNATURE_STRING, "<xml attr=\"test\"><![CDATA[ abdbdb\n\n%&*@&#\n]]></xml>" },
+    { (const char *) G_SIGNATURE_STRING, "I do, I in fact , I insist" },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      char* test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpstr (test, ==, values[i].value);
+      g_free (test);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+static void
+test_boolean (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gboolean value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_BOOLEAN, TRUE },
+    { (const char *) G_SIGNATURE_BOOLEAN, FALSE },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new (values[i].type, values[i].value);
+      gboolean test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+
+  return;
+}
+
+int
+main (int argc, char **argv)
+{
+  guint limit = 1000;
+  int i;
+
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/variant/basic/boolean", test_boolean);
+  g_test_add_func ("/variant/basic/string", test_string);
+  g_test_add_func ("/variant/basic/byte", test_byte);
+  g_test_add_func ("/variant/basic/uint16", test_uint16);
+  g_test_add_func ("/variant/basic/int16", test_int16);
+  g_test_add_func ("/variant/basic/int32", test_int32);
+  g_test_add_func ("/variant/basic/uint32", test_int32);
+  g_test_add_func ("/variant/basic/double", test_double);
+  g_test_add_func ("/variant/basic/int64", test_int64);
+  g_test_add_func ("/variant/basic/uint64", test_uint64);
+
+  return g_test_run ();
+}
+
diff --git a/glib/tests/gvariant-big.c b/glib/tests/gvariant-big.c
new file mode 100644
index 0000000..3bc1e7c
--- /dev/null
+++ b/glib/tests/gvariant-big.c
@@ -0,0 +1,217 @@
+#include <glib.h>
+
+gdouble
+ieee754ify (gdouble floating)
+{
+  volatile double value = floating;
+  return value;
+}
+
+static const gchar *
+random_string (GRand *rand)
+{
+  static char string[512];
+  int i = 0;
+
+  do
+    string[i] = g_rand_int_range (rand, 0, 128);
+  while (string[i++] != '\0' && i < 512);
+
+  string[511] = '\0';
+
+  return string;
+}
+
+static void
+verify2 (GVariant *value,
+         GRand    *rand)
+{
+  gsize length = g_rand_int_range (rand, 1, 100000);
+  const gchar *possible = "ybquds";
+  const GVariantType *type;
+  GVariantTypeClass class;
+  GVariantIter iter;
+  GVariant *child;
+  gsize actual;
+
+  type = (const GVariantType *) (possible + g_rand_int_range (rand, 0, 6));
+  class = g_variant_type_get_class (type);
+
+  actual = g_variant_iter_init (&iter, value);
+  g_assert_cmpint (actual, ==, length);
+
+  actual = 0;
+  while ((child = g_variant_iter_next (&iter)))
+    {
+      switch (class)
+        {
+          case G_VARIANT_TYPE_CLASS_BOOLEAN:
+            g_assert_cmpint (g_variant_get_boolean (child), ==,
+                             g_rand_int_range (rand, 0, 1));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_BYTE:
+            g_assert_cmpint (g_variant_get_byte (child), ==,
+                             g_rand_int_range (rand, 0, 256));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_UINT16:
+            g_assert_cmpint (g_variant_get_uint16 (child), ==,
+                             g_rand_int_range (rand, 0, 65536));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_UINT32:
+            g_assert_cmpint (g_variant_get_uint32 (child), ==,
+                             g_rand_int (rand));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_DOUBLE:
+            g_assert_cmpfloat (g_variant_get_double (child), ==,
+                               ieee754ify (g_rand_double (rand)));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_STRING:
+            g_assert_cmpstr (g_variant_get_string (child, NULL), ==,
+                             random_string (rand));
+            break;
+            
+          default:
+            g_assert_not_reached ();
+        }
+      actual++;
+    }
+
+  g_assert_cmpint (actual, ==, length);
+  g_variant_unref (value);
+}
+
+
+static GVariant *
+generate2 (GRand *rand)
+{
+  gsize length = g_rand_int_range (rand, 1, 100000);
+  const gchar *possible = "ybquds";
+  const GVariantType *type;
+  GVariantTypeClass class;
+  GVariantBuilder *builder;
+  gsize i;
+
+  type = (const GVariantType *) (possible + g_rand_int_range (rand, 0, 6));
+  class = g_variant_type_get_class (type);
+
+  builder = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY, NULL);
+  for (i = 0; i < length; i++)
+    {
+      switch (class)
+        {
+          case G_VARIANT_TYPE_CLASS_BOOLEAN:
+            g_variant_builder_add (builder, "b",
+                                   g_rand_int_range (rand, 0, 1));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_BYTE:
+            g_variant_builder_add (builder, "y",
+                                   g_rand_int_range (rand, 0, 256));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_UINT16:
+            g_variant_builder_add (builder, "q",
+                                   g_rand_int_range (rand, 0, 65536));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_UINT32:
+            g_variant_builder_add (builder, "u", g_rand_int (rand));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_DOUBLE:
+            g_variant_builder_add (builder, "d", g_rand_double (rand));
+            break;
+
+          case G_VARIANT_TYPE_CLASS_STRING:
+            g_variant_builder_add (builder, "s", random_string (rand));
+            break;
+            
+          default:
+            g_assert_not_reached ();
+        }
+    }
+
+  return g_variant_new_variant (g_variant_builder_end (builder));
+}
+
+static GVariant *
+generate (GRand *rand)
+{
+  gsize length = g_rand_int_range (rand, 0, 20);
+  GVariantBuilder *builder;
+  gsize i;
+
+  builder = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY,
+                                   G_VARIANT_TYPE ("av"));
+
+  /* length will fall into 0, 0..255, 256..65535, and >65536 ranges */
+  for (i = 0; i < length; i++)
+    g_variant_builder_add_value (builder, generate2 (rand));
+
+  return g_variant_builder_end (builder);
+}
+
+static void
+verify (GVariant *value,
+        GRand    *rand)
+{
+  gsize length = g_rand_int_range (rand, 0, 20);
+  GVariantIter iter;
+  GVariant *child;
+  gsize actual;
+
+  actual = g_variant_iter_init (&iter, value);
+  g_assert_cmpint (actual, ==, length);
+  actual = 0;
+
+  while ((child = g_variant_iter_next (&iter)))
+    {
+      verify2 (g_variant_get_variant (child), rand);
+      actual++;
+    }
+
+  g_assert_cmpint (actual, ==, length);
+}
+
+static void
+test (void)
+{
+  GRand *one, *two;
+  GVariant *value;
+  guint32 seed;
+
+  seed = g_test_rand_int ();
+  one = g_rand_new_with_seed (seed);
+  two = g_rand_new_with_seed (seed);
+
+  {
+    GVariant *test_double = g_variant_new_double (g_rand_double (one));
+    g_assert_cmpfloat (ieee754ify (g_rand_double (two)), ==,
+                       g_variant_get_double (test_double));
+    g_variant_unref (test_double);
+  }
+
+  value = generate (one);
+  g_rand_free (one);
+
+  g_variant_flatten (value);
+
+  verify (value, two);
+  g_rand_free (two);
+
+  g_variant_unref (value);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/gvariant/big", test);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-complex.c b/glib/tests/gvariant-complex.c
new file mode 100644
index 0000000..f57669f
--- /dev/null
+++ b/glib/tests/gvariant-complex.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2008 Philip Van Hoof, Ryan Lortie
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#include <glib.h>
+
+static void
+test_s_ii_v (void)
+{
+  GVariant *t, *variant;
+  gchar *s;
+  gint i1,i2;
+  gboolean mybool;
+
+  variant = g_variant_new ("(s(ii)v)",
+                           "Hello World", 800, 600,
+                           g_variant_new_boolean (TRUE));
+
+  g_variant_get (variant, "(s(ii)v)", &s, &i1, &i2, &t);
+
+  g_variant_get (t, "b", &mybool);
+  g_assert_cmpint (mybool, ==, TRUE);
+  g_variant_unref (t);
+
+  g_assert_cmpstr (s, ==, "Hello World");
+  g_assert_cmpint (i1, ==, 800);
+  g_assert_cmpint (i2, ==, 600);
+  g_free (s);
+
+  g_variant_unref (variant);
+}
+
+static void
+test_a_si (void)
+{
+  gchar *szero = NULL, *sone = NULL, *stwo = NULL, *sextra = NULL;
+  gint zero, one, two, extra, len;
+  GVariantIter iter;
+  GVariant *variant;
+  GVariant *array;
+
+  variant = g_variant_new ("(a{si}s)",
+                           3,
+                             "zero", 0,
+                             "one",  1,
+                             "two",  2,
+                           "");
+
+  array = g_variant_get_child (variant, 0);
+  len = g_variant_iter_init (&iter, array);
+  g_variant_unref (variant);
+
+  g_assert_cmpint (len, ==, 3);
+
+  g_variant_iterate (&iter, "{si}", &szero, &zero);
+  g_variant_iterate (&iter, "{si}", &sone, &one);
+  g_variant_iterate (&iter, "{si}", &stwo, &two);
+
+  g_assert (g_variant_iterate (&iter, "si", &sextra, &extra) == FALSE);
+
+  g_assert_cmpstr (szero, ==, "zero");
+  g_assert_cmpint (zero, ==, 0);
+
+  g_assert_cmpstr (sone, ==, "one");
+  g_assert_cmpint (one, ==, 1);
+
+  g_assert_cmpstr (stwo, ==, "two");
+  g_assert_cmpint (two, ==, 2);
+
+  g_variant_unref (array);
+  g_free (szero);
+  g_free (sone);
+  g_free (stwo);
+}
+
+static void
+test_s_vvvv_v (void)
+{
+  GVariant *variant;
+  guint16 myuint16;
+  gboolean myboolean;
+  gchar *mystring, *s;
+  guint8 mymaxbyte, myminbyte;
+  GVariant *t1, *t2, *t3, *t4, *t5;
+
+  variant = g_variant_new ("(s(vvvv)v)",
+                           "Crack example",
+                           g_variant_new_boolean (TRUE),
+                           g_variant_new_string ("abc"),
+                           g_variant_new_uint16 (0xfff3),
+                           g_variant_new_byte (255),
+                           g_variant_new_byte (0));
+
+  g_variant_get (variant, "(s(vvvv)v)", &s,
+                 &t1, &t2, &t3, &t4, &t5);
+
+  g_variant_get (t1, (const char *) G_SIGNATURE_BOOLEAN, &myboolean);
+  g_variant_get (t2, (const char *) G_SIGNATURE_STRING, &mystring);
+  g_variant_get (t3, (const char *) G_SIGNATURE_UINT16, &myuint16);
+  g_variant_get (t4, (const char *) G_SIGNATURE_BYTE, &mymaxbyte);
+  g_variant_get (t5, (const char *) G_SIGNATURE_BYTE, &myminbyte);
+
+  g_assert_cmpstr (s, ==, "Crack example");
+  g_assert_cmpint (myboolean, ==, TRUE);
+  g_assert_cmpstr (mystring, ==, "abc");
+  g_assert_cmpint (myuint16, ==, 0xfff3);
+  g_assert_cmpint (mymaxbyte, ==, 255);
+  g_assert_cmpint (myminbyte, ==, 0);
+
+  g_variant_unref (variant);
+  g_variant_unref (t1);
+  g_variant_unref (t2);
+  g_variant_unref (t3);
+  g_variant_unref (t4);
+  g_variant_unref (t5);
+  g_free (mystring);
+  g_free (s);
+}
+
+static void
+test_vvvv (void)
+{
+  guint16 myuint16;
+  gboolean myboolean;
+  gchar *mystring;
+  guint8 mymaxbyte, myminbyte;
+  GVariant *t1, *t2, *t3, *t4;
+  GVariant *variant;
+
+  variant = g_variant_new ("(vvvv)",
+                           g_variant_new_boolean (TRUE),
+                           g_variant_new_string ("abc"),
+                           g_variant_new_uint16 (0xfff3),
+                           g_variant_new_byte (255));
+
+  g_variant_get (variant, "(vvvv)",
+                 &t1, &t2, &t3, &t4);
+
+  g_variant_get (t1, (const char *) G_SIGNATURE_BOOLEAN, &myboolean);
+  g_variant_get (t2, (const char *) G_SIGNATURE_STRING, &mystring);
+  g_variant_get (t3, (const char *) G_SIGNATURE_UINT16, &myuint16);
+  g_variant_get (t4, (const char *) G_SIGNATURE_BYTE, &mymaxbyte);
+
+  g_assert_cmpint (myboolean, ==, TRUE);
+  g_assert_cmpstr (mystring, ==, "abc");
+  g_assert_cmpint (myuint16, ==, 0xfff3);
+  g_assert_cmpint (mymaxbyte, ==, 255);
+
+  g_variant_unref (variant);
+  g_variant_unref (t1);
+  g_variant_unref (t2);
+  g_variant_unref (t3);
+  g_variant_unref (t4);
+  g_free (mystring);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/variant/complex/s(ii)v", test_s_ii_v);
+  g_test_add_func ("/variant/complex/vvvv", test_vvvv);
+
+  g_test_add_func ("/variant/complex/a{si}", test_a_si);
+  g_test_add_func ("/variant/complex/s(vvvv)v", test_s_vvvv_v);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-constructors.c b/glib/tests/gvariant-constructors.c
new file mode 100644
index 0000000..e5ad24a
--- /dev/null
+++ b/glib/tests/gvariant-constructors.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright © 2008 Philip Van Hoof, Ryan Lortie
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#include <glib.h>
+
+static void
+test_int64 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gint64 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0xffffffffffffffff) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x7fffffffffffffff) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x0000000000000000) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(4242424242424242) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x0101010101010101) },
+    { (const char *) G_SIGNATURE_INT64, G_GINT64_CONSTANT(0x1010101010101010) },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_int64 (values[i].value);
+      gint64 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+
+static void
+test_uint64 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    guint64 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0xffffffffffffffff) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x7fffffffffffffff) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x0000000000000000) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(4242424242424242) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x0101010101010101) },
+    { (const char *) G_SIGNATURE_UINT64, G_GUINT64_CONSTANT(0x1010101010101010) },  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_uint64 (values[i].value);
+      guint64 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+static void
+test_double (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gdouble value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_DOUBLE, 0.123 },
+    { (const char *) G_SIGNATURE_DOUBLE, 123 },
+    { (const char *) G_SIGNATURE_DOUBLE, 0.1234 },
+    { (const char *) G_SIGNATURE_DOUBLE, 1.5567 },
+    { (const char *) G_SIGNATURE_DOUBLE, 1.5563 },
+    { (const char *) G_SIGNATURE_DOUBLE, 0. / 0. },
+    { (const char *) G_SIGNATURE_DOUBLE, 1. / 0. },
+    { (const char *) G_SIGNATURE_DOUBLE, -1. / 0. },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_double (values[i].value);
+      gdouble test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+static void
+test_int32 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gint32 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_INT32, 0xffffffff },
+    { (const char *) G_SIGNATURE_INT32, 0x7fffffff },
+    { (const char *) G_SIGNATURE_INT32, 0x00000000 },
+    { (const char *) G_SIGNATURE_INT32, 42424242 },
+    { (const char *) G_SIGNATURE_INT32, 0x01010101 },
+    { (const char *) G_SIGNATURE_INT32, 0x10101010 },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_int32 (values[i].value);
+      gint32 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+
+static void
+test_uint32 (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    guint32 value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_UINT32, 0xffffffff },
+    { (const char *) G_SIGNATURE_UINT32, 0x7fffffff },
+    { (const char *) G_SIGNATURE_UINT32, 0x00000000 },
+    { (const char *) G_SIGNATURE_UINT32, 42424242 },
+    { (const char *) G_SIGNATURE_UINT32, 0x01010101 },
+    { (const char *) G_SIGNATURE_UINT32, 0x10101010 },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_uint32 (values[i].value);
+      guint32 test;
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+static void
+test_int16 (void)
+{
+  int i;
+  gint16 b;
+
+  for (b = 0xffff; b < 0x7fff; b++)
+    {
+      GVariant *variant = g_variant_new_int16 (b);
+      gint16 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_INT16, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+}
+
+
+static void
+test_uint16 (void)
+{
+  int i;
+  guint16 b;
+
+  for (b = 0xffff; b < 0x7fff; b++)
+    {
+      GVariant *variant = g_variant_new_uint16 (b);
+      guint16 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_UINT16, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+}
+
+static void
+test_byte (void)
+{
+  int i;
+  guint8 b;
+
+  for (b = 0; b < 255; b++)
+    {
+      GVariant *variant = g_variant_new_byte (b);
+      guint8 test;
+      g_variant_get (variant, (const char *) G_SIGNATURE_BYTE, &test);
+
+      g_assert_cmpint (test, ==, b);
+
+      g_variant_unref (variant);
+    }
+}
+
+
+static void
+test_string (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    const char *value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_STRING, "" },
+    { (const char *) G_SIGNATURE_STRING, "the anti string" },
+    { (const char *) G_SIGNATURE_STRING, "<xml attr=\"test\"><![CDATA[ abdbdb\n\n%&*@&#\n]]></xml>" },
+    { (const char *) G_SIGNATURE_STRING, "I do, I in fact , I insist" },
+    { (const char *) G_SIGNATURE_STRING, "%s %d %s %*.*s printf, anyone?" },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_string (values[i].value);
+      char *test;
+
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpstr (test, ==, values[i].value);
+      g_free (test);
+
+      g_variant_unref (variant);
+    }
+}
+
+static void
+test_boolean (void)
+{
+  int i;
+
+  static struct
+  {
+    const char *type;
+    gboolean value;
+  } values[] = {
+    { (const char *) G_SIGNATURE_BOOLEAN, TRUE },
+    { (const char *) G_SIGNATURE_BOOLEAN, FALSE },
+  };
+
+  for (i = 0; i < G_N_ELEMENTS (values); i++)
+    {
+      GVariant *variant = g_variant_new_boolean (values[i].value);
+      gboolean test;
+
+      g_variant_get (variant, values[i].type, &test);
+
+      g_assert_cmpint (test, ==, values[i].value);
+
+      g_variant_unref (variant);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/variant/basic/boolean", test_boolean);
+  g_test_add_func ("/variant/basic/string", test_string);
+  g_test_add_func ("/variant/basic/byte", test_byte);
+  g_test_add_func ("/variant/basic/uint16", test_uint16);
+  g_test_add_func ("/variant/basic/int16", test_int16);
+  g_test_add_func ("/variant/basic/int32", test_int32);
+  g_test_add_func ("/variant/basic/uint32", test_int32);
+  g_test_add_func ("/variant/basic/double", test_double);
+  g_test_add_func ("/variant/basic/int64", test_int64);
+  g_test_add_func ("/variant/basic/uint64", test_uint64);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-endian.c b/glib/tests/gvariant-endian.c
new file mode 100644
index 0000000..6101349
--- /dev/null
+++ b/glib/tests/gvariant-endian.c
@@ -0,0 +1,32 @@
+#include <glib.h>
+
+static void
+test_byteswap (void)
+{
+  const guchar data[] = {
+    0, 0, 0, 0, 0, 0, 0, 8,
+    0, 0, 0, 1,
+    0, 2,
+    1,
+    0,
+    '\0', '(', 't', 'u', 'q', 'y', 'b', ')'
+  };
+  GVariant *value;
+  GString *string;
+
+  value = g_variant_load (NULL, data, sizeof data,
+                          G_BIG_ENDIAN | G_VARIANT_LAZY_BYTESWAP);
+  string = g_variant_markup_print (value, NULL, FALSE, 0, 0);
+  g_variant_unref (value);
+
+  g_assert_cmpstr (string->str, ==, "<struct><uint64>8</uint64><uint32>1</uint32><uint16>2</uint16><byte>0x01</byte><false/></struct>");
+  g_string_free (string, TRUE);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/gvariant/endian/0", test_byteswap);
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-fuzz.c b/glib/tests/gvariant-fuzz.c
new file mode 100644
index 0000000..df45988
--- /dev/null
+++ b/glib/tests/gvariant-fuzz.c
@@ -0,0 +1,428 @@
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <string.h>
+
+#define TESTS                     10000
+#define MAXIMUM_DEPTH             5
+#define MAXIMUM_ARRAY_SIZE        8
+#define MAXIMUM_STRUCT_SIZE       8
+/* the probability of an empty array/struct */
+#define PROBABILITY_OF_NOTHING    0.1
+#define PROBABILITY_OF_BASIC_TYPE 0.3
+/* log base 2 of maximum string length */
+#define LOG_2_MAXIMUM_STRING_SIZE 8
+
+/* change these only when protocol changes */
+#define NUMBER_OF_BASIC_TYPES     9
+#define NUMBER_OF_CONTAINER_TYPES 5
+
+static void         random_signature             (GString *signature,
+                                                  int      depth);
+static gchar       *random_string                (void);
+static const gchar *next_type_in_signature       (const gchar *sig);
+static const gchar *random_markup_from_signature (GString     *markup,
+                                                  const gchar *signature,
+                                                  int          depth);
+static void         random_markup                (GString *markup,
+                                                  int      depth);
+
+static void
+random_signature (GString *signature,
+                  int      depth)
+{
+  if (!depth || g_test_rand_double_range (0, 1) < PROBABILITY_OF_BASIC_TYPE)
+    {
+      const gchar *c = "ybnqiuxts";
+      int i = g_test_rand_int_range (0, NUMBER_OF_BASIC_TYPES);
+      g_string_append_c (signature, c[i]);
+    }
+  else
+    {
+      switch (g_test_rand_int_range (0, NUMBER_OF_CONTAINER_TYPES))
+        {
+          case 0:
+            g_string_append_c (signature, 'a');
+            random_signature (signature, depth - 1);
+            break;
+
+          case 1:
+            g_string_append_c (signature, '(');
+
+            if (g_test_rand_double_range (0, 1) >= PROBABILITY_OF_NOTHING)
+              {
+                int size = g_test_rand_int_range (1, MAXIMUM_STRUCT_SIZE + 1);
+
+                while (size--)
+                  random_signature (signature, depth - 1);
+              }
+
+            g_string_append_c (signature, ')');
+            break;
+
+          case 2:
+            g_string_append_c (signature, 'v');
+            break;
+
+          case 3:
+            g_string_append_c (signature, '{');
+            random_signature (signature, 0);
+            random_signature (signature, depth - 1);
+            g_string_append_c (signature, '}');
+            break;
+
+          case 4:
+            g_string_append_c (signature, 'm');
+            random_signature (signature, depth - 1);
+            break;
+        }
+    }
+}
+
+static gchar *
+random_string (void)
+{
+  gchar str[1 << LOG_2_MAXIMUM_STRING_SIZE];
+  int   size;
+  int   i;
+
+  size = 1 << g_test_rand_int_range (0, LOG_2_MAXIMUM_STRING_SIZE);
+  size += g_test_rand_int_range (-1, size - 1);
+
+  for (i = 0; i < size; i++)
+    str[i] = (gchar) g_test_rand_int_range (' ', '~' + 1);
+
+  return g_markup_escape_text (str, size);
+}
+
+static const gchar *
+next_type_in_signature (const gchar *sig)
+{
+  while (*sig == 'a' || *sig == 'm')
+    sig++;
+
+  if (*sig == '(' || *sig == '{')
+    for (sig++; *sig != ')' && *sig != '}';
+         sig = next_type_in_signature (sig));
+
+  return sig + 1;
+}
+
+static const gchar *
+random_markup_from_signature (GString     *markup,
+                              const gchar *signature,
+                              int          depth)
+{
+  switch (*signature)
+    {
+      case 'y':
+        g_string_append_printf (markup,
+                                "<byte>0x%02x</byte>",
+                                (guint8) g_test_rand_int ());
+        return signature + 1;
+
+      case 'b':
+        g_string_append_printf (markup,
+                                "<%s/>",
+                                g_test_rand_bit () ? "true" : "false");
+        return signature + 1;
+
+      case 'n':
+        g_string_append_printf (markup,
+                                "<int16>%d</int16>",
+                                (gint16) g_test_rand_int ());
+        return signature + 1;
+
+      case 'q':
+        g_string_append_printf (markup,
+                                "<uint16>%u</uint16>",
+                                (guint16) g_test_rand_int ());
+        return signature + 1;
+
+      case 'i':
+        g_string_append_printf (markup,
+                                "<int32>%d</int32>",
+                                (gint32) g_test_rand_int ());
+        return signature + 1;
+
+      case 'u':
+        g_string_append_printf (markup,
+                                "<uint32>%u</uint32>",
+                                (guint32) g_test_rand_int ());
+        return signature + 1;
+
+      case 'x':
+        g_string_append_printf (markup,
+                                "<int64>%d</int64>",
+                                g_test_rand_int ());
+        return signature + 1;
+
+      case 't':
+        g_string_append_printf (markup,
+                                "<uint64>%u</uint64>",
+                                g_test_rand_int ());
+        return signature + 1;
+
+      case 'd':
+        g_string_append_printf (markup,
+                                "<double>%lf</double>",
+                                g_test_rand_double ());
+        return signature + 1;
+
+      case 's':
+        {
+          gchar *escaped = random_string ();
+
+          g_string_append_printf (markup,
+                                  "<string>%s</string>",
+                                  escaped);
+
+          g_free (escaped);
+          return signature + 1;
+        }
+
+      case 'a':
+        if (g_test_rand_double_range (0, 1) >= PROBABILITY_OF_NOTHING)
+          {
+            const gchar *next = NULL;
+            int size;
+
+            g_string_append (markup, "<array>");
+
+            for (size = g_test_rand_int_range (1, MAXIMUM_ARRAY_SIZE + 1);
+                 size--;
+                 next = random_markup_from_signature (markup,
+                                                      signature + 1,
+                                                      depth - 1));
+
+            signature = next;
+
+            g_string_append (markup, "</array>");
+          }
+        else
+          {
+            const gchar *next = next_type_in_signature (signature);
+
+            g_string_append (markup, "<array type='");
+            g_string_append_len (markup, signature, next - signature);
+            g_string_append (markup, "'/>");
+
+            signature = next;
+          }
+
+        return signature;
+
+      case '(':
+        if (*++signature == ')')
+          g_string_append (markup, "<triv/>");
+        else
+          {
+            g_string_append (markup, "<struct>");
+
+            for (;
+                 *signature != ')';
+                 signature = random_markup_from_signature (markup,
+                                                           signature,
+                                                           depth - 1));
+
+            g_string_append (markup, "</struct>");
+          }
+
+        return signature + 1;
+
+      case 'v':
+        g_string_append (markup, "<variant>");
+        random_markup (markup, depth - 1);
+        g_string_append (markup, "</variant>");
+        return signature + 1;
+
+      case '{':
+        g_string_append (markup, "<dictionary-entry>");
+
+        for (signature++;
+             *signature != '}';
+             signature = random_markup_from_signature (markup,
+                                                       signature,
+                                                       depth - 1));
+
+        g_string_append (markup, "</dictionary-entry>");
+        return signature + 1;
+
+      case 'm':
+        if (g_test_rand_bit ())
+          {
+            g_string_append (markup, "<maybe>");
+
+            signature = random_markup_from_signature (markup,
+                                                      signature + 1,
+                                                      depth - 1);
+
+            g_string_append (markup, "</maybe>");
+          }
+        else
+          {
+            const gchar *next = next_type_in_signature (signature);
+
+            g_string_append (markup, "<nothing type='");
+            g_string_append_len (markup, signature, next - signature);
+            g_string_append (markup, "'/>");
+
+            signature = next;
+          }
+
+        return signature;
+
+      default:
+        g_assert_not_reached ();
+    }
+}
+
+static void
+random_markup (GString *markup,
+               int      depth)
+{
+  GString *signature = g_string_new ("");
+
+  random_signature (signature, depth);
+  random_markup_from_signature (markup, signature->str, depth);
+  /* g_message ("%s", signature->str); */
+
+  g_string_free (signature, TRUE);
+}
+
+static void
+fuzz (guchar  *data,
+      gsize    length,
+      gdouble  fuzziness)
+{
+  gboolean have_fuzz = FALSE;
+  gsize i;
+
+  g_assert (length > 0);
+
+  for (i = 0; i < length; i++)
+    if (g_test_rand_double () < fuzziness)
+      {
+        guchar new = g_test_rand_int_range (0, 255);
+
+        if (new >= data[i])
+          new++;
+
+        data[i] = new;
+
+        have_fuzz = TRUE;
+      }
+
+  if (!have_fuzz)
+    data[0]++;
+}
+
+gboolean g_variant_is_normal_ (GVariant *);
+
+static void
+fuzz_iteration (gdouble fuzziness)
+{
+  GError *error = NULL;
+  GVariant *value;
+  GString *markup;
+  gint depth;
+  gsize size;
+
+  markup = g_string_new ("");
+  depth = g_test_rand_int_range (3, MAXIMUM_DEPTH);
+  random_markup (markup, depth);
+
+  value = g_variant_markup_parse (markup->str, markup->len, NULL, &error);
+  if (value == NULL)
+    g_error ("%s", error->message);
+
+  size = g_variant_get_size (value);
+
+  if (size)
+    {
+      const guchar *internal_data;
+      GVariant *fuzzed_value;
+      guchar *slice;
+     
+      slice = g_slice_alloc (size);
+      g_variant_store (value, slice);
+      internal_data = g_variant_get_data (value);
+
+      g_assert (memcmp (slice, internal_data, size) == 0);
+      fuzz (slice, size, fuzziness);
+      g_assert (memcmp (slice, internal_data, size) != 0);
+
+      fuzzed_value = g_variant_from_slice (g_variant_get_type (value),
+                                           slice, size, 0);
+
+      if (g_variant_is_normal_ (fuzzed_value))
+        {
+          GString *different;
+
+          different = g_variant_markup_print (fuzzed_value, NULL, 0, 0, 0);
+          g_assert_cmpstr (markup->str, !=, different->str);
+          g_string_free (different, TRUE);
+        }
+      else
+        {
+          GVariant *reconstructed;
+          GString *fuzzy_markup;
+
+          fuzzy_markup = g_variant_markup_print (fuzzed_value, NULL, 0, 0, 0);
+          reconstructed = g_variant_markup_parse (fuzzy_markup->str,
+                                                  -1, NULL, &error);
+
+          if (reconstructed == NULL)
+            g_error ("parsing reconstructed document '%s': %s\n",
+                     fuzzy_markup->str, error->message);
+
+          if (g_variant_get_size (reconstructed) == size)
+            {
+              const guchar *reconstructed_data;
+
+              reconstructed_data = g_variant_get_data (reconstructed);
+              g_assert (memcmp (reconstructed_data, slice, size) != 0);
+            }
+
+          g_string_free (fuzzy_markup, TRUE);
+          g_variant_unref (reconstructed);
+        }
+
+      g_variant_unref (fuzzed_value);
+    }
+
+  g_string_free (markup, TRUE);
+  g_variant_unref (value);
+}
+
+static void
+fuzz_test (gpointer data)
+{
+  gdouble fuzziness;
+  gint percent;
+  int i;
+
+  percent = GPOINTER_TO_INT (data);
+  fuzziness = percent / 100.0;
+
+  for (i = 0; i < TESTS; i++)
+    fuzz_iteration (fuzziness);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  int i;
+
+  g_test_init (&argc, &argv, NULL);
+
+  for (i = 1; i <= 20; i += 4)
+    {
+      char testname[80];
+
+      g_sprintf (testname, "/gvariant/fuzz/fuzziness/%d%%", i);
+      g_test_add_data_func (testname, GINT_TO_POINTER (i), (gpointer) fuzz_test);
+    }
+
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-markup.c b/glib/tests/gvariant-markup.c
new file mode 100644
index 0000000..16c9a2d
--- /dev/null
+++ b/glib/tests/gvariant-markup.c
@@ -0,0 +1,111 @@
+#include <glib.h>
+
+#define add_tests(func, basename, array) \
+  G_STMT_START { \
+    int __add_tests_i;                                                  \
+                                                                        \
+    for (__add_tests_i  = 0;                                            \
+         __add_tests_i < G_N_ELEMENTS (array);                          \
+         __add_tests_i++)                                               \
+      {                                                                 \
+        char *testname;                                                 \
+                                                                        \
+        testname = g_strdup_printf ("%s/%d", basename, __add_tests_i);  \
+        g_test_add_data_func (testname, array[__add_tests_i], func);    \
+        g_free (testname);                                              \
+      }                                                                 \
+  } G_STMT_END
+
+const char *verbatim_tests[] = {
+  "<array type='ai'/>",
+
+  "<struct>"
+    "<array>"
+      "<int32>1</int32>"
+      "<int32>2</int32>"
+      "<int32>3</int32>"
+    "</array>"
+    "<array>"
+      "<array type='aaai'/>"
+      "<array type='aaai'/>"
+      "<array type='aaai'/>"
+    "</array>"
+  "</struct>",
+
+  "<array>"
+    "<string>hello world</string>"
+    "<string>how &lt;are&gt; you</string>"
+    "<string> working -- i -- hope    </string>"
+    "<string>%s %d %s %d</string>"
+    "<string></string>"
+  "</array>",
+
+  "<array>"
+    "<array>"
+      "<string>foo</string>"
+    "</array>"
+    "<array type='as'/>"
+  "</array>",
+
+  "<maybe>"
+    "<struct>"
+      "<uint32>42</uint32>"
+      "<byte>0x42</byte>"
+      "<int32>-1</int32>"
+      "<double>37.500000</double>"
+      "<int64>-35383472451088536</int64>"
+      "<uint64>9446744073709551616</uint64>"
+    "</struct>"
+  "</maybe>",
+
+  "<struct>"
+    "<array>"
+      "<true/>"
+      "<false/>"
+      "<true/>"
+      "<true/>"
+      "<false/>"
+      "<false/>"
+      "<true/>"
+      "<true/>"
+    "</array>"
+    "<array>"
+      "<triv/>"
+      "<triv/>"
+    "</array>"
+  "</struct>"
+};
+
+static void
+check_verbatim (gconstpointer data)
+{
+  const char *markup = data;
+  GError *error = NULL;
+  GVariant *value;
+  GString *out;
+
+  value = g_variant_markup_parse (markup, -1, NULL, &error);
+
+  if (value == NULL)
+    {
+      g_assert (error != NULL);
+      g_error ("%s", error->message);
+    }
+  else
+    g_assert (error == NULL);
+
+  g_variant_flatten (value);
+
+  out = g_variant_markup_print (value, NULL, FALSE, 0, 0);
+  g_assert_cmpstr (markup, ==, out->str);
+  g_string_free (out, TRUE);
+  g_variant_unref (value);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+  add_tests (check_verbatim, "/gvariant/markup/verbatim", verbatim_tests);
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-random.c b/glib/tests/gvariant-random.c
new file mode 100644
index 0000000..c5414ab
--- /dev/null
+++ b/glib/tests/gvariant-random.c
@@ -0,0 +1,334 @@
+#include <glib.h>
+
+#define TESTS                     1024
+#define MAXIMUM_DEPTH             16
+#define MAXIMUM_ARRAY_SIZE        8
+#define MAXIMUM_STRUCT_SIZE       8
+/* the probability of an empty array/struct */
+#define PROBABILITY_OF_NOTHING    0.1
+#define PROBABILITY_OF_BASIC_TYPE 0.3
+/* log base 2 of maximum string length */
+#define LOG_2_MAXIMUM_STRING_SIZE 8
+
+/* change these only when protocol changes */
+#define NUMBER_OF_BASIC_TYPES     10
+#define NUMBER_OF_CONTAINER_TYPES 5
+
+static void         random_signature             (GString *signature,
+                                                  int      depth);
+static gchar       *random_string                (void);
+static const gchar *next_type_in_signature       (const gchar *sig);
+static const gchar *random_markup_from_signature (GString     *markup,
+                                                  const gchar *signature,
+                                                  int          depth);
+static void         random_markup                (GString *markup,
+                                                  int      depth);
+static void         test                         (void);
+
+static void
+random_signature (GString *signature,
+                  int      depth)
+{
+  if (!depth || g_test_rand_double_range (0, 1) < PROBABILITY_OF_BASIC_TYPE)
+    {
+      const gchar *c = "ybnqiuxtds";
+      int i = g_test_rand_int_range (0, NUMBER_OF_BASIC_TYPES);
+      g_string_append_c (signature, c[i]);
+    }
+  else
+    {
+      switch (g_test_rand_int_range (0, NUMBER_OF_CONTAINER_TYPES))
+        {
+          case 0:
+            g_string_append_c (signature, 'a');
+            random_signature (signature, depth - 1);
+            break;
+
+          case 1:
+            g_string_append_c (signature, '(');
+
+            if (g_test_rand_double_range (0, 1) >= PROBABILITY_OF_NOTHING)
+              {
+                int size = g_test_rand_int_range (1, MAXIMUM_STRUCT_SIZE + 1);
+
+                while (size--)
+                  random_signature (signature, depth - 1);
+              }
+
+            g_string_append_c (signature, ')');
+            break;
+
+          case 2:
+            g_string_append_c (signature, 'v');
+            break;
+
+          case 3:
+            g_string_append_c (signature, '{');
+            random_signature (signature, 0);
+            random_signature (signature, depth - 1);
+            g_string_append_c (signature, '}');
+            break;
+
+          case 4:
+            g_string_append_c (signature, 'm');
+            random_signature (signature, depth - 1);
+            break;
+        }
+    }
+}
+
+static gchar *
+random_string (void)
+{
+  gchar str[1 << LOG_2_MAXIMUM_STRING_SIZE];
+  int   size;
+  int   i;
+
+  size = 1 << g_test_rand_int_range (0, LOG_2_MAXIMUM_STRING_SIZE);
+  size += g_test_rand_int_range (-1, size - 1);
+
+  for (i = 0; i < size; i++)
+    str[i] = (gchar) g_test_rand_int_range (' ', '~' + 1);
+
+  return g_markup_escape_text (str, size);
+}
+
+static const gchar *
+next_type_in_signature (const gchar *sig)
+{
+  while (*sig == 'a' || *sig == 'm')
+    sig++;
+
+  if (*sig == '(' || *sig == '{')
+    for (sig++; *sig != ')' && *sig != '}';
+         sig = next_type_in_signature (sig));
+
+  return sig + 1;
+}
+
+static const gchar *
+random_markup_from_signature (GString     *markup,
+                              const gchar *signature,
+                              int          depth)
+{
+  switch (*signature)
+    {
+      case 'y':
+        g_string_append_printf (markup,
+                                "<byte>0x%02x</byte>",
+                                (guint8) g_test_rand_int ());
+        return signature + 1;
+
+      case 'b':
+        g_string_append_printf (markup,
+                                "<%s/>",
+                                g_test_rand_bit () ? "true" : "false");
+        return signature + 1;
+
+      case 'n':
+        g_string_append_printf (markup,
+                                "<int16>%d</int16>",
+                                (gint16) g_test_rand_int ());
+        return signature + 1;
+
+      case 'q':
+        g_string_append_printf (markup,
+                                "<uint16>%u</uint16>",
+                                (guint16) g_test_rand_int ());
+        return signature + 1;
+
+      case 'i':
+        g_string_append_printf (markup,
+                                "<int32>%d</int32>",
+                                (gint32) g_test_rand_int ());
+        return signature + 1;
+
+      case 'u':
+        g_string_append_printf (markup,
+                                "<uint32>%u</uint32>",
+                                (guint32) g_test_rand_int ());
+        return signature + 1;
+
+      case 'x':
+        g_string_append_printf (markup,
+                                "<int64>%d</int64>",
+                                g_test_rand_int ());
+        return signature + 1;
+
+      case 't':
+        g_string_append_printf (markup,
+                                "<uint64>%u</uint64>",
+                                g_test_rand_int ());
+        return signature + 1;
+
+      case 'd':
+        g_string_append_printf (markup,
+                                "<double>%lf</double>",
+                                g_test_rand_double ());
+        return signature + 1;
+
+      case 's':
+        {
+          gchar *escaped = random_string ();
+
+          g_string_append_printf (markup,
+                                  "<string>%s</string>",
+                                  escaped);
+
+          g_free (escaped);
+          return signature + 1;
+        }
+
+      case 'a':
+        if (g_test_rand_double_range (0, 1) >= PROBABILITY_OF_NOTHING)
+          {
+            const gchar *next = NULL;
+            int size;
+
+            g_string_append (markup, "<array>");
+
+            for (size = g_test_rand_int_range (1, MAXIMUM_ARRAY_SIZE + 1);
+                 size--;
+                 next = random_markup_from_signature (markup,
+                                                      signature + 1,
+                                                      depth - 1));
+
+            signature = next;
+
+            g_string_append (markup, "</array>");
+          }
+        else
+          {
+            const gchar *next = next_type_in_signature (signature);
+
+            g_string_append (markup, "<array type='");
+            g_string_append_len (markup, signature, next - signature);
+            g_string_append (markup, "'/>");
+
+            signature = next;
+          }
+
+        return signature;
+
+      case '(':
+        if (*++signature == ')')
+          g_string_append (markup, "<triv/>");
+        else
+          {
+            g_string_append (markup, "<struct>");
+
+            for (;
+                 *signature != ')';
+                 signature = random_markup_from_signature (markup,
+                                                           signature,
+                                                           depth - 1));
+
+            g_string_append (markup, "</struct>");
+          }
+
+        return signature + 1;
+
+      case 'v':
+        g_string_append (markup, "<variant>");
+        random_markup (markup, depth - 1);
+        g_string_append (markup, "</variant>");
+        return signature + 1;
+
+      case '{':
+        g_string_append (markup, "<dictionary-entry>");
+
+        for (signature++;
+             *signature != '}';
+             signature = random_markup_from_signature (markup,
+                                                       signature,
+                                                       depth - 1));
+
+        g_string_append (markup, "</dictionary-entry>");
+        return signature + 1;
+
+      case 'm':
+        if (g_test_rand_bit ())
+          {
+            g_string_append (markup, "<maybe>");
+
+            signature = random_markup_from_signature (markup,
+                                                      signature + 1,
+                                                      depth - 1);
+
+            g_string_append (markup, "</maybe>");
+          }
+        else
+          {
+            const gchar *next = next_type_in_signature (signature);
+
+            g_string_append (markup, "<nothing type='");
+            g_string_append_len (markup, signature, next - signature);
+            g_string_append (markup, "'/>");
+
+            signature = next;
+          }
+
+        return signature;
+
+      default:
+        g_assert_not_reached ();
+    }
+}
+
+static void
+random_markup (GString *markup,
+               int      depth)
+{
+  GString *signature = g_string_new ("");
+
+  random_signature (signature, depth);
+  random_markup_from_signature (markup, signature->str, depth);
+  /* g_message ("%s", signature->str); */
+
+  g_string_free (signature, TRUE);
+}
+
+static void
+test (void)
+{
+  GError   *error = NULL;
+  GString  *markup1;
+  GString  *markup2;
+  GVariant *variant;
+  int       depth;
+  int       i;
+
+  for (i = 0; i < TESTS; i++)
+    {
+      markup1 = g_string_new ("");
+      depth = g_test_rand_int_range (0, MAXIMUM_DEPTH);
+
+      random_markup (markup1, depth);
+      /* g_message ("%s", markup1->str); */
+      variant = g_variant_markup_parse (markup1->str, -1, NULL, &error);
+      g_variant_flatten (variant);
+
+      if (variant == NULL)
+        {
+          g_assert (error != NULL);
+          g_error ("%s", error->message);
+        }
+      else
+        g_assert (error == NULL);
+
+      markup2 = g_variant_markup_print (variant, NULL, FALSE, 0, 0);
+      g_assert_cmpstr (markup1->str, ==, markup2->str);
+      g_string_free (markup1, TRUE);
+      g_string_free (markup2, TRUE);
+      g_variant_unref (variant);
+    }
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/gvariant/random/0", test);
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-serialiser.c b/glib/tests/gvariant-serialiser.c
new file mode 100644
index 0000000..858c025
--- /dev/null
+++ b/glib/tests/gvariant-serialiser.c
@@ -0,0 +1,90 @@
+#include <glib.h>
+#include <stdio.h>
+
+#define add_tests(func, basename, array) \
+  G_STMT_START { \
+    int __add_tests_i;                                                  \
+                                                                        \
+    for (__add_tests_i  = 0;                                            \
+         __add_tests_i < G_N_ELEMENTS (array);                          \
+         __add_tests_i++)                                               \
+      {                                                                 \
+        char *testname;                                                 \
+                                                                        \
+        testname = g_strdup_printf ("%s/%d", basename, __add_tests_i);  \
+        g_test_add_data_func (testname, &array[__add_tests_i], func);   \
+        g_free (testname);                                              \
+      }                                                                 \
+  } G_STMT_END
+
+struct test_case
+{
+  const char *type;
+  int size;
+  const char *data;
+  const char *markup;
+};
+
+#define testcase(type, binary, markup) \
+  { type, sizeof binary - 1, binary, markup }
+
+struct test_case test_cases[] = {
+  testcase ("as", "foo\0bar\0se\0\x4\x8\xb",
+            "<array>"
+              "<string>foo</string>"
+              "<string>bar</string>"
+              "<string>se</string>"
+            "</array>"),
+  testcase ("(syus)", "str\0\xaa\0\0\0\x1\x1\x1\x1theend\0\x4",
+            "<struct>"
+              "<string>str</string>"
+              "<byte>0xaa</byte>"
+              "<uint32>16843009</uint32>"
+              "<string>theend</string>"
+            "</struct>"),
+  testcase ("a(sss)", "hello\0world\0gvariant\0\xc\x6" /*         0x17 */
+                      "this\0hopefully\0works\0\xf\x5" /* +0x17 = 0x2e */
+                      "k\0thx\0bye\0\x6\x2"            /* +0x0c = 0x3a */
+                      "\x17\x2e\x3a",
+            "<array>"
+              "<struct>"
+                "<string>hello</string>"
+                "<string>world</string>"
+                "<string>gvariant</string>"
+              "</struct>"
+              "<struct>"
+                "<string>this</string>"
+                "<string>hopefully</string>"
+                "<string>works</string>"
+              "</struct>"
+              "<struct>"
+                "<string>k</string>"
+                "<string>thx</string>"
+                "<string>bye</string>"
+              "</struct>"
+            "</array>")
+
+};
+
+void
+test (gconstpointer data)
+{
+  const struct test_case *tc = data;
+  GVariant *variant;
+  GString *markup;
+
+  variant = g_variant_load (G_VARIANT_TYPE (tc->type), tc->data, tc->size, 0);
+  markup = g_variant_markup_print (variant, NULL, FALSE, 0, 0);
+  g_variant_unref (variant);
+
+  g_assert_cmpstr (tc->markup, ==, markup->str);
+  g_string_free (markup, TRUE);
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+  add_tests (test, "/gvariant/serialiser", test_cases);
+  return g_test_run ();
+}
diff --git a/glib/tests/gvariant-varargs.c b/glib/tests/gvariant-varargs.c
new file mode 100644
index 0000000..318d91b
--- /dev/null
+++ b/glib/tests/gvariant-varargs.c
@@ -0,0 +1,289 @@
+#include <glib.h>
+
+struct structure
+{
+  guchar boolean;
+  guint16 uint16;
+  guint32 uint32;
+  guint64 uint64;
+  gdouble floating;
+};
+
+static GVariant *
+make_value (void)
+{
+  GVariantBuilder *array, *builder, *ebuilder1, *ebuilder2, *ebuilder3;
+  struct structure fixed_struct[] =
+  {
+    { FALSE, 16161, 3232323232u, 6464646464646464ull, 42.0 },
+    { FALSE, 16161, 3232323232u, 6464646464646464ull, 42.0 },
+    { FALSE, 16161, 3232323232u, 6464646464646464ull, 42.0 }
+  };
+
+  array = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY, NULL);
+
+  ebuilder1 = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY,
+                                     G_VARIANT_TYPE ("an"));
+  ebuilder2 = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY,
+                                     G_VARIANT_TYPE ("an"));
+  ebuilder3 = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY,
+                                     G_VARIANT_TYPE ("an"));
+  builder = g_variant_builder_new (G_VARIANT_TYPE_CLASS_ARRAY,
+                                   G_VARIANT_TYPE ("an"));
+  g_variant_builder_add (builder, "n", 234);
+
+  g_variant_builder_add (array, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                         "&a(bqutd)msmvm*m?m sm@*anmanm&(bqutd))",
+                         TRUE, 0x8c,
+                         TRUE, 0x1316, 0xccff, -344763333, 0xf77f5aa5,
+                         "crikey!!", g_variant_new_int32 (-11111111),
+                         G_GINT64_CONSTANT (0x123),
+                         G_GUINT64_CONSTANT (0xaabbccddeeff),
+                         1234.75,
+                         g_variant_new_uint16 (0xfcfb),
+                         g_variant_new_string ("i'm here"),
+                         g_variant_new_boolean (TRUE),
+                         g_variant_new_double (37.5),
+                         g_variant_new_object_path ("/usr/local"),
+                         g_variant_new ("()"),
+                         g_variant_new ("(bbb)", TRUE, FALSE, TRUE),
+                         fixed_struct, fixed_struct, (gsize) 3,
+                         "i'm gone",
+                         g_variant_new_uint16 (44444),
+                         g_variant_new_uint16 (22222),
+                         g_variant_new_int16 (-7777),
+                         g_variant_new_string ("this is getting insane"),
+                         g_variant_new_string ("ugh"),
+                         ebuilder1, builder, fixed_struct, 72727);
+
+  g_variant_builder_add (array, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                         "&a(bqutd)msmvm qm@nm sm@sanmanm&(bqutd))",
+                         TRUE, 0x8c,
+                         FALSE,
+                         G_GINT64_CONSTANT (0x123),
+                         G_GUINT64_CONSTANT (0xaabbccddeeff),
+                         1234.75,
+                         g_variant_new_uint16 (0xfcfb),
+                         g_variant_new_string ("i'm here"),
+                         g_variant_new_boolean (TRUE),
+                         g_variant_new_double (37.5),
+                         g_variant_new_object_path ("/usr/local"),
+                         g_variant_new ("()"),
+                         g_variant_new ("(bbb)", TRUE, FALSE, TRUE),
+                         fixed_struct, fixed_struct, (gsize) 3,
+                         NULL, NULL, NULL, NULL, NULL, NULL,
+                         ebuilder2, NULL, NULL);
+
+  g_variant_builder_add (array, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                         "&a(bqutd)msmvm qm@nm sm@sanmanm&(bqutd))",
+                         TRUE, 0x8c,
+                         FALSE,
+                         G_GINT64_CONSTANT (0x123),
+                         G_GUINT64_CONSTANT (0xaabbccddeeff),
+                         1234.75,
+                         g_variant_new_uint16 (0xfcfb),
+                         g_variant_new_string ("i'm here"),
+                         g_variant_new_boolean (TRUE),
+                         g_variant_new_double (37.5),
+                         g_variant_new_object_path ("/usr/local"),
+                         g_variant_new ("()"),
+                         g_variant_new ("(bbb)", TRUE, FALSE, TRUE),
+                         fixed_struct, fixed_struct, (gsize) 3,
+                         NULL, NULL, NULL, NULL, NULL, NULL,
+                         ebuilder3, NULL, NULL);
+
+  return g_variant_builder_end (array);
+}
+
+static void
+test_iterate (void)
+{
+  GVariant *maybe_one, *maybe_two, *maybe_three, *maybe_four, *maybe_five;
+  GVariant *one, *two, *three, *four, *five, *six, *seven = (gpointer) 0xcccccccc, *eight;
+  struct structure *fixed_array; gsize fixed_array_size;
+  struct structure *maybe_fixed_struct, *fixed_struct;
+  const gchar *string, *maybe_string;
+  GVariantIter maybe_array, array;
+  guchar byte; gboolean boolean;
+  guint16 uint16; gint16 int16;
+  guint32 uint32; gint32 int32;
+  guint64 uint64; gint64 int64;
+  gdouble floating;
+  gboolean is_just;
+
+  GVariantIter iter;
+  gboolean first;
+  gint count;
+
+  GVariant *value = make_value ();
+
+  g_variant_iter_init (&iter, value);
+  g_variant_unref (value);
+  first = TRUE;
+  count = 0;
+
+  while (g_variant_iterate (&iter, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                                   "&a(bqutd)msmvm*m?m sm@*anmanm&(bqutd))",
+                                   &boolean, &byte, /* by */
+
+                                   &is_just, &int16, &uint16, &int32,
+                                             &uint32, &string, &one,
+
+                                   &int64, &uint64, &floating, /* xtd */
+
+                                   &two, &three, &four, &five, &six, &seven,
+                                   &eight, /* ? s@?* *r@r */
+
+                                   &fixed_struct,
+                                   &fixed_array, &fixed_array_size,
+
+                                   &maybe_string, &maybe_one, &maybe_two,
+                                   &maybe_three, &maybe_four, &maybe_five,
+
+                                   &array, &maybe_array, &maybe_fixed_struct))
+    {
+      g_assert_cmpint (boolean, ==, TRUE);
+      g_assert_cmpint (byte, ==, 0x8c);
+      g_assert_cmpint (is_just, ==, first);
+
+      if (is_just)
+        {
+          g_assert_cmpint (int16, ==, 0x1316);
+          g_assert_cmpint (uint16, ==, 0xccff);
+          g_assert_cmpint (int32, ==, -344763333);
+          g_assert_cmpint (uint32, ==, 0xf77f5aa5);
+          g_assert_cmpstr (string, ==, "crikey!!");
+          g_assert_cmpint (g_variant_get_int32 (one), ==, -11111111);
+        }
+
+      g_assert (int64 == 0x123);
+      g_assert (uint64 == 0xaabbccddeeffull);
+      g_assert_cmpfloat (floating, ==, 1234.75);
+      
+      g_assert_cmpint (g_variant_get_uint16 (two), ==, 0xfcfb);
+      g_assert_cmpstr (g_variant_get_string (three, NULL), ==, "i'm here");
+      g_assert_cmpint (g_variant_get_boolean (four), ==, TRUE);
+      g_assert_cmpfloat (g_variant_get_double (five), ==, 37.5);
+      g_assert_cmpstr (g_variant_get_string (six, NULL), ==, "/usr/local");
+      g_assert_cmpint (g_variant_n_children (seven), ==, 0);
+      g_assert_cmpint (g_variant_n_children (eight), ==, 3);
+
+      g_assert_cmpint (fixed_struct->boolean, ==, FALSE);
+      g_assert_cmpint (fixed_struct->uint16, ==, 16161);
+      g_assert_cmpint (fixed_struct->uint32, ==, 3232323232u);
+      g_assert (fixed_struct->uint64 == 6464646464646464ull);
+      g_assert_cmpfloat (fixed_struct->floating, ==, 42.0);
+
+      g_assert_cmpint (fixed_array->boolean, ==, FALSE);
+      g_assert_cmpint (fixed_array->uint16, ==, 16161);
+      g_assert_cmpint (fixed_array->uint32, ==, 3232323232u);
+      g_assert (fixed_array->uint64 == 6464646464646464ull);
+      g_assert_cmpfloat (fixed_array->floating, ==, 42.0);
+
+      g_assert_cmpint (fixed_array_size, ==, 3);
+
+      g_assert_cmpint ((maybe_string != NULL), ==, first);
+      g_assert_cmpint ((maybe_one != NULL), ==, first);
+      g_assert_cmpint ((maybe_two != NULL), ==, first);
+      g_assert_cmpint ((maybe_three != NULL), ==, first);
+      g_assert_cmpint ((maybe_four != NULL), ==, first);
+      g_assert_cmpint ((maybe_five != NULL), ==, first);
+      g_assert_cmpint (g_variant_iter_was_cancelled (&array), ==, FALSE);
+      g_assert_cmpint (g_variant_iter_was_cancelled (&maybe_array), !=, first);
+      g_assert_cmpint ((maybe_fixed_struct != NULL), ==, first);
+
+      if (first)
+        {
+          g_assert_cmpstr (maybe_string, ==, "i'm gone");
+          g_assert_cmpint (g_variant_get_uint16 (maybe_one), ==, 44444);
+          g_assert_cmpint (g_variant_get_uint16 (maybe_two), ==, 22222);
+          g_assert_cmpint (g_variant_get_int16 (maybe_three), ==, -7777);
+          g_assert_cmpstr (g_variant_get_string (maybe_four, NULL),
+                           ==, "this is getting insane");
+          g_assert_cmpstr (g_variant_get_string (maybe_five, NULL),
+                           ==, "ugh");
+
+          g_assert_cmpint (maybe_fixed_struct->boolean, ==, FALSE);
+          g_assert_cmpint (maybe_fixed_struct->uint16, ==, 16161);
+          g_assert_cmpint (maybe_fixed_struct->uint32, ==, 3232323232u);
+          g_assert (maybe_fixed_struct->uint64 == 6464646464646464ull);
+          g_assert_cmpfloat (maybe_fixed_struct->floating, ==, 42.0);
+
+          /* access this once, but not the other time, to make sure
+           * freeing works in both cases */
+          g_assert (g_variant_iter_next (&array) == NULL);
+        }
+
+      first = FALSE;
+      count++;
+    }
+
+  g_assert_cmpint (count, ==, 3);
+}
+
+static void
+test_null (void)
+{
+  GVariant *value = make_value ();
+  GVariantIter iter;
+  gboolean is_just;
+  gboolean first;
+
+  g_variant_iter_init (&iter, value);
+  g_variant_unref (value);
+  first = TRUE;
+
+  while (g_variant_iterate (&iter, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                                   "&a(bqutd)msmvm*m?m sm@*anmanm&(bqutd))",
+                                   NULL, NULL,
+                                   &is_just, NULL, NULL, NULL,
+                                             NULL, NULL, NULL,
+                                   NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL))
+    {
+      g_assert_cmpint (is_just, ==, first);
+      first = FALSE;
+    }
+}
+
+static void
+test_totally_null (void)
+{
+  GVariant *value = make_value ();
+  GVariantIter iter;
+  gint count;
+
+  g_variant_iter_init (&iter, value);
+  g_variant_unref (value);
+  count = 0;
+
+  while (g_variant_iterate (&iter, "(bym(nquisv)xtd? s@?* *r@r&(bqutd)"
+                                   "&a(bqutd)msmvm*m?m sm@*anmanm&(bqutd))",
+                                   NULL, NULL,
+
+                                   NULL, /* skip the ones for the struct */
+
+                                   NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL))
+    count++;
+
+  g_assert_cmpint (count, ==, 3);
+}
+ 
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/gvariant/varargs/iterate", test_iterate);
+  g_test_add_func ("/gvariant/varargs/iterate/null", test_null);
+  g_test_add_func ("/gvariant/varargs/iterate/very-null", test_totally_null);
+
+  return g_test_run ();
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]