[glib/GVariantType] Add test case for GVariantType
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib/GVariantType] Add test case for GVariantType
- Date: Sat, 23 Jan 2010 00:22:30 +0000 (UTC)
commit b564db8c724358e7e5723b1017ceb8dfaee65c4a
Author: Ryan Lortie <desrt desrt ca>
Date: Fri Jan 22 19:20:57 2010 -0500
Add test case for GVariantType
glib/tests/.gitignore | 1 +
glib/tests/Makefile.am | 3 +
glib/tests/gvarianttype.c | 488 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 492 insertions(+), 0 deletions(-)
---
diff --git a/glib/tests/.gitignore b/glib/tests/.gitignore
index 76c25a8..7b02941 100644
--- a/glib/tests/.gitignore
+++ b/glib/tests/.gitignore
@@ -1,5 +1,6 @@
array-test
fileutils
+gvarianttype
hostutils
keyfile
markup-subparser
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index 673d338..3d3b8d4 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -47,6 +47,9 @@ array_test_LDADD = $(progs_ldadd)
TEST_PROGS += hostutils
hostutils_LDADD = $(progs_ldadd)
+TEST_PROGS += gvarianttype
+gvarianttype_LDADD = $(progs_ldadd)
+
if OS_UNIX
# some testing of gtester funcitonality
diff --git a/glib/tests/gvarianttype.c b/glib/tests/gvarianttype.c
new file mode 100644
index 0000000..dc71837
--- /dev/null
+++ b/glib/tests/gvarianttype.c
@@ -0,0 +1,488 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include <string.h>
+#include <glib.h>
+
+#define BASIC "bynqiuxthdsog?"
+#define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
+
+#define INVALIDS "cefjklpwz&@^$"
+#define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
+
+static gboolean
+randomly (gdouble prob)
+{
+ return g_test_rand_double_range (0, 1) < prob;
+}
+
+static GVariantType *
+append_type_string (GString *string,
+ GString *description,
+ gint depth)
+{
+ if (!depth-- || randomly (0.3))
+ {
+ gchar b = BASIC[g_test_rand_int_range (0, N_BASIC)];
+ g_string_append_c (string, b);
+ g_string_append_c (description, b);
+
+ switch (b)
+ {
+ case 'b':
+ return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
+ case 'y':
+ return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
+ case 'n':
+ return g_variant_type_copy (G_VARIANT_TYPE_INT16);
+ case 'q':
+ return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
+ case 'i':
+ return g_variant_type_copy (G_VARIANT_TYPE_INT32);
+ case 'u':
+ return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
+ case 'x':
+ return g_variant_type_copy (G_VARIANT_TYPE_INT64);
+ case 't':
+ return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
+ case 'h':
+ return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
+ case 'd':
+ return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
+ case 's':
+ return g_variant_type_copy (G_VARIANT_TYPE_STRING);
+ case 'o':
+ return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
+ case 'g':
+ return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
+ case '?':
+ return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
+ default:
+ g_assert_not_reached ();
+ }
+ }
+ else
+ {
+ GVariantType *result;
+
+ switch (g_test_rand_int_range (0, 7))
+ {
+ case 0:
+ {
+ GVariantType *element;
+
+ g_string_append_c (string, 'a');
+ g_string_append (description, "a of ");
+ element = append_type_string (string, description, depth);
+ result = g_variant_type_new_array (element);
+ g_variant_type_free (element);
+ }
+
+ g_assert (g_variant_type_is_array (result));
+ break;
+
+ case 1:
+ {
+ GVariantType *element;
+
+ g_string_append_c (string, 'm');
+ g_string_append (description, "m of ");
+ element = append_type_string (string, description, depth);
+ result = g_variant_type_new_maybe (element);
+ g_variant_type_free (element);
+ }
+
+ g_assert (g_variant_type_is_maybe (result));
+ break;
+
+ case 2:
+ {
+ GVariantType *other_result;
+ GVariantType **types;
+ gint size;
+ gint i;
+
+ g_string_append_c (string, '(');
+ g_string_append (description, "t of [");
+
+ size = g_test_rand_int_range (0, 20);
+ types = g_new (GVariantType *, size + 1);
+
+ for (i = 0; i < size; i++)
+ {
+ types[i] = append_type_string (string, description, depth);
+
+ if (i < size - 1)
+ g_string_append (description, ", ");
+ }
+
+ types[i] = NULL;
+
+ g_string_append_c (description, ']');
+ g_string_append_c (string, ')');
+
+ result = g_variant_type_new_tuple ((gpointer) types, size);
+ other_result = g_variant_type_new_tuple ((gpointer) types, -1);
+ g_assert (g_variant_type_equal (result, other_result));
+ g_variant_type_free (other_result);
+ for (i = 0; i < size; i++)
+ g_variant_type_free (types[i]);
+ g_free (types);
+ }
+
+ g_assert (g_variant_type_is_tuple (result));
+ break;
+
+ case 3:
+ {
+ GVariantType *key, *value;
+
+ g_string_append_c (string, '{');
+ g_string_append (description, "e of [");
+ key = append_type_string (string, description, 0);
+ g_string_append (description, ", ");
+ value = append_type_string (string, description, depth);
+ g_string_append_c (description, ']');
+ g_string_append_c (string, '}');
+ result = g_variant_type_new_dict_entry (key, value);
+ g_variant_type_free (key);
+ g_variant_type_free (value);
+ }
+
+ g_assert (g_variant_type_is_dict_entry (result));
+ break;
+
+ case 4:
+ g_string_append_c (string, 'v');
+ g_string_append_c (description, 'V');
+ result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
+ g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
+ break;
+
+ case 5:
+ g_string_append_c (string, '*');
+ g_string_append_c (description, 'S');
+ result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
+ g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
+ break;
+
+ case 6:
+ g_string_append_c (string, 'r');
+ g_string_append_c (description, 'R');
+ result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
+ g_assert (g_variant_type_is_tuple (result));
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return result;
+ }
+}
+
+/* given a valid type string, make it invalid */
+static gchar *
+invalid_mutation (const gchar *type_string)
+{
+ gboolean have_parens, have_braces;
+
+ /* it's valid, so '(' implies ')' and same for '{' and '}' */
+ have_parens = strchr (type_string, '(') != NULL;
+ have_braces = strchr (type_string, '{') != NULL;
+
+ if (have_parens && have_braces && randomly (0.3))
+ {
+ /* swap a paren and a brace */
+ gchar *pp, *bp;
+ gint np, nb;
+ gchar p, b;
+ gchar *new;
+
+ new = g_strdup (type_string);
+
+ if (randomly (0.5))
+ p = '(', b = '{';
+ else
+ p = ')', b = '}';
+
+ np = nb = 0;
+ pp = bp = new - 1;
+
+ /* count number of parens/braces */
+ while ((pp = strchr (pp + 1, p))) np++;
+ while ((bp = strchr (bp + 1, b))) nb++;
+
+ /* randomly pick one of each */
+ np = g_test_rand_int_range (0, np) + 1;
+ nb = g_test_rand_int_range (0, nb) + 1;
+
+ /* find it */
+ pp = bp = new - 1;
+ while (np--) pp = strchr (pp + 1, p);
+ while (nb--) bp = strchr (bp + 1, b);
+
+ /* swap */
+ g_assert (*bp == b && *pp == p);
+ *bp = p;
+ *pp = b;
+
+ return new;
+ }
+
+ if ((have_parens || have_braces) && randomly (0.3))
+ {
+ /* drop a paren/brace */
+ gchar *new;
+ gchar *pp;
+ gint np;
+ gchar p;
+
+ if (have_parens)
+ if (randomly (0.5)) p = '('; else p = ')';
+ else
+ if (randomly (0.5)) p = '{'; else p = '}';
+
+ new = g_strdup (type_string);
+
+ np = 0;
+ pp = new - 1;
+ while ((pp = strchr (pp + 1, p))) np++;
+ np = g_test_rand_int_range (0, np) + 1;
+ pp = new - 1;
+ while (np--) pp = strchr (pp + 1, p);
+ g_assert (*pp == p);
+
+ while (*pp)
+ {
+ *pp = *(pp + 1);
+ pp++;
+ }
+
+ return new;
+ }
+
+ /* else, perform a random mutation at a random point */
+ {
+ gint length, n;
+ gchar *new;
+ gchar p;
+
+ if (randomly (0.3))
+ {
+ /* insert a paren/brace */
+ if (randomly (0.5))
+ if (randomly (0.5)) p = '('; else p = ')';
+ else
+ if (randomly (0.5)) p = '{'; else p = '}';
+ }
+ else if (randomly (0.5))
+ {
+ /* insert junk */
+ p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
+ }
+ else
+ {
+ /* truncate */
+ p = '\0';
+ }
+
+
+ length = strlen (type_string);
+ new = g_malloc (length + 2);
+ n = g_test_rand_int_range (0, length);
+ memcpy (new, type_string, n);
+ new[n] = p;
+ memcpy (new + n + 1, type_string + n, length - n);
+ new[length + 1] = '\0';
+
+ return new;
+ }
+}
+
+static gchar *
+describe_type (const GVariantType *type)
+{
+ gchar *result;
+
+ if (g_variant_type_is_container (type))
+ {
+ g_assert (!g_variant_type_is_basic (type));
+
+ if (g_variant_type_is_array (type))
+ {
+ gchar *subtype = describe_type (g_variant_type_element (type));
+ result = g_strdup_printf ("a of %s", subtype);
+ g_free (subtype);
+ }
+ else if (g_variant_type_is_maybe (type))
+ {
+ gchar *subtype = describe_type (g_variant_type_element (type));
+ result = g_strdup_printf ("m of %s", subtype);
+ g_free (subtype);
+ }
+ else if (g_variant_type_is_tuple (type))
+ {
+ if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
+ {
+ const GVariantType *sub;
+ GString *string;
+ gint length;
+ gint i;
+
+ string = g_string_new ("t of [");
+
+ length = g_variant_type_n_items (type);
+ sub = g_variant_type_first (type);
+ for (i = 0; i < length; i++)
+ {
+ gchar *subtype = describe_type (sub);
+ g_string_append (string, subtype);
+ g_free (subtype);
+
+ if ((sub = g_variant_type_next (sub)))
+ g_string_append (string, ", ");
+ }
+ g_assert (sub == NULL);
+ g_string_append_c (string, ']');
+
+ result = g_string_free (string, FALSE);
+ }
+ else
+ result = g_strdup ("R");
+ }
+ else if (g_variant_type_is_dict_entry (type))
+ {
+ gchar *key, *value, *key2, *value2;
+
+ key = describe_type (g_variant_type_key (type));
+ value = describe_type (g_variant_type_value (type));
+ key2 = describe_type (g_variant_type_first (type));
+ value2 = describe_type (
+ g_variant_type_next (g_variant_type_first (type)));
+ g_assert (g_variant_type_next (g_variant_type_next (
+ g_variant_type_first (type))) == NULL);
+ g_assert_cmpstr (key, ==, key2);
+ g_assert_cmpstr (value, ==, value2);
+ result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
+ g_free (key2);
+ g_free (value2);
+ g_free (key);
+ g_free (value);
+ }
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
+ {
+ result = g_strdup ("V");
+ }
+ else
+ g_assert_not_reached ();
+ }
+ else
+ {
+ if (g_variant_type_is_definite (type))
+ {
+ g_assert (g_variant_type_is_basic (type));
+
+ if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
+ result = g_strdup ("b");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
+ result = g_strdup ("y");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
+ result = g_strdup ("n");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
+ result = g_strdup ("q");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
+ result = g_strdup ("i");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
+ result = g_strdup ("u");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
+ result = g_strdup ("x");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
+ result = g_strdup ("t");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
+ result = g_strdup ("h");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
+ result = g_strdup ("d");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
+ result = g_strdup ("s");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
+ result = g_strdup ("o");
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
+ result = g_strdup ("g");
+ else
+ g_assert_not_reached ();
+ }
+ else
+ {
+ if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
+ {
+ result = g_strdup ("S");
+ }
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
+ {
+ result = g_strdup ("?");
+ }
+ else
+ g_assert_not_reached ();
+ }
+ }
+
+ return result;
+}
+
+static void
+test_gvarianttype (void)
+{
+ gint i;
+
+ for (i = 0; i < 10000; i++)
+ {
+ GString *type_string, *description;
+ const GVariantType *ctype;
+ GVariantType *type;
+ gchar *invalid;
+ gchar *desc;
+
+ type_string = g_string_new (NULL);
+ description = g_string_new (NULL);
+
+ type = append_type_string (type_string, description, 6);
+ desc = describe_type (type);
+ g_assert_cmpstr (desc, ==, description->str);
+
+ invalid = invalid_mutation (type_string->str);
+ g_assert (g_variant_type_string_is_valid (type_string->str));
+ g_assert (!g_variant_type_string_is_valid (invalid));
+
+ ctype = G_VARIANT_TYPE (type_string->str);
+ g_assert (g_variant_type_equal (ctype, type));
+ g_assert (g_variant_type_is_subtype_of (ctype, type));
+ g_assert (g_variant_type_is_subtype_of (type, ctype));
+
+ g_string_free (description, TRUE);
+ g_string_free (type_string, TRUE);
+ g_variant_type_free (type);
+ g_free (invalid);
+ g_free (desc);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/gvariant/type", test_gvarianttype);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]