desktop-app-info test: use g_assert_strcmp()
[platform/upstream/glib.git] / gio / tests / converter-stream.c
index 63f9e70..c867249 100644 (file)
@@ -92,14 +92,11 @@ g_expander_converter_convert (GConverter *converter,
                              gsize      *bytes_written,
                              GError    **error)
 {
-  GExpanderConverter  *conv;
   const guint8 *in, *in_end;
   guint8 v, *out;
   int i;
   gsize block_size;
 
-  conv = G_EXPANDER_CONVERTER (converter);
-
   in = inbuf;
   out = outbuf;
   in_end = in + inbuf_size;
@@ -211,14 +208,11 @@ g_compressor_converter_convert (GConverter *converter,
                                gsize      *bytes_written,
                                GError    **error)
 {
-  GCompressorConverter  *conv;
   const guint8 *in, *in_end;
   guint8 v, *out;
   int i;
   gsize block_size;
 
-  conv = G_COMPRESSOR_CONVERTER (converter);
-
   in = inbuf;
   out = outbuf;
   in_end = in + inbuf_size;
@@ -301,6 +295,7 @@ test_expander (void)
   GInputStream *mem, *cstream;
   GOutputStream *mem_out, *cstream_out;
   GConverter *expander;
+  GConverter *converter;
   GError *error;
   int i;
 
@@ -326,6 +321,9 @@ test_expander (void)
                                             NULL);
   cstream = g_converter_input_stream_new (mem, expander);
   g_assert (g_converter_input_stream_get_converter (G_CONVERTER_INPUT_STREAM (cstream)) == expander);
+  g_object_get (cstream, "converter", &converter, NULL);
+  g_assert (converter == expander);
+  g_object_unref (converter);
   g_object_unref (mem);
 
   total_read = 0;
@@ -350,6 +348,10 @@ test_expander (void)
 
   mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
   cstream_out = g_converter_output_stream_new (mem_out, expander);
+  g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (cstream_out)) == expander);
+  g_object_get (cstream_out, "converter", &converter, NULL);
+  g_assert (converter == expander);
+  g_object_unref (converter);
   g_object_unref (mem_out);
 
   for (i = 0; i < sizeof(unexpanded_data); i++)
@@ -494,6 +496,8 @@ test_compressor (void)
   g_assert (total_read == 1);
   g_assert (*converted == 5);
 
+  g_object_unref (cstream);
+
   mem = g_memory_input_stream_new_from_data (expanded,
                                             5*1000 * 2,
                                             NULL);
@@ -540,6 +544,7 @@ test_compressor (void)
       if (res == -1)
        {
          g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
+          g_error_free (error);
          break;
        }
 
@@ -559,11 +564,180 @@ test_compressor (void)
   g_object_unref (compressor);
 }
 
