[gtk/more-content-serializer-tests] Add a test for custom serializers




commit 4c6c0b9099f55b22d6930444921db720a3655713
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun May 2 09:17:20 2021 -0400

    Add a test for custom serializers

 testsuite/gdk/contentserializer.c | 288 ++++++++++++++++++++++++++++++++------
 1 file changed, 249 insertions(+), 39 deletions(-)
---
diff --git a/testsuite/gdk/contentserializer.c b/testsuite/gdk/contentserializer.c
index c317531088..d20a60d99e 100644
--- a/testsuite/gdk/contentserializer.c
+++ b/testsuite/gdk/contentserializer.c
@@ -2,14 +2,69 @@
 
 #include <gtk/gtk.h>
 
+typedef gboolean (* ValueCompareFunc) (GValue *v1, GValue *v2);
+
 typedef struct {
   GOutputStream *ostream;
   GInputStream *istream;
   const char *mime_type;
   GValue value;
+  ValueCompareFunc compare;
   gboolean done;
 } TestData;
 
+static gboolean
+compare_string_values (GValue *v1, GValue *v2)
+{
+  return G_VALUE_TYPE (v1) == G_TYPE_STRING &&
+         G_VALUE_TYPE (v2) == G_TYPE_STRING &&
+         strcmp (g_value_get_string (v1), g_value_get_string (v2)) == 0;
+}
+
+static gboolean
+compare_rgba_values (GValue *v1, GValue *v2)
+{
+  return G_VALUE_TYPE (v1) == GDK_TYPE_RGBA &&
+         G_VALUE_TYPE (v2) == GDK_TYPE_RGBA &&
+         gdk_rgba_equal ((GdkRGBA *)g_value_get_boxed (v1),
+                         (GdkRGBA *)g_value_get_boxed (v2));
+}
+
+static gboolean
+compare_file_values (GValue *v1, GValue *v2)
+{
+  return G_VALUE_TYPE (v1) == G_TYPE_FILE &&
+         G_VALUE_TYPE (v2) == G_TYPE_FILE &&
+         g_file_equal ((GFile *)g_value_get_object (v1),
+                       (GFile *)g_value_get_object (v2));
+}
+
+static gboolean
+compare_file_list_values (GValue *v1, GValue *v2)
+{
+  GSList *s1, *s2, *l1, *l2;
+
+  if (G_VALUE_TYPE (v1) != GDK_TYPE_FILE_LIST ||
+      G_VALUE_TYPE (v2) != GDK_TYPE_FILE_LIST)
+    return FALSE;
+
+  s1 = g_value_get_boxed (v1);
+  s2 = g_value_get_boxed (v2);
+
+  if (g_slist_length (s1) != g_slist_length (s2))
+    return FALSE;
+
+  for (l1 = s1, l2 = s2; l1 != NULL; l1 = l1->next, l2 = l2->next)
+    {
+      GFile *f1 = l1->data;
+      GFile *f2 = l2->data;
+      if (!g_file_equal (f1, f2))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
 static void
 deserialize_done (GObject      *source,
                   GAsyncResult *result,
@@ -26,38 +81,7 @@ deserialize_done (GObject      *source,
   g_assert_true (res);
   g_assert_no_error (error);
 
-  if (G_VALUE_TYPE (&data->value) == G_TYPE_STRING)
-    g_assert_cmpstr (g_value_get_string (&data->value), ==, g_value_get_string (&value));
-  else if (G_VALUE_TYPE (&data->value) == GDK_TYPE_RGBA)
-    {
-      GdkRGBA *c1 = g_value_get_boxed (&data->value);
-      GdkRGBA *c2 = g_value_get_boxed (&value);
-
-      g_assert_true (gdk_rgba_equal (c1, c2));
-    }
-  else if (G_VALUE_TYPE (&data->value) == G_TYPE_FILE)
-    {
-      GFile *f1 = g_value_get_object (&data->value);
-      GFile *f2 = g_value_get_object (&value);
-
-      g_assert_true (g_file_equal (f1, f2));
-    }
-  else if (G_VALUE_TYPE (&data->value) == GDK_TYPE_FILE_LIST)
-    {
-      GSList *s1 = g_value_get_boxed (&data->value);
-      GSList *s2 = g_value_get_boxed (&value);
-      GSList *l1, *l2;
-
-      g_assert_cmpint (g_slist_length (s1), ==, g_slist_length (s2));
-      for (l1 = s1, l2 = s2; l1 != NULL; l1 = l1->next, l2 = l2->next)
-        {
-          GFile *f1 = l1->data;
-          GFile *f2 = l2->data;
-          g_assert_true (g_file_equal (f1, f2));
-        }
-    }
-  else
-    g_assert_not_reached ();
+  g_assert_true (data->compare (&data->value, &value));
 
   g_value_unset (&value);
 
@@ -94,8 +118,9 @@ serialize_done (GObject      *source,
 }
 
 static void
-test_content_roundtrip (const GValue *value,
-                        const char   *mime_type)
+test_content_roundtrip (const GValue     *value,
+                        const char       *mime_type,
+                        ValueCompareFunc  compare)
 {
   TestData data = { 0, };
 
@@ -103,6 +128,7 @@ test_content_roundtrip (const GValue *value,
   data.mime_type = g_strdup (mime_type);
   g_value_init (&data.value, G_VALUE_TYPE (value));
   g_value_copy (value, &data.value);
+  data.compare = compare;
   data.done = FALSE;
 
   gdk_content_serialize_async (data.ostream,
@@ -128,7 +154,7 @@ test_content_text_plain_utf8 (void)
 
   g_value_init (&value, G_TYPE_STRING);
   g_value_set_string (&value, "ABCDEF12345");
-  test_content_roundtrip (&value, "text/plain;charset=utf-8");
+  test_content_roundtrip (&value, "text/plain;charset=utf-8", compare_string_values);
   g_value_unset (&value);
 }
 
@@ -139,7 +165,7 @@ test_content_text_plain (void)
 
   g_value_init (&value, G_TYPE_STRING);
   g_value_set_string (&value, "ABCDEF12345");
-  test_content_roundtrip (&value, "text/plain");
+  test_content_roundtrip (&value, "text/plain", compare_string_values);
   g_value_unset (&value);
 }
 
@@ -152,7 +178,7 @@ test_content_color (void)
   gdk_rgba_parse (&color, "magenta");
   g_value_init (&value, GDK_TYPE_RGBA);
   g_value_set_boxed (&value, &color);
-  test_content_roundtrip (&value, "application/x-color");
+  test_content_roundtrip (&value, "application/x-color", compare_rgba_values);
   g_value_unset (&value);
 }
 
@@ -165,7 +191,7 @@ test_content_file (void)
   file = g_file_new_for_path ("/etc/passwd");
   g_value_init (&value, G_TYPE_FILE);
   g_value_set_object (&value, file);
-  test_content_roundtrip (&value, "text/uri-list");
+  test_content_roundtrip (&value, "text/uri-list", compare_file_values);
   g_value_unset (&value);
   g_object_unref (file);
 }
@@ -182,11 +208,194 @@ test_content_files (void)
 
   g_value_init (&value, GDK_TYPE_FILE_LIST);
   g_value_set_boxed (&value, files);
-  test_content_roundtrip (&value, "text/uri-list");
+  test_content_roundtrip (&value, "text/uri-list", compare_file_list_values);
   g_value_unset (&value);
   g_slist_free_full (files, g_object_unref);
 }
 
+#define MY_TYPE_INT_LIST (my_int_list_get_type ())
+GType my_int_list_get_type (void) G_GNUC_CONST;
+
+typedef gpointer MyIntList;
+
+static gpointer
+my_int_list_copy (gpointer list)
+{
+  int size;
+  gpointer copy;
+
+  size = *(int *)list;
+  copy = g_malloc ((size + 1) * sizeof (int));
+  memcpy (copy, list, (size + 1) * sizeof (int));
+
+  return copy;
+}
+
+static void
+my_int_list_free (gpointer list)
+{
+  g_free (list);
+}
+
+G_DEFINE_BOXED_TYPE (MyIntList, my_int_list, my_int_list_copy, my_int_list_free)
+
+static void
+int_list_serializer_finish (GObject      *source,
+                            GAsyncResult *result,
+                            gpointer      serializer)
+{
+  GOutputStream *stream = G_OUTPUT_STREAM (source);
+  GError *error = NULL;
+
+  if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
+    gdk_content_serializer_return_error (serializer, error);
+  else
+    gdk_content_serializer_return_success (serializer);
+}
+
+static void
+int_list_serializer (GdkContentSerializer *serializer)
+{
+  GString *str;
+  const GValue *value;
+  int *data;
+
+  str = g_string_new (NULL);
+  value = gdk_content_serializer_get_value (serializer);
+
+  data = g_value_get_boxed (value);
+  for (int i = 0; i < data[0] + 1; i++)
+    {
+      if (i > 0)
+        g_string_append_c (str, ' ');
+      g_string_append_printf (str, "%d", data[i]);
+    }
+
+  g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
+                                   str->str,
+                                   str->len,
+                                   gdk_content_serializer_get_priority (serializer),
+                                   gdk_content_serializer_get_cancellable (serializer),
+                                   int_list_serializer_finish,
+                                   serializer);
+  gdk_content_serializer_set_task_data (serializer, g_string_free (str, FALSE), g_free);
+}
+
+static void
+int_list_deserializer_finish (GObject      *source,
+                              GAsyncResult *result,
+                              gpointer      deserializer)
+{
+  GOutputStream *stream = G_OUTPUT_STREAM (source);
+  GError *error = NULL;
+  gssize written;
+  GValue *value;
+  char *str;
+  char **strv;
+  int size;
+  int *data;
+
+  written = g_output_stream_splice_finish (stream, result, &error);
+  if (written < 0)
+    {
+      gdk_content_deserializer_return_error (deserializer, error);
+      return;
+    }
+
+  /* write terminating NULL */
+  if (g_output_stream_write (stream, "", 1, NULL, &error) < 0 ||
+      !g_output_stream_close (stream, NULL, &error))
+    {
+      gdk_content_deserializer_return_error (deserializer, error);
+      return;
+    }
+
+  str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
+  strv = g_strsplit (str, " ", -1);
+  size = atoi (strv[0]);
+  if (size + 1 != g_strv_length (strv))
+    {
+      g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Int list corrupt");
+      gdk_content_deserializer_return_error (deserializer, error);
+      g_free (str);
+      g_strfreev (strv);
+      return;
+    }
+
+  data = g_malloc ((size + 1) * sizeof (int));
+  for (int i = 0; i < size + 1; i++)
+    data[i] = atoi (strv[i]);
+  g_free (str);
+  g_strfreev (strv);
+
+  value = gdk_content_deserializer_get_value (deserializer);
+  g_value_take_boxed (value, data);
+
+  gdk_content_deserializer_return_success (deserializer);
+}
+
+static void
+int_list_deserializer (GdkContentDeserializer *deserializer)
+{
+  GOutputStream *output;
+
+  output = g_memory_output_stream_new_resizable ();
+
+  g_output_stream_splice_async (output,
+                                gdk_content_deserializer_get_input_stream (deserializer),
+                                G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
+                                gdk_content_deserializer_get_priority (deserializer),
+                                gdk_content_deserializer_get_cancellable (deserializer),
+                                int_list_deserializer_finish,
+                                deserializer);
+  g_object_unref (output);
+}
+
+static gboolean
+compare_int_list_values (GValue *v1, GValue *v2)
+{
+  int *d1, *d2;
+
+  if (G_VALUE_TYPE (v1) != MY_TYPE_INT_LIST ||
+      G_VALUE_TYPE (v2) != MY_TYPE_INT_LIST)
+    return FALSE;
+
+  d1 = g_value_get_boxed (v1);
+  d2 = g_value_get_boxed (v2);
+
+  if (d1[0] != d2[0])
+    return FALSE;
+
+  return memcmp (d1, d2, (d1[0] + 1) * sizeof (int)) == 0;
+}
+
+static void
+test_custom_format (void)
+{
+  int *data;
+  GValue value = G_VALUE_INIT;
+
+  gdk_content_register_serializer (MY_TYPE_INT_LIST,
+                                   "application/x-int-list",
+                                   int_list_serializer,
+                                   NULL, NULL);
+  gdk_content_register_deserializer ("application/x-int-list",
+                                     MY_TYPE_INT_LIST,
+                                     int_list_deserializer,
+                                     NULL, NULL);
+
+  data = g_malloc (3 * sizeof (int));
+  data[0] = 2;
+  data[1] = 3;
+  data[2] = 5;
+
+  g_value_init (&value, MY_TYPE_INT_LIST);
+  g_value_set_boxed (&value, data);
+  test_content_roundtrip (&value, "application/x-int-list", compare_int_list_values);
+  g_value_unset (&value);
+  g_free (data);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -199,6 +408,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/content/color", test_content_color);
   g_test_add_func ("/content/file", test_content_file);
   g_test_add_func ("/content/files", test_content_files);
+  g_test_add_func ("/content/custom", test_custom_format);
 
   return g_test_run ();
 }


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