[glib] Improve test coverage



commit 309f5f978bc1378449fea2a81f4d47e749ae7ceb
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Feb 13 23:47:42 2011 -0500

    Improve test coverage
    
    Various test additions, mainly in GObject

 gio/tests/gapplication.c  |   32 ++++
 gio/tests/gsettings.c     |    4 +-
 glib/tests/Makefile.am    |    9 +-
 glib/tests/dataset.c      |  187 ++++++++++++++++++++++
 glib/tests/gdatetime.c    |   26 +++
 glib/tests/mappedfile.c   |   73 +++++++++
 glib/tests/utils.c        |   53 ++++++
 gobject/tests/Makefile.am |   12 ++-
 gobject/tests/binding.c   |   52 ++++++-
 gobject/tests/boxed.c     |  386 +++++++++++++++++++++++++++++++++++++++++++++
 gobject/tests/enums.c     |  113 +++++++++++++
 gobject/tests/param.c     |  223 ++++++++++++++++++++++++++
 gobject/tests/reference.c |  213 +++++++++++++++++++++++++
 13 files changed, 1376 insertions(+), 7 deletions(-)
---
diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c
index 453d8d8..96de072 100644
--- a/gio/tests/gapplication.c
+++ b/gio/tests/gapplication.c
@@ -221,12 +221,44 @@ basic (void)
   session_bus_down ();
 }
 
