[glibmm] Add tests/glibmm_refptr.



commit a2195549d6477bccfd6365388997d2d5e1752032
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Jul 27 09:23:31 2015 +0200

    Add tests/glibmm_refptr.
    
    To test refcounting, though I'm not sure that the test for the
    move constructor is quite right.

 tests/Makefile.am           |    2 +
 tests/glibmm_refptr/main.cc |  215 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 217 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c2b0458..8f35cbb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -41,6 +41,7 @@ check_PROGRAMS =                              \
        glibmm_bool_arrayhandle/test            \
        glibmm_null_vectorutils/test            \
        glibmm_null_containerhandle/test        \
+       glibmm_refptr/test              \
        glibmm_refptr_sigc_bind/test            \
        glibmm_bytearray/test
 
@@ -101,5 +102,6 @@ glibmm_null_vectorutils_test_SOURCES     = glibmm_null_vectorutils/main.cc
 glibmm_null_vectorutils_test_LDADD       = $(giomm_ldadd)
 glibmm_null_containerhandle_test_SOURCES = glibmm_null_containerhandle/main.cc
 glibmm_null_containerhandle_test_LDADD   = $(giomm_ldadd)
+glibmm_refptr_test_SOURCES               = glibmm_refptr/main.cc
 glibmm_refptr_sigc_bind_test_SOURCES     = glibmm_refptr_sigc_bind/main.cc
 glibmm_bytearray_test_SOURCES            = glibmm_bytearray/main.cc
diff --git a/tests/glibmm_refptr/main.cc b/tests/glibmm_refptr/main.cc
new file mode 100644
index 0000000..269c7b0
--- /dev/null
+++ b/tests/glibmm_refptr/main.cc
@@ -0,0 +1,215 @@
+// Bug 564005 - Valgrind errors and crash on exit with Gtk::UIManager
+// Bug 154498 - Unnecessary warning on console: signalproxy_connectionnode.cc
+
+
+#include <glibmm.h>
+#include <sigc++/sigc++.h>
+#include <iostream>
+#include <stdlib.h>
+
+#define ACTIVATE_BUG 1
+
+// A class with its own reference-count, for use with RefPtr.
+class Something
+{
+public:
+  Something()
+  : ref_count_(1),
+    max_ref_count_(ref_count_)
+  {}
+
+  void reference()
+  {
+    ++ref_count_;
+
+    //Track the highest-ever max count.
+    if(max_ref_count_ < ref_count_)
+      max_ref_count_ = ref_count_;
+  }
+
+  void unreference()
+  {
+    if (--ref_count_ <= 0)
+      delete this;
+  }
+
+  //Just so we can check it in our test.
+  int ref_count()
+  {
+    return ref_count_;
+  }
+
+  //Just so we can check it in our test.
+  int max_ref_count()
+  {
+    return max_ref_count_;
+  }
+
+
+private:
+  int ref_count_;
+  int max_ref_count_;
+};
+
+class Parent
+{
+public:
+  explicit Parent(const Glib::RefPtr<Something>& something)
+  : something_(something),
+    was_constructed_via_copy_constructor_(true),
+    was_constructed_via_move_constructor_(false)
+  {
+  }
+
+  explicit Parent(const Glib::RefPtr<Something>&& something)
+  : something_(std::move(something)),
+    was_constructed_via_copy_constructor_(false),
+    was_constructed_via_move_constructor_(true)
+  {
+  }
+
+  //Non copyable
+  Parent(const Parent& src) = delete;
+  Parent& operator=(const Parent& src) = delete;
+
+  bool was_constructed_via_copy_constructor() const
+  {
+    return was_constructed_via_copy_constructor_;
+  }
+
+  bool was_constructed_via_move_constructor() const
+  {
+    return was_constructed_via_move_constructor_;
+  }
+
+  int something_ref_count() const
+  {
+    return something_->ref_count();
+  }
+
+  int something_max_ref_count() const
+  {
+    return something_->max_ref_count();
+  }
+
+private:
+  Glib::RefPtr<Something> something_;
+  bool was_constructed_via_copy_constructor_;
+  bool was_constructed_via_move_constructor_;
+
+};
+
+static
+void test_initial_refcount()
+{
+  Glib::RefPtr<Something> refSomething (new Something());
+  g_assert_cmpint(refSomething->ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+}
+
+static
+void test_refptr_copy_constructor()
+{
+  Glib::RefPtr<Something> refSomething (new Something());
+  g_assert_cmpint(refSomething->ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+
+  {
+    Glib::RefPtr<Something> refSomething2(refSomething);
+    g_assert_cmpint(refSomething->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
+  }
+
+  //Test the refcount after other references should have been released
+  //when other RefPtrs went out of scope:
+  g_assert_cmpint(refSomething->ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
+}
+
+static
+void test_refptr_assignment_operator()
+{
+  Glib::RefPtr<Something> refSomething (new Something());
+  g_assert_cmpint(refSomething->ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
+
+  {
+    Glib::RefPtr<Something> refSomething2 = refSomething;
+    g_assert_cmpint(refSomething->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
+    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
+  }
+
+  //Test the refcount after other references should have been released
+  //when other RefPtrs went out of scope:
+  g_assert_cmpint(refSomething->ref_count(), ==, 1);
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
+}
+
+
+
+static
+Glib::RefPtr<Something> get_something()
+{
+  static Glib::RefPtr<Something> something_to_get;
+
+  //Reinitialize it each time:
+  something_to_get = Glib::RefPtr<Something>(new Something());
+
+  return something_to_get;
+}
+
+static
+void test_refptr_with_parent_copy_constructor()
+{
+  //We use get_something() because test_refptr_with_parent_move_constructor() does.
+  Glib::RefPtr<Something> refSomething = get_something();
+  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
+
+  {
+    Parent parent(refSomething);
+    g_assert(!parent.was_constructed_via_move_constructor());
+    g_assert(parent.was_constructed_via_copy_constructor());
+    g_assert_cmpint(parent.something_ref_count(), ==, 3); //1 here, 1 in parent, and 1 inside get_something()
+    g_assert_cmpint(parent.something_max_ref_count(), ==, 3);
+  }
+
+  //Test the refcount after other references should have been released
+  //when other RefPtrs went out of scope:
+  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
+  g_assert_cmpint(refSomething->max_ref_count(), ==, 3);
+}
+
+static
+void test_refptr_with_parent_move_constructor()
+{
+  Parent parent(get_something());
+  g_assert(parent.was_constructed_via_move_constructor());
+  g_assert(!parent.was_constructed_via_copy_constructor());
+  g_assert_cmpint(parent.something_ref_count(), ==, 2); //1 in parent and 1 inside get_something()
+  g_assert_cmpint(parent.something_max_ref_count(), ==, 3); //TODO: Avoid the extra ref in RefPtr::swap()?
+}
+
+int main(int, char**)
+{
+  //Test initial refcount:
+  test_initial_refcount();
+
+  //Test refcount when using the RefPtr copy constructor:
+  test_refptr_copy_constructor();
+
+  //Test refcount when using the RefPtr assignment operator (operator=):
+  test_refptr_assignment_operator();
+
+  //Test the refcount when another class makes a copy via its constructor:
+  test_refptr_with_parent_copy_constructor();
+
+  //Test the refcount when another class makes a copy via its
+  //(perfect-forwarding)move constructor, which should not involve a temporary
+  //instance:
+  test_refptr_with_parent_move_constructor();  
+
+  return EXIT_SUCCESS;
+}


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