From dafac00334ffa0ccc32696a208b2531cb4f44947 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Sun, 17 Jul 2005 20:18:14 +0000 Subject: [PATCH] Added unit tests for smart pointer. --- SConstruct | 3 +- src/object.cpp | 12 ++ tests/utility/smartPtrTest.cpp | 195 +++++++++++++++++++++++++++++++++ vmime/object.hpp | 13 +++ vmime/utility/smartPtr.hpp | 15 +++ 5 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 tests/utility/smartPtrTest.cpp diff --git a/SConstruct b/SConstruct index 68aace55..3f814709 100644 --- a/SConstruct +++ b/SConstruct @@ -348,7 +348,8 @@ libvmimetest_sources = [ [ 'tests/utility/stringProxyTest', [ 'tests/utility/stringProxyTest.cpp' ] ], [ 'tests/utility/stringUtilsTest', [ 'tests/utility/stringUtilsTest.cpp' ] ], [ 'tests/utility/pathTest', [ 'tests/utility/pathTest.cpp' ] ], - [ 'tests/utility/urlTest', [ 'tests/utility/urlTest.cpp' ] ] + [ 'tests/utility/urlTest', [ 'tests/utility/urlTest.cpp' ] ], + [ 'tests/utility/smartPtrTest', [ 'tests/utility/smartPtrTest.cpp' ] ] ] libvmime_autotools = [ diff --git a/src/object.cpp b/src/object.cpp index 481a3564..dc4602c7 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -126,5 +126,17 @@ weak_ref object::thisWeakRef() const } +const int object::getStrongRefCount() const +{ + return m_strongCount; +} + + +const int object::getWeakRefCount() const +{ + return static_cast (m_weakRefs.size()); +} + + } // vmime diff --git a/tests/utility/smartPtrTest.cpp b/tests/utility/smartPtrTest.cpp new file mode 100644 index 00000000..9bb8a49d --- /dev/null +++ b/tests/utility/smartPtrTest.cpp @@ -0,0 +1,195 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// This program 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. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "../lib/unit++/unit++.h" + +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + +#include "vmime/utility/smartPtr.hpp" + +using namespace unitpp; + + +namespace +{ + class smartPtrTest : public suite + { + struct A : public vmime::object + { + const int strongCount() const { return getStrongRefCount(); } + const int weakCount() const { return getWeakRefCount(); } + }; + + struct B : public virtual A { }; + struct C : public virtual A { }; + struct D : public B, public C { }; + + class R : public A + { + public: + + R(bool* aliveFlag) : m_aliveFlag(aliveFlag) { *m_aliveFlag = true; } + ~R() { *m_aliveFlag = false; } + + private: + + bool* m_aliveFlag; + }; + + + void testNull() + { + vmime::ref r1; + + assert_true("1", r1 == NULL); + assert_true("2", r1 == 0); + assert_true("3", NULL == r1); + assert_true("4", 0 == r1); + assert_true("5", !r1); + assert_true("6", r1 == vmime::null); + assert_true("7", vmime::null == r1); + assert_eq("8", static_cast (0), r1.get()); + + const A* p = r1; + assert_eq("9", static_cast (0), p); + } + + void testRefCounting() + { + bool o1_alive; + vmime::ref r1 = vmime::create (&o1_alive); + + assert_true("1", r1.get() != 0); + assert_true("2", o1_alive); + assert_eq("3", 1, r1->strongCount()); + assert_eq("4", 0, r1->weakCount()); + + vmime::ref r2 = r1; + + assert_true("5", o1_alive); + assert_eq("6", 2, r1->strongCount()); + assert_eq("7", 0, r1->weakCount()); + + bool o2_alive; + vmime::ref r3 = vmime::create (&o2_alive); + + r2 = r3; + + assert_true("8", o1_alive); + assert_true("9", o2_alive); + assert_eq("10", 1, r1->strongCount()); + assert_eq("11", 2, r2->strongCount()); + assert_eq("12", 2, r3->strongCount()); + + { + vmime::ref r4; + + r4 = r1; + + assert_true("13", o1_alive); + assert_true("14", o2_alive); + assert_eq("15", 2, r4->strongCount()); + assert_eq("16", 2, r1->strongCount()); + + r1 = NULL; + + assert_true("17", o1_alive); + assert_true("18", o2_alive); + assert_eq("19", 1, r4->strongCount()); + + // Here, object1 will be deleted + } + + assert_true("20", !o1_alive); + assert_true("21", o2_alive); + + { + vmime::weak_ref w1 = r3; + + assert_eq("22", 1, r3->weakCount()); + } + + assert_true("23", o2_alive); + assert_eq("24", 2, r3->strongCount()); + assert_eq("25", 0, r3->weakCount()); + } + + void testWeakRef() + { + vmime::ref r1 = vmime::create (); + vmime::weak_ref w1 = r1; + + assert_true("1", r1.get() != 0); + assert_true("2", r1.get() == w1.get()); + + { + vmime::ref r2 = r1; + + assert_true("3", r1.get() == r2.get()); + assert_true("4", r1.get() == w1.get()); + } + + assert_true("5", r1.get() != 0); + assert_true("6", r1.get() == w1.get()); + + r1 = 0; + + assert_true("7", w1.get() == 0); + } + + void testCast() + { + // Explicit upcast + vmime::ref r1 = vmime::create (); + vmime::ref r2 = r1.dynamicCast (); + + assert_true("1", r2.get() == dynamic_cast (r1.get())); + assert_true("2", 0 == r1.dynamicCast ().get()); + + // Implicit downcast + vmime::ref r3 = vmime::create (); + vmime::ref r4 = r3; + + assert_true("3", r4.get() == dynamic_cast (r3.get())); + } + + public: + + smartPtrTest() : suite("vmime::utility::url") + { + // VMime initialization + vmime::platformDependant::setHandler(); + + add("Null", testcase(this, "TestNull", &smartPtrTest::testNull)); + add("RefCounting", testcase(this, "TestRefCounting", &smartPtrTest::testRefCounting)); + add("WeakRef", testcase(this, "TestWeakRef", &smartPtrTest::testWeakRef)); + add("Cast", testcase(this, "TestCast", &smartPtrTest::testCast)); + + suite::main().add("vmime::utility::smartPtr", this); + } + + }; + + smartPtrTest* theTest = new smartPtrTest(); +} + diff --git a/vmime/object.hpp b/vmime/object.hpp index b8024e56..471670df 100644 --- a/vmime/object.hpp +++ b/vmime/object.hpp @@ -92,6 +92,19 @@ protected: */ weak_ref thisWeakRef() const; + /** Return the number of strong refs to this object. + * For debugging purposes only. + * + * @return strong reference count + */ + const int getStrongRefCount() const; + + /** Return the number of weak refs to this object. + * For debugging purposes only. + * + * @return weak reference count + */ + const int getWeakRefCount() const; #endif // VMIME_BUILDING_DOC private: diff --git a/vmime/utility/smartPtr.hpp b/vmime/utility/smartPtr.hpp index 65ea2ff6..c20d4c06 100644 --- a/vmime/utility/smartPtr.hpp +++ b/vmime/utility/smartPtr.hpp @@ -208,6 +208,9 @@ public: bool operator==(const class null_pointer*) const { return m_ptr == 0; } bool operator!=(const class null_pointer*) const { return m_ptr != 0; } + bool operator==(const null_ref&) const { return m_ptr == 0; } + bool operator!=(const null_ref&) const { return m_ptr != 0; } + /** Create a ref<> from a raw pointer. * * WARNING: you should use this function only if you know what @@ -307,6 +310,18 @@ bool operator!=(T* const p, const ref & a) return (a.get() != p); } +template +bool operator==(const null_ref&, const ref & r) +{ + return (r.get() == 0); +} + +template +bool operator!=(const null_ref&, const ref & r) +{ + return (r.get() != 0); +} + /** Base class for weak references.