+static void
+properties (void)
+{
+  GObject *app;
+  gchar *id;
+  GApplicationFlags flags;
+  gboolean registered;
+  guint timeout;
+
+  app = g_object_new (G_TYPE_APPLICATION,
+                      "application-id", "org.gtk.TestApplication",
+                      NULL);
+
+  g_object_get (app,
+                "application-id", &id,
+                "flags", &flags,
+                "is-registered", &registered,
+                "inactivity-timeout", &timeout,
+                NULL);
+
+  g_assert_cmpstr (id, ==, "org.gtk.TestApplication");
+  g_assert_cmpint (flags, ==, G_APPLICATION_FLAGS_NONE);
+  g_assert (!registered);
+  g_assert_cmpint (timeout, ==, 0);
+
+  g_object_unref (app);
+  g_free (id);
+}
+
 int
 main (int argc, char **argv)
 {
+  g_type_init ();
+
   g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/gapplication/basic", basic);
+  g_test_add_func ("/gapplication/properties", properties);
 
   return g_test_run ();
 }
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index b2f9d4f..e178a05 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -158,7 +158,7 @@ test_wrong_path (void)
 {
   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
     {
-      GSettings *settings;
+      GSettings *settings G_GNUC_UNUSED;
 
       settings = g_settings_new_with_path ("org.gtk.test", "/wrong-path/");
     }
@@ -172,7 +172,7 @@ test_no_path (void)
 {
   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
     {
-      GSettings *settings;
+      GSettings *settings G_GNUC_UNUSED;
 
       settings = g_settings_new ("org.gtk.test.no-path");
     }
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index 14b987b..17698eb 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -151,6 +151,12 @@ gdatetime_LDADD      = $(progs_ldadd)
 TEST_PROGS       += environment
 environment_LDADD = $(progs_ldadd)
 
+TEST_PROGS       += mappedfile
+mappedfile_LDADD  = $(progs_ldadd)
+
+TEST_PROGS    += dataset
+dataset_LDADD  = $(progs_ldadd)
+
 if OS_UNIX
 
 # some testing of gtester funcitonality
@@ -169,7 +175,8 @@ EXTRA_DIST += \
 	4096-random-bytes	\
 	keyfiletest.ini		\
 	pages.ini		\
-	bookmarks.xbel
+	bookmarks.xbel		\
+	empty
 
 dist-hook:
 	mkdir $(distdir)/markups;		\
diff --git a/glib/tests/dataset.c b/glib/tests/dataset.c
new file mode 100644
index 0000000..4b01965
--- /dev/null
+++ b/glib/tests/dataset.c
@@ -0,0 +1,187 @@
+#include <glib.h>
+
+static void
+test_quark_basic (void)
+{
+  GQuark quark;
+  const gchar *orig = "blargh";
+  gchar *copy;
+  const gchar *str;
+
+  quark = g_quark_try_string ("no-such-quark");
+  g_assert (quark == 0);
+
+  copy = g_strdup (orig);
+  quark = g_quark_from_static_string (orig);
+  g_assert (quark != 0);
+  g_assert (g_quark_from_string (orig) == quark);
+  g_assert (g_quark_from_string (copy) == quark);
+  g_assert (g_quark_try_string (orig) == quark);
+
+  str = g_quark_to_string (quark);
+  g_assert_cmpstr (str, ==, orig);
+
+  g_free (copy);
+}
+
+static void
+test_quark_string (void)
+{
+  const gchar *orig = "string1";
+  gchar *copy;
+  const gchar *str1;
+  const gchar *str2;
+
+  copy = g_strdup (orig);
+
+  str1 = g_intern_static_string (orig);
+  str2 = g_intern_string (copy);
+  g_assert (str1 == str2);
+  g_assert (str1 == orig);
+
+  g_free (copy);
+}
+
+static void
+test_dataset_basic (void)
+{
+  gpointer location = (gpointer)test_dataset_basic;
+  gpointer other = (gpointer)test_quark_basic;
+  gpointer data = "test1";
+  gpointer ret;
+
+  g_dataset_set_data (location, "test1", data);
+
+  ret = g_dataset_get_data (location, "test1");
+  g_assert (ret == data);
+
+  ret = g_dataset_get_data (location, "test2");
+  g_assert (ret == NULL);
+
+  ret = g_dataset_get_data (other, "test1");
+  g_assert (ret == NULL);
+
+  g_dataset_set_data (location, "test1", "new-value");
+  ret = g_dataset_get_data (location, "test1");
+  g_assert (ret != data);
+
+  g_dataset_remove_data (location, "test1");
+  ret = g_dataset_get_data (location, "test1");
+  g_assert (ret == NULL);
+}
+
+static gint destroy_count;
+
+static void
+notify (gpointer data)
+{
+  destroy_count++;
+}
+
+static void
+test_dataset_full (void)
+{
+  gpointer location = (gpointer)test_dataset_full;
+
+  g_dataset_set_data_full (location, "test1", "test1", notify);
+
+  destroy_count = 0;
+  g_dataset_set_data (location, "test1", NULL);
+  g_assert (destroy_count == 1);
+
+  g_dataset_set_data_full (location, "test1", "test1", notify);
+
+  destroy_count = 0;
+  g_dataset_remove_data (location, "test1");
+  g_assert (destroy_count == 1);
+
+  g_dataset_set_data_full (location, "test1", "test1", notify);
+
+  destroy_count = 0;
+  g_dataset_remove_no_notify (location, "test1");
+  g_assert (destroy_count == 0);
+}
+
+static void
+foreach (GQuark   id,
+         gpointer data,
+         gpointer user_data)
+{
+  gint *counter = user_data;
+
+  *counter += 1;
+}
+
+static void
+test_dataset_foreach (void)
+{
+  gpointer location = (gpointer)test_dataset_foreach;
+  gint my_count;
+
+  my_count = 0;
+  g_dataset_set_data_full (location, "test1", "test1", notify);
+  g_dataset_set_data_full (location, "test2", "test2", notify);
+  g_dataset_set_data_full (location, "test3", "test3", notify);
+  g_dataset_foreach (location, foreach, &my_count);
+  g_assert (my_count == 3);
+}
+
+static void
+test_dataset_destroy (void)
+{
+  gpointer location = (gpointer)test_dataset_destroy;
+
+  destroy_count = 0;
+  g_dataset_set_data_full (location, "test1", "test1", notify);
+  g_dataset_set_data_full (location, "test2", "test2", notify);
+  g_dataset_set_data_full (location, "test3", "test3", notify);
+  g_dataset_destroy (location);
+  g_assert (destroy_count == 3);
+}
+
+static void
+test_dataset_id (void)
+{
+  gpointer location = (gpointer)test_dataset_id;
+  gpointer other = (gpointer)test_quark_basic;
+  gpointer data = "test1";
+  gpointer ret;
+  GQuark quark;
+
+  quark = g_quark_from_string ("test1");
+
+  g_dataset_id_set_data (location, quark, data);
+
+  ret = g_dataset_id_get_data (location, quark);
+  g_assert (ret == data);
+
+  ret = g_dataset_id_get_data (location, g_quark_from_string ("test2"));
+  g_assert (ret == NULL);
+
+  ret = g_dataset_id_get_data (other, quark);
+  g_assert (ret == NULL);
+
+  g_dataset_id_set_data (location, quark, "new-value");
+  ret = g_dataset_id_get_data (location, quark);
+  g_assert (ret != data);
+
+  g_dataset_id_remove_data (location, quark);
+  ret = g_dataset_id_get_data (location, quark);
+  g_assert (ret == NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/quark/basic", test_quark_basic);
+  g_test_add_func ("/quark/string", test_quark_string);
+  g_test_add_func ("/dataset/basic", test_dataset_basic);
+  g_test_add_func ("/dataset/id", test_dataset_id);
+  g_test_add_func ("/dataset/full", test_dataset_full);
+  g_test_add_func ("/dataset/foreach", test_dataset_foreach);
+  g_test_add_func ("/dataset/destroy", test_dataset_destroy);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/empty b/glib/tests/empty
new file mode 100644
index 0000000..e69de29
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 619bb02..e381b9d 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -625,6 +625,28 @@ test_GDateTime_now_utc (void)
 }
 
 static void
+test_GDateTime_new_from_unix_utc (void)
+{
+  GDateTime *dt;
+  gint64 t;
+
+  t = g_get_real_time ();
+
+  dt = g_date_time_new_from_unix_utc (t);
+  g_assert (dt == NULL);
+
+  t = t / 1e6;  /* oops, this was microseconds */
+
+  dt = g_date_time_new_from_unix_utc (t);
+  g_assert (dt != NULL);
+
+  g_assert (dt == g_date_time_ref (dt));
+  g_date_time_unref (dt);
+  g_assert_cmpint (g_date_time_to_unix (dt), ==, t);
+  g_date_time_unref (dt);
+}
+
+static void
 test_GDateTime_get_utc_offset (void)
 {
   GDateTime *dt;
@@ -639,6 +661,9 @@ test_GDateTime_get_utc_offset (void)
 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
   g_assert_cmpint (ts, ==, (tm.tm_gmtoff * G_TIME_SPAN_SECOND));
 #endif
+#ifdef HAVE_STRUCT_TM___TM_GMTOFF
+  g_assert_cmpint (ts, ==, (tm.__tm_gmtoff * G_TIME_SPAN_SECOND));
+#endif
   g_date_time_unref (dt);
 }
 
@@ -1029,6 +1054,7 @@ main (gint   argc,
   g_test_add_func ("/GDateTime/get_year", test_GDateTime_get_year);
   g_test_add_func ("/GDateTime/hash", test_GDateTime_hash);
   g_test_add_func ("/GDateTime/new_from_unix", test_GDateTime_new_from_unix);
+  g_test_add_func ("/GDateTime/new_from_unix_utc", test_GDateTime_new_from_unix_utc);
   g_test_add_func ("/GDateTime/new_from_timeval", test_GDateTime_new_from_timeval);
   g_test_add_func ("/GDateTime/new_full", test_GDateTime_new_full);
   g_test_add_func ("/GDateTime/now", test_GDateTime_now);
diff --git a/glib/tests/mappedfile.c b/glib/tests/mappedfile.c
new file mode 100644
index 0000000..8a0af9b
--- /dev/null
+++ b/glib/tests/mappedfile.c
@@ -0,0 +1,73 @@
+#include <glib.h>
+#include <string.h>
+
+static void
+test_empty (void)
+{
+  GMappedFile *file;
+  GError *error;
+
+  error = NULL;
+  file = g_mapped_file_new ("empty", FALSE, &error);
+  g_assert_no_error (error);
+
+  g_assert (g_mapped_file_get_contents (file) == NULL);
+
+  g_mapped_file_free (file);
+}
+
+static void
+test_nonexisting (void)
+{
+  GMappedFile *file;
+  GError *error;
+
+  error = NULL;
+  file = g_mapped_file_new ("no-such-file", FALSE, &error);
+  g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
+  g_clear_error (&error);
+  g_assert (file == NULL);
+}
+
+static void
+test_writable (void)
+{
+  GMappedFile *file;
+  GError *error;
+  gchar *contents;
+  const gchar *old = "MMMMMMMMMMMMMMMMMMMMMMMMM";
+  const gchar *new = "abcdefghijklmnopqrstuvxyz";
+
+  error = NULL;
+  file = g_mapped_file_new ("4096-random-bytes", TRUE, &error);
+  g_assert_no_error (error);
+
+  contents = g_mapped_file_get_contents (file);
+  g_assert (strncmp (contents, old, strlen (old)) == 0);
+
+  memcpy (contents, new, strlen (new));
+  g_assert (strncmp (contents, new, strlen (new)) == 0);
+
+  g_mapped_file_free (file);
+
+  error = NULL;
+  file = g_mapped_file_new ("4096-random-bytes", TRUE, &error);
+  g_assert_no_error (error);
+
+  contents = g_mapped_file_get_contents (file);
+  g_assert (strncmp (contents, old, strlen (old)) == 0);
+
+  g_mapped_file_free (file);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/mappedfile/empty", test_empty);
+  g_test_add_func ("/mappedfile/nonexisting", test_nonexisting);
+  g_test_add_func ("/mappedfile/writable", test_writable);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/utils.c b/glib/tests/utils.c
index cf7d8dd..41e5237 100644
--- a/glib/tests/utils.c
+++ b/glib/tests/utils.c
@@ -151,6 +151,58 @@ test_tmpdir (void)
   g_assert_cmpstr (g_get_tmp_dir (), !=, "");
 }
 
+static void
+test_bits (void)
+{
+  gulong mask;
+  gint max_bit;
+  gint i, pos;
+
+  pos = g_bit_nth_lsf (0, -1);
+  g_assert_cmpint (pos, ==, -1);
+
+  max_bit = sizeof (gulong) * 8;
+  for (i = 0; i < max_bit; i++)
+    {
+      mask = 1UL << i;
+
+      pos = g_bit_nth_lsf (mask, -1);
+      g_assert_cmpint (pos, ==, i);
+
+      pos = g_bit_nth_lsf (mask, i - 3);
+      g_assert_cmpint (pos , ==, i);
+
+      pos = g_bit_nth_lsf (mask, i);
+      g_assert_cmpint (pos , ==, -1);
+
+      pos = g_bit_nth_lsf (mask, i + 1);
+      g_assert_cmpint (pos , ==, -1);
+    }
+
+  pos = g_bit_nth_msf (0, -1);
+  g_assert_cmpint (pos, ==, -1);
+
+  for (i = 0; i < max_bit; i++)
+    {
+      mask = 1UL << i;
+
+      pos = g_bit_nth_msf (mask, -1);
+      g_assert_cmpint (pos, ==, i);
+
+      pos = g_bit_nth_msf (mask, i + 3);
+      g_assert_cmpint (pos , ==, i);
+
+      pos = g_bit_nth_msf (mask, i);
+      g_assert_cmpint (pos , ==, -1);
+
+      if (i > 0)
+        {
+          pos = g_bit_nth_msf (mask, i - 1);
+          g_assert_cmpint (pos , ==, -1);
+        }
+    }
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -170,6 +222,7 @@ main (int   argc,
   g_test_add_func ("/utils/version", test_version);
   g_test_add_func ("/utils/appname", test_appname);
   g_test_add_func ("/utils/tmpdir", test_tmpdir);
+  g_test_add_func ("/utils/bits", test_bits);
 
   return g_test_run();
 }
diff --git a/gobject/tests/Makefile.am b/gobject/tests/Makefile.am
index 8452164..2ea23e4 100644
--- a/gobject/tests/Makefile.am
+++ b/gobject/tests/Makefile.am
@@ -5,5 +5,15 @@ INCLUDES = -g $(gobject_INCLUDES) $(GLIB_DEBUG_FLAGS)
 noinst_PROGRAMS  = $(TEST_PROGS)
 LDADD = ../libgobject-2.0.la $(top_builddir)/gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la
 
-TEST_PROGS += threadtests dynamictests binding properties reference ifaceproperties
+TEST_PROGS += 		\
+	boxed		\
+	enums		\
+	param		\
+	threadtests	\
+	dynamictests	\
+	binding		\
+	properties	\
+	reference	\
+	ifaceproperties
+
 ifaceproperties_SOURCES = ifaceproperties.c testcommon.h
diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c
index 31993f3..ca1022e 100644
--- a/gobject/tests/binding.c
+++ b/gobject/tests/binding.c
@@ -329,11 +329,52 @@ data_free (gpointer data)
 }
 
 static void
-binding_transform (void)
+binding_transform_default (void)
 {
   BindingSource *source = g_object_new (binding_source_get_type (), NULL);
   BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
   GBinding *binding;
+  gpointer src, trg;
+  gchar *src_prop, *trg_prop;
+  GBindingFlags flags;
+
+  binding = g_object_bind_property (source, "foo",
+                                    target, "value",
+                                    G_BINDING_BIDIRECTIONAL);
+
+  g_object_get (binding,
+                "source", &src,
+                "source-property", &src_prop,
+                "target", &trg,
+                "target-property", &trg_prop,
+                "flags", &flags,
+                NULL);
+  g_assert (src == source);
+  g_assert (trg == target);
+  g_assert_cmpstr (src_prop, ==, "foo");
+  g_assert_cmpstr (trg_prop, ==, "value");
+  g_assert_cmpint (flags, ==, G_BINDING_BIDIRECTIONAL);
+  g_object_unref (src);
+  g_object_unref (trg);
+  g_free (src_prop);
+  g_free (trg_prop);
+
+  g_object_set (source, "foo", 24, NULL);
+  g_assert_cmpfloat (target->value, ==, 24.0);
+
+  g_object_set (target, "value", 69.0, NULL);
+  g_assert_cmpint (source->foo, ==, 69);
+
+  g_object_unref (source);
+  g_object_unref (target);
+}
+
+static void
+binding_transform (void)
+{
+  BindingSource *source = g_object_new (binding_source_get_type (), NULL);
+  BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
+  GBinding *binding G_GNUC_UNUSED;
   gboolean unused_data = FALSE;
 
   binding = g_object_bind_property_full (source, "value",
@@ -360,7 +401,7 @@ binding_transform_closure (void)
 {
   BindingSource *source = g_object_new (binding_source_get_type (), NULL);
   BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
-  GBinding *binding;
+  GBinding *binding G_GNUC_UNUSED;
   gboolean unused_data_1 = FALSE, unused_data_2 = FALSE;
   GClosure *c2f_clos, *f2c_clos;
 
@@ -471,7 +512,7 @@ binding_invert_boolean (void)
 
   binding = g_object_bind_property (source, "toggle",
                                     target, "toggle",
-                                    G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
+                                    G_BINDING_BIDIRECTIONAL | G_BINDING_INVERT_BOOLEAN);
 
   g_assert (source->toggle);
   g_assert (!target->toggle);
@@ -480,6 +521,10 @@ binding_invert_boolean (void)
   g_assert (!source->toggle);
   g_assert (target->toggle);
 
+  g_object_set (target, "toggle", FALSE, NULL);
+  g_assert (source->toggle);
+  g_assert (!target->toggle);
+
   g_object_unref (binding);
   g_object_unref (source);
   g_object_unref (target);
@@ -496,6 +541,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/binding/default", binding_default);
   g_test_add_func ("/binding/bidirectional", binding_bidirectional);
   g_test_add_func ("/binding/transform", binding_transform);
+  g_test_add_func ("/binding/transform-default", binding_transform_default);
   g_test_add_func ("/binding/transform-closure", binding_transform_closure);
   g_test_add_func ("/binding/chain", binding_chain);
   g_test_add_func ("/binding/sync-create", binding_sync_create);
diff --git a/gobject/tests/boxed.c b/gobject/tests/boxed.c
new file mode 100644
index 0000000..a2c8d60
--- /dev/null
+++ b/gobject/tests/boxed.c
@@ -0,0 +1,386 @@
+#include <glib-object.h>
+
+typedef struct _MyBoxed MyBoxed;
+
+struct _MyBoxed
+{
+  gint ivalue;
+  gchar *bla;
+};
+
+static gpointer
+my_boxed_copy (gpointer orig)
+{
+  MyBoxed *a = orig;
+  MyBoxed *b;
+
+  b = g_slice_new (MyBoxed);
+  b->ivalue = a->ivalue;
+  b->bla = g_strdup (a->bla);
+
+  return b;
+}
+
+static gint my_boxed_free_count;
+
+static void
+my_boxed_free (gpointer orig)
+{
+  MyBoxed *a = orig;
+
+  g_free (a->bla);
+  g_slice_free (MyBoxed, a);
+
+  my_boxed_free_count++;
+}
+
+#define MY_TYPE_BOXED (my_boxed_get_type ())
+
+G_DEFINE_BOXED_TYPE (MyBoxed, my_boxed, my_boxed_copy, my_boxed_free)
+
+static void
+test_define_boxed (void)
+{
+  MyBoxed a;
+  MyBoxed *b;
+
+  a.ivalue = 20;
+  a.bla = g_strdup ("bla");
+
+  b = g_boxed_copy (MY_TYPE_BOXED, &a);
+
+  g_assert_cmpint (b->ivalue, ==, 20);
+  g_assert_cmpstr (b->bla, ==, "bla");
+
+  g_boxed_free (MY_TYPE_BOXED, b);
+}
+
+static void
+test_boxed_ownership (void)
+{
+  GValue value = { 0, };
+  static MyBoxed boxed = { 10, "bla" };
+
+  g_value_init (&value, MY_TYPE_BOXED);
+
+  my_boxed_free_count = 0;
+
+  g_value_set_static_boxed (&value, &boxed);
+  g_value_reset (&value);
+
+  g_assert_cmpint (my_boxed_free_count, ==, 0);
+
+  g_value_set_boxed_take_ownership (&value, g_boxed_copy (MY_TYPE_BOXED, &boxed));
+  g_value_reset (&value);
+  g_assert_cmpint (my_boxed_free_count, ==, 1);
+
+  g_value_take_boxed (&value, g_boxed_copy (MY_TYPE_BOXED, &boxed));
+  g_value_reset (&value);
+  g_assert_cmpint (my_boxed_free_count, ==, 2);
+
+  g_value_set_boxed (&value, &boxed);
+  g_value_reset (&value);
+  g_assert_cmpint (my_boxed_free_count, ==, 3);
+}
+
+static void
+my_callback (gpointer user_data)
+{
+}
+
+static gint destroy_count;
+
+static void
+my_closure_notify (gpointer user_data, GClosure *closure)
+{
+  destroy_count++;
+}
+
+static void
+test_boxed_closure (void)
+{
+  GClosure *closure;
+  GClosure *closure2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_CLOSURE);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  closure = g_cclosure_new (G_CALLBACK (my_callback), "bla", my_closure_notify);
+  g_value_take_boxed (&value, closure);
+
+  closure2 = g_value_get_boxed (&value);
+  g_assert (closure2 == closure);
+
+  closure2 = g_value_dup_boxed (&value);
+  g_assert (closure2 == closure); /* closures use ref/unref for copy/free */
+  g_closure_unref (closure2);
+
+  g_value_unset (&value);
+  g_assert_cmpint (destroy_count, ==, 1);
+}
+
+static void
+test_boxed_date (void)
+{
+  GDate *date;
+  GDate *date2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_DATE);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  date = g_date_new_dmy (1, 3, 1970);
+  g_value_take_boxed (&value, date);
+
+  date2 = g_value_get_boxed (&value);
+  g_assert (date2 == date);
+
+  date2 = g_value_dup_boxed (&value);
+  g_assert (date2 != date);
+  g_assert (g_date_compare (date, date2) == 0);
+  g_date_free (date2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_value (void)
+{
+  GValue value1 = { 0, };
+  GValue *value2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_VALUE);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  g_value_init (&value1, G_TYPE_INT);
+  g_value_set_int (&value1, 26);
+
+  g_value_set_static_boxed (&value, &value1);
+
+  value2 = g_value_get_boxed (&value);
+  g_assert (value2 == &value1);
+
+  value2 = g_value_dup_boxed (&value);
+  g_assert (value2 != &value1);
+  g_assert (G_VALUE_HOLDS_INT (value2));
+  g_assert_cmpint (g_value_get_int (value2), ==, 26);
+  g_boxed_free (G_TYPE_VALUE, value2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_string (void)
+{
+  GString *v;
+  GString *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_GSTRING);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_string_new ("bla");
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 != v);
+  g_assert (g_string_equal (v, v2));
+  g_string_free (v2, TRUE);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_hashtable (void)
+{
+  GHashTable *v;
+  GHashTable *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_HASH_TABLE);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_hash_table_new (g_str_hash, g_str_equal);
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 == v);  /* hash tables use ref/unref for copy/free */
+  g_hash_table_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_array (void)
+{
+  GArray *v;
+  GArray *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_ARRAY);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_array_new (TRUE, FALSE, 1);
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 == v);  /* arrays use ref/unref for copy/free */
+  g_array_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_ptrarray (void)
+{
+  GPtrArray *v;
+  GPtrArray *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_PTR_ARRAY);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_ptr_array_new ();
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 == v);  /* ptr arrays use ref/unref for copy/free */
+  g_ptr_array_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_regex (void)
+{
+  GRegex *v;
+  GRegex *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_REGEX);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_regex_new ("a+b+", 0, 0, NULL);
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 == v);  /* regexes use ref/unref for copy/free */
+  g_regex_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_varianttype (void)
+{
+  GVariantType *v;
+  GVariantType *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_VARIANT_TYPE);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_variant_type_new ("mas");
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 != v);
+  g_assert_cmpstr (g_variant_type_peek_string (v), ==, g_variant_type_peek_string (v2));
+  g_variant_type_free (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_datetime (void)
+{
+  GDateTime *v;
+  GDateTime *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_DATE_TIME);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_date_time_new_now_local ();
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 == v); /* datetime uses ref/unref for copy/free */
+  g_date_time_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_boxed_error (void)
+{
+  GError *v;
+  GError *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_ERROR);
+  g_assert (G_VALUE_HOLDS_BOXED (&value));
+
+  v = g_error_new_literal (G_VARIANT_PARSE_ERROR,
+                           G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG,
+                           "Too damn big");
+  g_value_take_boxed (&value, v);
+
+  v2 = g_value_get_boxed (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_boxed (&value);
+  g_assert (v2 != v);
+  g_assert_cmpint (v->domain, ==, v2->domain);
+  g_assert_cmpint (v->code, ==, v2->code);
+  g_assert_cmpstr (v->message, ==, v2->message);
+  g_error_free (v2);
+
+  g_value_unset (&value);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_type_init ();
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/boxed/define", test_define_boxed);
+  g_test_add_func ("/boxed/ownership", test_boxed_ownership);
+  g_test_add_func ("/boxed/closure", test_boxed_closure);
+  g_test_add_func ("/boxed/date", test_boxed_date);
+  g_test_add_func ("/boxed/value", test_boxed_value);
+  g_test_add_func ("/boxed/string", test_boxed_string);
+  g_test_add_func ("/boxed/hashtable", test_boxed_hashtable);
+  g_test_add_func ("/boxed/array", test_boxed_array);
+  g_test_add_func ("/boxed/ptrarray", test_boxed_ptrarray);
+  g_test_add_func ("/boxed/regex", test_boxed_regex);
+  g_test_add_func ("/boxed/varianttype", test_boxed_varianttype);
+  g_test_add_func ("/boxed/error", test_boxed_error);
+  g_test_add_func ("/boxed/datetime", test_boxed_datetime);
+
+  return g_test_run ();
+}
diff --git a/gobject/tests/enums.c b/gobject/tests/enums.c
new file mode 100644
index 0000000..f4076f2
--- /dev/null
+++ b/gobject/tests/enums.c
@@ -0,0 +1,113 @@
+#include <glib-object.h>
+
+static const GEnumValue my_enum_values[] =
+{
+  { 1, "the first value", "one" },
+  { 2, "the second value", "two" },
+  { 3, "the third value", "three" },
+  { 0, NULL, NULL }
+};
+
+static void
+test_enum_basic (void)
+{
+  GType type;
+  GEnumClass *class;
+  GEnumValue *val;
+  GValue value = { 0, };
+
+  type = g_enum_register_static ("MyEnum", my_enum_values);
+
+  g_value_init (&value, type);
+  g_assert (G_VALUE_HOLDS_ENUM (&value));
+
+  g_value_set_enum (&value, 2);
+  g_assert_cmpint (g_value_get_enum (&value), ==, 2);
+  g_value_unset (&value);
+
+  class = g_type_class_ref (type);
+
+  g_assert_cmpint (class->minimum, ==, 1);
+  g_assert_cmpint (class->maximum, ==, 3);
+  g_assert_cmpint (class->n_values, ==, 3);
+
+  val = g_enum_get_value (class, 2);
+  g_assert (val != NULL);
+  g_assert_cmpstr (val->value_name, ==, "the second value");
+  val = g_enum_get_value (class, 15);
+  g_assert (val == NULL);
+
+  val = g_enum_get_value_by_name (class, "the third value");
+  g_assert (val != NULL);
+  g_assert_cmpint (val->value, ==, 3);
+  val = g_enum_get_value_by_name (class, "the color purple");
+  g_assert (val == NULL);
+
+  val = g_enum_get_value_by_nick (class, "one");
+  g_assert (val != NULL);
+  g_assert_cmpint (val->value, ==, 1);
+  val = g_enum_get_value_by_nick (class, "purple");
+  g_assert (val == NULL);
+}
+
+static const GFlagsValue my_flag_values[] =
+{
+  { 1, "the first flag", "one" },
+  { 2, "the second flag", "two" },
+  { 8, "the third flag", "three" },
+  { 0, NULL, NULL }
+};
+
+
+static void
+test_flags_basic (void)
+{
+  GType type;
+  GFlagsClass *class;
+  GFlagsValue *val;
+  GValue value = { 0, };
+
+  type = g_flags_register_static ("MyFlags", my_flag_values);
+
+  g_value_init (&value, type);
+  g_assert (G_VALUE_HOLDS_FLAGS (&value));
+
+  g_value_set_flags (&value, 2|8);
+  g_assert_cmpint (g_value_get_flags (&value), ==, 2|8);
+  g_value_unset (&value);
+
+  class = g_type_class_ref (type);
+
+  g_assert_cmpint (class->mask, ==, 1|2|8);
+  g_assert_cmpint (class->n_values, ==, 3);
+
+  val = g_flags_get_first_value (class, 2|8);
+  g_assert (val != NULL);
+  g_assert_cmpstr (val->value_name, ==, "the second flag");
+  val = g_flags_get_first_value (class, 16);
+  g_assert (val == NULL);
+
+  val = g_flags_get_value_by_name (class, "the third flag");
+  g_assert (val != NULL);
+  g_assert_cmpint (val->value, ==, 8);
+  val = g_flags_get_value_by_name (class, "the color purple");
+  g_assert (val == NULL);
+
+  val = g_flags_get_value_by_nick (class, "one");
+  g_assert (val != NULL);
+  g_assert_cmpint (val->value, ==, 1);
+  val = g_flags_get_value_by_nick (class, "purple");
+  g_assert (val == NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_type_init ();
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/enum/basic", test_enum_basic);
+  g_test_add_func ("/flags/basic", test_flags_basic);
+
+  return g_test_run ();
+}
diff --git a/gobject/tests/param.c b/gobject/tests/param.c
new file mode 100644
index 0000000..d63e84f
--- /dev/null
+++ b/gobject/tests/param.c
@@ -0,0 +1,223 @@
+#include <glib-object.h>
+
+static void
+test_param_value (void)
+{
+  GParamSpec *p, *p2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_PARAM);
+  g_assert (G_VALUE_HOLDS_PARAM (&value));
+
+  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+
+  g_value_take_param (&value, p);
+  p2 = g_value_get_param (&value);
+  g_assert (p2 == p);
+
+  p2 = g_value_dup_param (&value);
+  g_assert (p2 == p); /* param specs use ref/unref for copy/free */
+  g_param_spec_unref (p2);
+
+  g_value_unset (&value);
+}
+
+static gint destroy_count;
+
+static void
+my_destroy (gpointer data)
+{
+  destroy_count++;
+}
+
+static void
+test_param_qdata (void)
+{
+  GParamSpec *p;
+  gchar *bla;
+  GQuark q;
+
+  q = g_quark_from_string ("bla");
+
+  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+  g_param_spec_set_qdata (p, q, "bla");
+  bla = g_param_spec_get_qdata (p, q);
+  g_assert_cmpstr (bla, ==, "bla");
+
+  g_assert_cmpint (destroy_count, ==, 0);
+  g_param_spec_set_qdata_full (p, q, "bla", my_destroy);
+  g_param_spec_set_qdata_full (p, q, "blabla", my_destroy);
+  g_assert_cmpint (destroy_count, ==, 1);
+  g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla");
+  g_assert_cmpint (destroy_count, ==, 1);
+  g_assert (g_param_spec_get_qdata (p, q) == NULL);
+
+  g_param_spec_ref_sink (p);
+
+  g_param_spec_unref (p);
+}
+
+static void
+test_param_validate (void)
+{
+  GParamSpec *p;
+  GValue value = { 0, };
+
+  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+
+  g_value_init (&value, G_TYPE_INT);
+  g_value_set_int (&value, 100);
+  g_assert (!g_param_value_defaults (p, &value));
+  g_assert (g_param_value_validate (p, &value));
+  g_assert_cmpint (g_value_get_int (&value), ==, 20);
+
+  g_param_value_set_default (p, &value);
+  g_assert (g_param_value_defaults (p, &value));
+  g_assert_cmpint (g_value_get_int (&value), ==, 10);
+
+  g_param_spec_unref (p);
+}
+
+static void
+test_param_strings (void)
+{
+  GParamSpec *p;
+
+  /* test canonicalization */
+  p = g_param_spec_int ("my_int:bla", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+
+  g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int-bla");
+  g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int");
+  g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb");
+
+  g_param_spec_unref (p);
+
+  /* test nick defaults to name */
+  p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE);
+
+  g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
+  g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int");
+  g_assert (g_param_spec_get_blurb (p) == NULL);
+
+  g_param_spec_unref (p);
+}
+
+static void
+test_param_convert (void)
+{
+  GParamSpec *p;
+  GValue v1 = { 0, };
+  GValue v2 = { 0, };
+
+  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+  g_value_init (&v1, G_TYPE_UINT);
+  g_value_set_uint (&v1, 43);
+
+  g_value_init (&v2, G_TYPE_INT);
+  g_value_set_int (&v2, -4);
+
+  g_assert (!g_param_value_convert (p, &v1, &v2, TRUE));
+  g_assert_cmpint (g_value_get_int (&v2), ==, -4);
+
+  g_assert (g_param_value_convert (p, &v1, &v2, FALSE));
+  g_assert_cmpint (g_value_get_int (&v2), ==, 20);
+
+  g_param_spec_unref (p);
+}
+
+static void
+test_value_transform (void)
+{
+  GValue src = { 0, };
+  GValue dest = { 0, };
+
+#define CHECK_INT_CONVERSION(type, getter, value)                       \
+  g_assert (g_value_type_transformable (G_TYPE_INT, type));             \
+  g_value_init (&src, G_TYPE_INT);                                      \
+  g_value_init (&dest, type);                                           \
+  g_value_set_int (&src, value);                                        \
+  g_assert (g_value_transform (&src, &dest));                           \
+  g_assert_cmpint (g_value_get_##getter (&dest), ==, value);            \
+  g_value_unset (&src);                                                 \
+  g_value_unset (&dest);
+
+  CHECK_INT_CONVERSION(G_TYPE_CHAR, char, -124)
+  CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124)
+  CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
+  CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
+  CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345)
+  CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345)
+  CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0)
+  CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345)
+  CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678)
+  CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
+  CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678)
+  CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
+  CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
+  CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
+
+#define CHECK_BOOLEAN_CONVERSION(type, setter, value)                   \
+  g_assert (g_value_type_transformable (type, G_TYPE_BOOLEAN));         \
+  g_value_init (&src, type);                                            \
+  g_value_init (&dest, G_TYPE_BOOLEAN);                                 \
+  g_value_set_##setter (&src, value);                                   \
+  g_assert (g_value_transform (&src, &dest));                           \
+  g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE);              \
+  g_value_set_##setter (&src, 0);                                       \
+  g_assert (g_value_transform (&src, &dest));                           \
+  g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE);             \
+  g_value_unset (&src);                                                 \
+  g_value_unset (&dest);
+
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345)
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345)
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678)
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678)
+  CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
+
+#define CHECK_STRING_CONVERSION(int_type, setter, int_value)            \
+  g_assert (g_value_type_transformable (int_type, G_TYPE_STRING));      \
+  g_value_init (&src, int_type);                                        \
+  g_value_init (&dest, G_TYPE_STRING);                                  \
+  g_value_set_##setter (&src, int_value);                               \
+  g_assert (g_value_transform (&src, &dest));                           \
+  g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value);         \
+  g_value_unset (&src);                                                 \
+  g_value_unset (&dest);
+
+  CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345)
+  CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345)
+  CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678)
+  CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
+  CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678)
+  CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
+  CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000)
+  CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567)
+
+  g_assert (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR));
+  g_value_init (&src, G_TYPE_STRING);
+  g_value_init (&dest, G_TYPE_CHAR);
+  g_value_set_static_string (&src, "bla");
+  g_value_set_char (&dest, 'c');
+  g_assert (!g_value_transform (&src, &dest));
+  g_assert_cmpint (g_value_get_char (&dest), ==, 'c');
+  g_value_unset (&src);
+  g_value_unset (&dest);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_type_init ();
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/param/value", test_param_value);
+  g_test_add_func ("/param/strings", test_param_strings);
+  g_test_add_func ("/param/qdata", test_param_qdata);
+  g_test_add_func ("/param/validate", test_param_validate);
+  g_test_add_func ("/param/convert", test_param_convert);
+  g_test_add_func ("/value/transform", test_value_transform);
+
+  return g_test_run ();
+}
diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c
index 38354a1..37793dd 100644
--- a/gobject/tests/reference.c
+++ b/gobject/tests/reference.c
@@ -1,6 +1,113 @@
 #include <glib-object.h>
 
 static void