+#define LEFTOVER_SHORT_READ_SIZE 512
+
+#define G_TYPE_LEFTOVER_CONVERTER         (g_leftover_converter_get_type ())
+#define G_LEFTOVER_CONVERTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverter))
+#define G_LEFTOVER_CONVERTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
+#define G_IS_LEFTOVER_CONVERTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LEFTOVER_CONVERTER))
+#define G_IS_LEFTOVER_CONVERTER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LEFTOVER_CONVERTER))
+#define G_LEFTOVER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
+
+typedef struct _GLeftoverConverter       GLeftoverConverter;
+typedef struct _GLeftoverConverterClass  GLeftoverConverterClass;
+
+struct _GLeftoverConverterClass
+{
+  GObjectClass parent_class;
+};
+
+GType       g_leftover_converter_get_type (void) G_GNUC_CONST;
+GConverter *g_leftover_converter_new      (void);
+
+
+
+static void g_leftover_converter_iface_init          (GConverterIface *iface);
+
+struct _GLeftoverConverter
+{
+  GObject parent_instance;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GLeftoverConverter, g_leftover_converter, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
+                                               g_leftover_converter_iface_init))
+
+static void
+g_leftover_converter_class_init (GLeftoverConverterClass *klass)
+{
+}
+
+static void
+g_leftover_converter_init (GLeftoverConverter *local)
+{
+}
+
+GConverter *
+g_leftover_converter_new (void)
+{
+  GConverter *conv;
+
+  conv = g_object_new (G_TYPE_LEFTOVER_CONVERTER, NULL);
+
+  return conv;
+}
+
+static void
+g_leftover_converter_reset (GConverter *converter)
+{
+}
+
+static GConverterResult
+g_leftover_converter_convert (GConverter *converter,
+                             const void *inbuf,
+                             gsize       inbuf_size,
+                             void       *outbuf,
+                             gsize       outbuf_size,
+                             GConverterFlags flags,
+                             gsize      *bytes_read,
+                             gsize      *bytes_written,
+                             GError    **error)
+{
+  if (outbuf_size == LEFTOVER_SHORT_READ_SIZE)
+    {
+      g_set_error_literal (error,
+                          G_IO_ERROR,
+                          G_IO_ERROR_PARTIAL_INPUT,
+                          "partial input");
+      return G_CONVERTER_ERROR;
+    }
+
+  if (inbuf_size < 100)
+    *bytes_read = *bytes_written = MIN (inbuf_size, outbuf_size);
+  else
+    *bytes_read = *bytes_written = MIN (inbuf_size - 10, outbuf_size);
+  memcpy (outbuf, inbuf, *bytes_written);
+
+  if (*bytes_read == inbuf_size && (flags & G_CONVERTER_INPUT_AT_END))
+    return G_CONVERTER_FINISHED;
+  return G_CONVERTER_CONVERTED;
+}
+
+static void
+g_leftover_converter_iface_init (GConverterIface *iface)
+{
+  iface->convert = g_leftover_converter_convert;
+  iface->reset = g_leftover_converter_reset;
+}
+
+#define LEFTOVER_BUFSIZE 8192
+#define INTERNAL_BUFSIZE 4096
+
+static void
+test_converter_leftover (void)
+{
+  gchar *orig, *converted;
+  gsize total_read;
+  gssize res;
+  goffset offset;
+  GInputStream *mem, *cstream;
+  GConverter *converter;
+  GError *error;
+  int i;
+
+  converter = g_leftover_converter_new ();
+
+  orig = g_malloc (LEFTOVER_BUFSIZE);
+  converted = g_malloc (LEFTOVER_BUFSIZE);
+  for (i = 0; i < LEFTOVER_BUFSIZE; i++)
+    orig[i] = i % 64 + 32;
+
+  mem = g_memory_input_stream_new_from_data (orig, LEFTOVER_BUFSIZE, NULL);
+  cstream = g_converter_input_stream_new (mem, G_CONVERTER (converter));
+  g_object_unref (mem);
+
+  total_read = 0;
+
+  error = NULL;
+  res = g_input_stream_read (cstream,
+                            converted, LEFTOVER_SHORT_READ_SIZE,
+                            NULL, &error);
+  g_assert_cmpint (res, ==, LEFTOVER_SHORT_READ_SIZE);
+  total_read += res;
+
+  offset = g_seekable_tell (G_SEEKABLE (mem));
+  g_assert_cmpint (offset, >, LEFTOVER_SHORT_READ_SIZE);
+  g_assert_cmpint (offset, <, LEFTOVER_BUFSIZE);
+
+  /* At this point, @cstream has both a non-empty input_buffer
+   * and a non-empty converted_buffer, which is the case
+   * we want to test.
+   */
+
+  while (TRUE)
+    {
+      error = NULL;
+      res = g_input_stream_read (cstream,
+                                converted + total_read,
+                                LEFTOVER_BUFSIZE - total_read,
+                                NULL, &error);
+      g_assert (res >= 0);
+      if (res == 0)
+       break;
+      total_read += res;
+  }
+
+  g_assert_cmpint (total_read, ==, LEFTOVER_BUFSIZE);
+  g_assert (memcmp (converted, orig, LEFTOVER_BUFSIZE)  == 0);
+
+  g_object_unref (cstream);
+  g_free (orig);
+  g_free (converted);
+  g_object_unref (converter);
+}
+
 #define DATA_LENGTH 1000000
 
+typedef struct {
+  const gchar *path;
+  GZlibCompressorFormat format;
+  gint level;
+} CompressorTest;
+
 static void
