summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2018-10-23 19:43:01 -0500
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2018-11-14 22:47:39 -0600
commit8d42b0246b8338e140354fb9ffb3004272b185e3 (patch)
treec2d2017d40ed4b81aa04a888a9f920642be06988
parent86c073dba9d82ef3f1bc3d3116b058b9b5c3b1eb (diff)
downloadglib-8d42b0246b8338e140354fb9ffb3004272b185e3.tar.gz
gobject, tests: add tests for autoptr (and lists) with declared
Add tests using an object declared with G_DECLARE_FINAL_TYPE, that is derived from another, declared using G_DECLARE_DERIVABLE_TYPE, and that thus uses _GLIB_DEFINE_AUTOPTR_CHAINUP to define cleanup functions. And verify that both g_autoptr(Type) and g_auto(s)list(Type) work
-rw-r--r--gobject/tests/Makefile.am6
-rw-r--r--gobject/tests/autoptr.c173
-rw-r--r--gobject/tests/meson.build4
3 files changed, 183 insertions, 0 deletions
diff --git a/gobject/tests/Makefile.am b/gobject/tests/Makefile.am
index 84823cc47..ae94d5010 100644
--- a/gobject/tests/Makefile.am
+++ b/gobject/tests/Makefile.am
@@ -26,6 +26,12 @@ test_programs = \
signal-handler \
$(NULL)
+if HAVE_GCC
+test_programs += \
+ autoptr \
+ $(NULL)
+endif
+
# -----------------------------------------------------------------------------
test_programs += ifaceproperties
diff --git a/gobject/tests/autoptr.c b/gobject/tests/autoptr.c
new file mode 100644
index 000000000..544938fbd
--- /dev/null
+++ b/gobject/tests/autoptr.c
@@ -0,0 +1,173 @@
+/* GLib testing framework examples and tests
+ * Copyright (C) 2018 Canonical Ltd
+ * Authors: Marco Trevisan <marco@ubuntu.com>
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+
+#include <glib-object.h>
+#include <string.h>
+
+G_DECLARE_DERIVABLE_TYPE (TestAutoCleanupBase, test_base_auto_cleanup, TEST, BASE_AUTO_CLEANUP, GObject)
+
+struct _TestAutoCleanupBaseClass {
+ GObjectClass parent_class;
+};
+
+G_DECLARE_FINAL_TYPE (TestAutoCleanup, test_auto_cleanup, TEST, AUTO_CLEANUP, TestAutoCleanupBase)
+
+struct _TestAutoCleanup
+{
+ TestAutoCleanupBase parent_instance;
+};
+
+G_DEFINE_TYPE (TestAutoCleanup, test_auto_cleanup, G_TYPE_OBJECT)
+
+static void
+test_auto_cleanup_class_init (TestAutoCleanupClass *class)
+{
+}
+
+static void
+test_auto_cleanup_init (TestAutoCleanup *tac)
+{
+}
+
+static TestAutoCleanup *
+test_auto_cleanup_new (void)
+{
+ return g_object_new (test_auto_cleanup_get_type (), NULL);
+}
+
+/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
+ * autocleanup functions, defined using the ones of the base type (defined with
+ * G_DECLARE_DERIVABLE_TYPE) and so that it can be used with g_autoptr */
+static void
+test_autoptr (void)
+{
+ TestAutoCleanup *tac_ptr = test_auto_cleanup_new ();
+ g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr);
+
+ {
+ g_autoptr (TestAutoCleanup) tac = tac_ptr;
+ }
+#ifdef __GNUC__
+ g_assert_null (tac_ptr);
+#endif
+}
+
+/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
+ * autocleanup functions, defined using the ones of the base type (defined with
+ * G_DECLARE_DERIVABLE_TYPE) and that stealing an autopointer works properly */
+static void
+test_autoptr_steal (void)
+{
+ g_autoptr (TestAutoCleanup) tac1 = test_auto_cleanup_new ();
+ TestAutoCleanup *tac_ptr = tac1;
+
+ g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr);
+
+ {
+ g_autoptr (TestAutoCleanup) tac2 = g_steal_pointer (&tac1);
+ g_assert_nonnull (tac_ptr);
+ g_assert_null (tac1);
+ g_assert_true (tac2 == tac_ptr);
+ }
+#ifdef __GNUC__
+ g_assert_null (tac_ptr);
+#endif
+}
+
+/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
+ * autolist cleanup functions defined using the ones of the parent type
+ * and so that can be used with g_autolist, and that freeing the list correctly
+ * unrefs the object too */
+static void
+test_autolist (void)
+{
+ TestAutoCleanup *tac1 = test_auto_cleanup_new ();
+ TestAutoCleanup *tac2 = test_auto_cleanup_new ();
+ g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new ();
+
+ g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1);
+ g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2);
+ g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3);
+
+ {
+ g_autolist (TestAutoCleanup) l = NULL;
+
+ l = g_list_prepend (l, tac1);
+ l = g_list_prepend (l, tac2);
+ }
+
+ /* Only assert if autoptr works */
+#ifdef __GNUC__
+ g_assert_null (tac1);
+ g_assert_null (tac2);
+#endif
+ g_assert_nonnull (tac3);
+
+ g_clear_object (&tac3);
+ g_assert_null (tac3);
+}
+
+/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
+ * autoslist cleanup functions (defined using the ones of the base type declared
+ * with G_DECLARE_DERIVABLE_TYPE) and so that can be used with g_autoslist, and
+ * that freeing the slist correctly unrefs the object too */
+static void
+test_autoslist (void)
+{
+ TestAutoCleanup *tac1 = test_auto_cleanup_new ();
+ TestAutoCleanup *tac2 = test_auto_cleanup_new ();
+ g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new ();
+
+ g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1);
+ g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2);
+ g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3);
+
+ {
+ g_autoslist (TestAutoCleanup) l = NULL;
+
+ l = g_slist_prepend (l, tac1);
+ l = g_slist_prepend (l, tac2);
+ }
+
+ /* Only assert if autoptr works */
+#ifdef __GNUC__
+ g_assert_null (tac1);
+ g_assert_null (tac2);
+#endif
+ g_assert_nonnull (tac3);
+
+ g_clear_object (&tac3);
+ g_assert_null (tac3);
+}
+
+int
+main (int argc, gchar *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/autoptr/autoptr", test_autoptr);
+ g_test_add_func ("/autoptr/autoptr_steal", test_autoptr_steal);
+ g_test_add_func ("/autoptr/autolist", test_autolist);
+ g_test_add_func ("/autoptr/autoslist", test_autoslist);
+
+ return g_test_run ();
+}
diff --git a/gobject/tests/meson.build b/gobject/tests/meson.build
index 51571c076..44d4588d1 100644
--- a/gobject/tests/meson.build
+++ b/gobject/tests/meson.build
@@ -51,6 +51,10 @@ gobject_tests = {
},
}
+if cc.get_id() != 'msvc'
+ gobject_tests += {'autoptr' : {}}
+endif
+
# FIXME: put common bits of test environment() in one location
# Not entirely random of course, but at least it changes over time
random_number = minor_version + meson.version().split('.').get(1).to_int()