+test_fundamentals (void)
+{
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_NONE));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INTERFACE));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_CHAR));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UCHAR));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOOLEAN));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_LONG));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ULONG));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT64));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT64));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ENUM));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLAGS));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLOAT));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_DOUBLE));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_STRING));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_POINTER));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOXED));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_PARAM));
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_OBJECT));
+  g_assert (G_TYPE_OBJECT == g_object_get_type ());
+  g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_VARIANT));
+  g_assert (G_TYPE_VARIANT == g_variant_get_gtype ());
+  g_assert (G_TYPE_IS_DERIVED (G_TYPE_INITIALLY_UNOWNED));
+
+  g_assert (g_type_fundamental_next () == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST));
+}
+
+static void
+test_type_qdata (void)
+{
+  gchar *data;
+
+  g_type_set_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"), "bla");
+  data = g_type_get_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"));
+  g_assert_cmpstr (data, ==, "bla");
+}
+
+static void
+test_type_query (void)
+{
+  GTypeQuery query;
+
+  g_type_query (G_TYPE_ENUM, &query);
+  g_assert_cmpint (query.type, ==, G_TYPE_ENUM);
+  g_assert_cmpstr (query.type_name, ==, "GEnum");
+  g_assert_cmpint (query.class_size, ==, sizeof (GEnumClass));
+  g_assert_cmpint (query.instance_size, ==, 0);
+}
+
+typedef struct _MyObject MyObject;
+typedef struct _MyObjectClass MyObjectClass;
+typedef struct _MyObjectClassPrivate MyObjectClassPrivate;
+
+struct _MyObject
+{
+  GObject parent_instance;
+
+  gint count;
+};
+
+struct _MyObjectClass
+{
+  GObjectClass parent_class;
+};
+
+struct _MyObjectClassPrivate
+{
+  gint secret_class_count;
+};
+
+G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT,
+                         g_type_add_class_private (g_define_type_id, sizeof (MyObjectClassPrivate)) );
+
+static void
+my_object_init (MyObject *obj)
+{
+  obj->count = 42;
+}
+
+static void
+my_object_class_init (MyObjectClass *klass)
+{
+}
+
+static void
+test_class_private (void)
+{
+  GObject *obj;
+  MyObjectClass *class;
+  MyObjectClassPrivate *priv;
+
+  obj = g_object_new (my_object_get_type (), NULL);
+
+  class = g_type_class_ref (my_object_get_type ());
+  priv = G_TYPE_CLASS_GET_PRIVATE (class, my_object_get_type (), MyObjectClassPrivate);
+  priv->secret_class_count = 13;
+  g_type_class_unref (class);
+
+  g_object_unref (obj);
+
+  g_assert_cmpint (g_type_qname (my_object_get_type ()), ==, g_quark_from_string ("MyObject"));
+}
+
+static void
 test_clear (void)
 {
   GObject *o = NULL;
@@ -22,6 +129,104 @@ test_clear (void)
   g_object_unref (tmp);
 }
 