-test_corruption (GZlibCompressorFormat format, gint level)
+test_roundtrip (gconstpointer data)
 {
+  const CompressorTest *test = data;
   GError *error = NULL;
   guint32 *data0, *data1;
   gsize data1_size;
@@ -571,6 +745,12 @@ test_corruption (GZlibCompressorFormat format, gint level)
   GInputStream *istream0, *istream1, *cistream1;
   GOutputStream *ostream1, *ostream2, *costream1;
   GConverter *compressor, *decompressor;
+  GZlibCompressorFormat fmt;
+  gint lvl;
+  GFileInfo *info;
+  GFileInfo *info2;
+
+  g_test_bug ("619945");
 
   data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
   for (i = 0; i < DATA_LENGTH; i++)
@@ -579,8 +759,14 @@ test_corruption (GZlibCompressorFormat format, gint level)
   istream0 = g_memory_input_stream_new_from_data (data0,
     DATA_LENGTH * sizeof (guint32), NULL);
 
-  ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, NULL);
-  compressor = G_CONVERTER (g_zlib_compressor_new (format, level));
+  ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+  compressor = G_CONVERTER (g_zlib_compressor_new (test->format, test->level));
+  info = g_file_info_new ();
+  g_file_info_set_name (info, "foo");
+  g_object_set (compressor, "file-info", info, NULL);
+  info2 = g_zlib_compressor_get_file_info (G_ZLIB_COMPRESSOR (compressor));
+  g_assert (info == info2);
+  g_object_unref (info);
   costream1 = g_converter_output_stream_new (ostream1, compressor);
   g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
 
@@ -588,18 +774,23 @@ test_corruption (GZlibCompressorFormat format, gint level)
   g_assert_no_error (error);
 
   g_object_unref (costream1);
+
+  g_converter_reset (compressor);
+  g_object_get (compressor, "format", &fmt, "level", &lvl, NULL);
+  g_assert_cmpint (fmt, ==, test->format);
+  g_assert_cmpint (lvl, ==, test->level);
   g_object_unref (compressor);
-  data1 = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (ostream1));
+  data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
   data1_size = g_memory_output_stream_get_data_size (
     G_MEMORY_OUTPUT_STREAM (ostream1));
   g_object_unref (ostream1);
   g_object_unref (istream0);
 
-  istream1 = g_memory_input_stream_new_from_data (data1, data1_size, NULL);
-  decompressor = G_CONVERTER (g_zlib_decompressor_new (format));
+  istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
+  decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
   cistream1 = g_converter_input_stream_new (istream1, decompressor);
 
-  ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, NULL);
+  ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
 
   g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
   g_assert_no_error (error);
@@ -608,20 +799,14 @@ test_corruption (GZlibCompressorFormat format, gint level)
     g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream2)));
   g_assert (memcmp (data0, g_memory_output_stream_get_data (
     G_MEMORY_OUTPUT_STREAM (ostream2)), DATA_LENGTH * sizeof (guint32)) == 0);
-}
-
-typedef struct {
-  const gchar *path;
-  GZlibCompressorFormat format;
-  gint level;
-} CompressorTest;
-
-static void
-test_roundtrip (gconstpointer data)
-{
-  const CompressorTest *test = data;
-
-  test_corruption (test->format, test->level);
+  g_object_unref (istream1);
+  g_converter_reset (decompressor);
+  g_object_get (decompressor, "format", &fmt, NULL);
+  g_assert_cmpint (fmt, ==, test->format);
+  g_object_unref (decompressor);
+  g_object_unref (cistream1);
+  g_object_unref (ostream2);
+  g_free (data0);
 }
 
 typedef struct {
@@ -663,14 +848,20 @@ test_charset (gconstpointer data)
       g_assert_cmpstr (buffer, ==, test->text_out);
     }
   else
-    g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
+    {
+      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
+      g_error_free (error);
+    }
 
   g_free (buffer);
   g_object_unref (in2);
   g_object_unref (in);
 
   if (test->n_fallbacks == 0)
-    return;
+    {
+       g_object_unref (conv);
+       return;
+    }
 
   g_converter_reset (conv);
 
@@ -696,39 +887,349 @@ test_charset (gconstpointer data)
   g_object_unref (conv);
 }
 
+
+static void
+client_connected (GObject      *source,
+                 GAsyncResult *result,
+                 gpointer      user_data)
+{
+  GSocketClient *client = G_SOCKET_CLIENT (source);
+  GSocketConnection **conn = user_data;
+  GError *error = NULL;
+
+  *conn = g_socket_client_connect_finish (client, result, &error);
+  g_assert_no_error (error);
+}
+
+static void
+server_connected (GObject      *source,
+                 GAsyncResult *result,
+                 gpointer      user_data)
+{
+  GSocketListener *listener = G_SOCKET_LISTENER (source);
+  GSocketConnection **conn = user_data;
+  GError *error = NULL;
+
+  *conn = g_socket_listener_accept_finish (listener, result, NULL, &error);
+  g_assert_no_error (error);
+}
+
+static void
+make_socketpair (GIOStream **left,
+                GIOStream **right)
+{
+  GInetAddress *iaddr;
+  GSocketAddress *saddr, *effective_address;
+  GSocketListener *listener;
+  GSocketClient *client;
+  GError *error = NULL;
+  GSocketConnection *client_conn = NULL, *server_conn = NULL;
+
+  iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
+  saddr = g_inet_socket_address_new (iaddr, 0);
+  g_object_unref (iaddr);
+
+  listener = g_socket_listener_new ();
+  g_socket_listener_add_address (listener, saddr,
+                                G_SOCKET_TYPE_STREAM,
+                                G_SOCKET_PROTOCOL_TCP,
+                                NULL,
+                                &effective_address,
+                                &error);
+  g_assert_no_error (error);
+  g_object_unref (saddr);
+
+  client = g_socket_client_new ();
+
+  g_socket_client_connect_async (client,
+                                G_SOCKET_CONNECTABLE (effective_address),
+                                NULL, client_connected, &client_conn);
+  g_socket_listener_accept_async (listener, NULL,
+                                 server_connected, &server_conn);
+
+  while (!client_conn || !server_conn)
+    g_main_context_iteration (NULL, TRUE);
+
+  g_object_unref (client);
+  g_object_unref (listener);
+  g_object_unref (effective_address);
+
+  *left = G_IO_STREAM (client_conn);
+  *right = G_IO_STREAM (server_conn);
+}
+
+static void
+test_converter_pollable (void)
+{
+  GIOStream *left, *right;
+  guint8 *converted, *inptr;
+  guint8 *expanded, *outptr, *expanded_end;
+  gsize n_read, expanded_size;
+  gsize total_read;
+  gssize res;
+  gboolean is_readable;
+  GConverterResult cres;
+  GInputStream *cstream;
+  GPollableInputStream *pollable_in;
+  GOutputStream *socket_out, *mem_out, *cstream_out;
+  GPollableOutputStream *pollable_out;
+  GConverter *expander, *compressor;
+  GError *error;
+  int i;
+
+  expander = g_expander_converter_new ();
+  expanded = g_malloc (100*1000); /* Large enough */
+  cres = g_converter_convert (expander,
+                             unexpanded_data, sizeof(unexpanded_data),
+                             expanded, 100*1000,
+                             G_CONVERTER_INPUT_AT_END,
+                             &n_read, &expanded_size, NULL);
+  g_assert (cres == G_CONVERTER_FINISHED);
+  g_assert (n_read == 11);
+  g_assert (expanded_size == 41030);
+  expanded_end = expanded + expanded_size;
+
+  make_socketpair (&left, &right);
+
+  compressor = g_compressor_converter_new ();
+
+  converted = g_malloc (100*1000); /* Large enough */
+
+  cstream = g_converter_input_stream_new (g_io_stream_get_input_stream (left),
+                                         compressor);
+  pollable_in = G_POLLABLE_INPUT_STREAM (cstream);
+  g_assert (g_pollable_input_stream_can_poll (pollable_in));
+
+  socket_out = g_io_stream_get_output_stream (right);
+
+  total_read = 0;
+  outptr = expanded;
+  inptr = converted;
+  while (TRUE)
+    {
+      error = NULL;
+
+      if (outptr < expanded_end)
+       {
+          res = g_output_stream_write (socket_out,
+                                      outptr,
+                                      MIN (1000, (expanded_end - outptr)),
+                                      NULL, &error);
+         g_assert_cmpint (res, >, 0);
+         outptr += res;
+       }
+      else if (socket_out)
+       {
+         g_object_unref (right);
+         socket_out = NULL;
+       }
+
+      /* Wait a few ticks to check for the pipe to propagate the
+       * write. Finesses the race condition in the following test,
+       * where is_readable fails because the write hasn't propagated,
+       * but the read then succeeds because it has. */
+      g_usleep (80L);
+
+      is_readable = g_pollable_input_stream_is_readable (pollable_in);
+      res = g_pollable_input_stream_read_nonblocking (pollable_in,
+                                                     inptr, 1,
+                                                     NULL, &error);
+
+      /* is_readable can be a false positive, but not a false negative */
+      if (!is_readable)
+       g_assert_cmpint (res, ==, -1);
+
+      /* After closing the write end, we can't get WOULD_BLOCK any more */
+      if (!socket_out)
+       g_assert_cmpint (res, !=, -1);
+
+      if (res == -1)
+       {
+         g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
+         g_error_free (error);
+
+         continue;
+       }
+
+      if (res == 0)
+       break;
+      inptr += res;
+      total_read += res;
+    }
+
+  g_assert (total_read == n_read - 1); /* Last 2 zeros are combined */
+  g_assert (memcmp (converted, unexpanded_data, total_read)  == 0);
+
+  g_object_unref (cstream);
+  g_object_unref (left);
+
+  g_converter_reset (compressor);
+
+  /* This doesn't actually test the behavior on
+   * G_IO_ERROR_WOULD_BLOCK; to do that we'd need to implement a
+   * custom GOutputStream that we could control blocking on.
+   */
+
+  mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+  cstream_out = g_converter_output_stream_new (mem_out, compressor);
+  g_object_unref (mem_out);
+  pollable_out = G_POLLABLE_OUTPUT_STREAM (cstream_out);
+  g_assert (g_pollable_output_stream_can_poll (pollable_out));
+  g_assert (g_pollable_output_stream_is_writable (pollable_out));
+
+  for (i = 0; i < expanded_size; i++)
+    {
+      error = NULL;
+      res = g_pollable_output_stream_write_nonblocking (pollable_out,
+                                                       expanded + i, 1,
+                                                       NULL, &error);
+      g_assert (res != -1);
+      if (res == 0)
+       {
+         g_assert (i == expanded_size -1);
+         break;
+       }
+      g_assert (res == 1);
+    }
+
+  g_output_stream_close (cstream_out, NULL, NULL);
+
+  g_assert (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)) == n_read - 1); /* Last 2 zeros are combined */
+  g_assert (memcmp (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
+                   unexpanded_data,
+                   g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)))  == 0);
+
+  g_object_unref (cstream_out);
+
+  g_free (expanded);
+  g_free (converted);
+  g_object_unref (expander);
+  g_object_unref (compressor);
+}
+
+static void
+test_truncation (gconstpointer data)
+{
+  const CompressorTest *test = data;
+  GError *error = NULL;
+  guint32 *data0, *data1;
+  gsize data1_size;
+  gint i;
+  GInputStream *istream0, *istream1, *cistream1;
+  GOutputStream *ostream1, *ostream2, *costream1;
+  GConverter *compressor, *decompressor;
+
+  data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
+  for (i = 0; i < DATA_LENGTH; i++)
+    data0[i] = g_random_int ();
+
+  istream0 = g_memory_input_stream_new_from_data (data0,
+    DATA_LENGTH * sizeof (guint32), NULL);
+
+  ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+  compressor = G_CONVERTER (g_zlib_compressor_new (test->format, -1));
+  costream1 = g_converter_output_stream_new (ostream1, compressor);
+  g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
+
+  g_output_stream_splice (costream1, istream0, 0, NULL, &error);
+  g_assert_no_error (error);
+
+  g_object_unref (costream1);
+  g_object_unref (compressor);
+
+  data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
+  data1_size = g_memory_output_stream_get_data_size (
+    G_MEMORY_OUTPUT_STREAM (ostream1));
+  g_object_unref (ostream1);
+  g_object_unref (istream0);
+
+  /* truncate */
+  data1_size /= 2;
+
+  istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
+  decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
+  cistream1 = g_converter_input_stream_new (istream1, decompressor);
+
+  ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+
+  g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
+  g_error_free (error);
+
+  g_object_unref (istream1);
+  g_object_unref (decompressor);
+  g_object_unref (cistream1);
+  g_object_unref (ostream2);
+  g_free (data0);
+}
+
+static void
+test_converter_basics (void)
+{
+  GConverter *converter;
+  GError *error = NULL;
+  gchar *to;
+  gchar *from;
+
+  converter = (GConverter *)g_charset_converter_new ("utf-8", "latin1", &error);
+  g_assert_no_error (error);
+  g_object_get (converter,
+                "to-charset", &to,
+                "from-charset", &from,
+                NULL);
+
+  g_assert_cmpstr (to, ==, "utf-8");
+  g_assert_cmpstr (from, ==, "latin1");
+
+  g_free (to);
+  g_free (from);
+  g_object_unref (converter);
+}
+
 int
 main (int   argc,
       char *argv[])
 {
   CompressorTest compressor_tests[] = {
-    { "/converter-output-stream/corruption/zlib-0", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
-    { "/converter-output-stream/corruption/zlib-9", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9 },
-    { "/converter-output-stream/corruption/gzip-0", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
-    { "/converter-output-stream/corruption/gzip-9", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9 },
-    { "/converter-output-stream/corruption/raw-0", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
-    { "/converter-output-stream/corruption/raw-9", G_ZLIB_COMPRESSOR_FORMAT_RAW, 9 },
+    { "/converter-output-stream/roundtrip/zlib-0", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
+    { "/converter-output-stream/roundtrip/zlib-9", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9 },
+    { "/converter-output-stream/roundtrip/gzip-0", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
+    { "/converter-output-stream/roundtrip/gzip-9", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9 },
+    { "/converter-output-stream/roundtrip/raw-0", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
+    { "/converter-output-stream/roundtrip/raw-9", G_ZLIB_COMPRESSOR_FORMAT_RAW, 9 },
+  };
+  CompressorTest truncation_tests[] = {
+    { "/converter-input-stream/truncation/zlib", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
+    { "/converter-input-stream/truncation/gzip", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
+    { "/converter-input-stream/truncation/raw", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
   };
   CharsetTest charset_tests[] = {
     { "/converter-input-stream/charset/utf8->latin1", "UTF-8", "\303\205rr Sant\303\251", "ISO-8859-1", "\305rr Sant\351", 0 },
     { "/converter-input-stream/charset/latin1->utf8", "ISO-8859-1", "\305rr Sant\351", "UTF-8", "\303\205rr Sant\303\251", 0 },
     { "/converter-input-stream/charset/fallbacks", "UTF-8", "Some characters just don't fit into latin1: πא", "ISO-8859-1", "Some characters just don't fit into latin1: \\CF\\80\\D7\\90", 4 },
-
   };
 
   gint i;
 
-  g_type_init ();
   g_test_init (&argc, &argv, NULL);
 
+  g_test_bug_base ("http://bugzilla.gnome.org/");
+
+  g_test_add_func ("/converter/basics", test_converter_basics);
   g_test_add_func ("/converter-input-stream/expander", test_expander);
   g_test_add_func ("/converter-input-stream/compressor", test_compressor);
 
   for (i = 0; i < G_N_ELEMENTS (compressor_tests); i++)
     g_test_add_data_func (compressor_tests[i].path, &compressor_tests[i], test_roundtrip);
 
+  for (i = 0; i < G_N_ELEMENTS (truncation_tests); i++)
+    g_test_add_data_func (truncation_tests[i].path, &truncation_tests[i], test_truncation);
+
   for (i = 0; i < G_N_ELEMENTS (charset_tests); i++)
     g_test_add_data_func (charset_tests[i].path, &charset_tests[i], test_charset);
 
+  g_test_add_func ("/converter-stream/pollable", test_converter_pollable);
+  g_test_add_func ("/converter-stream/leftover", test_converter_leftover);
 
   return g_test_run();
 }