+static void
+test_clear_function (void)
+{
+  volatile GObject *o = NULL;
+  GObject *tmp;
+
+  (g_clear_object) (&o);
+  g_assert (o == NULL);
+
+  tmp = g_object_new (G_TYPE_OBJECT, NULL);
+  g_assert_cmpint (tmp->ref_count, ==, 1);
+  o = g_object_ref (tmp);
+  g_assert (o != NULL);
+
+  g_assert_cmpint (tmp->ref_count, ==, 2);
+  (g_clear_object) (&o);
+  g_assert_cmpint (tmp->ref_count, ==, 1);
+  g_assert (o == NULL);
+
+  g_object_unref (tmp);
+}
+
+static void
+test_object_value (void)
+{
+  GObject *v;
+  GObject *v2;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_OBJECT);
+
+  v = g_object_new (G_TYPE_OBJECT, NULL);
+  g_value_take_object (&value, v);
+
+  v2 = g_value_get_object (&value);
+  g_assert (v2 == v);
+
+  v2 = g_value_dup_object (&value);
+  g_assert (v2 == v);  /* objects use ref/unref for copy/free */
+  g_object_unref (v2);
+
+  g_value_unset (&value);
+}
+
+static void
+test_initially_unowned (void)
+{
+  GObject *obj;
+
+  obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
+  g_assert (g_object_is_floating (obj));
+  g_assert_cmpint (obj->ref_count, ==, 1);
+
+  g_object_ref_sink (obj);
+  g_assert (!g_object_is_floating (obj));
+  g_assert_cmpint (obj->ref_count, ==, 1);
+
+  g_object_ref_sink (obj);
+  g_assert (!g_object_is_floating (obj));
+  g_assert_cmpint (obj->ref_count, ==, 2);
+
+  g_object_unref (obj);
+  g_assert_cmpint (obj->ref_count, ==, 1);
+
+  g_object_force_floating (obj);
+  g_assert (g_object_is_floating (obj));
+  g_assert_cmpint (obj->ref_count, ==, 1);
+
+  g_object_ref_sink (obj);
+  g_object_unref (obj);
+}
+
+static void
+test_weak_pointer (void)
+{
+  GObject *obj;
+  gpointer weak;
+  gpointer weak2;
+
+  weak = weak2 = obj = g_object_new (G_TYPE_OBJECT, NULL);
+  g_assert_cmpint (obj->ref_count, ==, 1);
+
+  g_object_add_weak_pointer (obj, &weak);
+  g_object_add_weak_pointer (obj, &weak2);
+  g_assert_cmpint (obj->ref_count, ==, 1);
+  g_assert (weak == obj);
+  g_assert (weak2 == obj);
+
+  g_object_remove_weak_pointer (obj, &weak2);
+  g_assert_cmpint (obj->ref_count, ==, 1);
+  g_assert (weak == obj);
+  g_assert (weak2 == obj);
+
+  g_object_unref (obj);
+  g_assert (weak == NULL);
+  g_assert (weak2 == obj);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -29,7 +234,15 @@ main (int argc, char **argv)
 
   g_type_init ();
 
+  g_test_add_func ("/type/fundamentals", test_fundamentals);
+  g_test_add_func ("/type/qdata", test_type_qdata);
+  g_test_add_func ("/type/query", test_type_query);
+  g_test_add_func ("/type/class-private", test_class_private);
   g_test_add_func ("/object/clear", test_clear);
+  g_test_add_func ("/object/clear-function", test_clear_function);
+  g_test_add_func ("/object/value", test_object_value);
+  g_test_add_func ("/object/initially-unowned", test_initially_unowned);
+  g_test_add_func ("/object/weak-pointer", test_weak_pointer);
 
   return g_test_run ();
 }



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