summaryrefslogtreecommitdiff
path: root/xpcom/tests/gtest/TestAutoPtr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/tests/gtest/TestAutoPtr.cpp')
-rw-r--r--xpcom/tests/gtest/TestAutoPtr.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/xpcom/tests/gtest/TestAutoPtr.cpp b/xpcom/tests/gtest/TestAutoPtr.cpp
new file mode 100644
index 0000000000..362ba55c50
--- /dev/null
+++ b/xpcom/tests/gtest/TestAutoPtr.cpp
@@ -0,0 +1,220 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:ts=4:et:sw=4:
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsAutoPtr.h"
+#include "gtest/gtest.h"
+
+class TestObjectBaseA {
+ public:
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObjectBaseA() { }
+ void MemberFunction(int, int*, int&)
+ {
+ }
+ virtual void VirtualMemberFunction(int, int*, int&) { };
+ virtual void VirtualConstMemberFunction(int, int*, int&) const { };
+ int fooA;
+};
+
+class TestObjectBaseB {
+ public:
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObjectBaseB() { }
+ int fooB;
+};
+
+class TestObject : public TestObjectBaseA, public TestObjectBaseB {
+ public:
+ TestObject()
+ {
+ }
+
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObject()
+ {
+ destructed++;
+ }
+
+ virtual void VirtualMemberFunction(int, int*, int&) override
+ {
+ }
+ virtual void VirtualConstMemberFunction(int, int*, int&) const override
+ {
+ }
+
+ static int destructed;
+ static const void* last_ptr;
+};
+
+int TestObject::destructed = 0;
+const void* TestObject::last_ptr = nullptr;
+
+static void CreateTestObject(TestObject **aResult)
+{
+ *aResult = new TestObject();
+}
+
+static void DoSomethingWithTestObject(TestObject *aIn)
+{
+ TestObject::last_ptr = static_cast<void*>(aIn);
+}
+
+static void DoSomethingWithConstTestObject(const TestObject *aIn)
+{
+ TestObject::last_ptr = static_cast<const void*>(aIn);
+}
+
+static void DoSomethingWithTestObjectBaseB(TestObjectBaseB *aIn)
+{
+ TestObject::last_ptr = static_cast<void*>(aIn);
+}
+
+static void DoSomethingWithConstTestObjectBaseB(const TestObjectBaseB *aIn)
+{
+ TestObject::last_ptr = static_cast<const void*>(aIn);
+}
+
+TEST(AutoPtr, Assignment)
+{
+ TestObject::destructed = 0;
+
+ {
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+
+ {
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ pobj = new TestObject();
+ ASSERT_EQ(2, TestObject::destructed);
+ }
+
+ ASSERT_EQ(3, TestObject::destructed);
+}
+
+TEST(AutoPtr, getter_Transfers)
+{
+ TestObject::destructed = 0;
+
+ {
+ nsAutoPtr<TestObject> ptr;
+ CreateTestObject(getter_Transfers(ptr));
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+}
+
+TEST(AutoPtr, Casting)
+{
+ // This comparison is always false, as it should be. The extra parens
+ // suppress a -Wunreachable-code warning about printf being unreachable.
+ ASSERT_NE(((void*)(TestObject*)0x1000),
+ ((void*)(TestObjectBaseB*)(TestObject*)0x1000));
+
+ {
+ nsAutoPtr<TestObject> p1(new TestObject());
+ TestObjectBaseB *p2 = p1;
+ ASSERT_NE(static_cast<void*>(p1),
+ static_cast<void*>(p2));
+ ASSERT_EQ(p1, p2);
+ ASSERT_FALSE(p1 != p2);
+ ASSERT_EQ(p2, p1);
+ ASSERT_FALSE(p2 != p1);
+ }
+
+ {
+ TestObject *p1 = new TestObject();
+ nsAutoPtr<TestObjectBaseB> p2(p1);
+ ASSERT_EQ(p1, p2);
+ ASSERT_FALSE(p1 != p2);
+ ASSERT_EQ(p2, p1);
+ ASSERT_FALSE(p2 != p1);
+ }
+}
+
+TEST(AutoPtr, Forget)
+{
+ TestObject::destructed = 0;
+
+ {
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ nsAutoPtr<TestObject> pobj2( pobj.forget() );
+ ASSERT_EQ(0, TestObject::destructed);
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+}
+
+TEST(AutoPtr, Construction)
+{
+ TestObject::destructed = 0;
+
+ {
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+}
+
+TEST(AutoPtr, ImplicitConversion)
+{
+ // This test is basically successful if it builds. We add a few assertions
+ // to make gtest happy.
+ TestObject::destructed = 0;
+
+ {
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ DoSomethingWithTestObject(pobj);
+ DoSomethingWithConstTestObject(pobj);
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+
+ {
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ DoSomethingWithTestObjectBaseB(pobj);
+ DoSomethingWithConstTestObjectBaseB(pobj);
+ }
+
+ ASSERT_EQ(2, TestObject::destructed);
+
+ {
+ const nsAutoPtr<TestObject> pobj(new TestObject());
+ DoSomethingWithTestObject(pobj);
+ DoSomethingWithConstTestObject(pobj);
+ }
+
+ ASSERT_EQ(3, TestObject::destructed);
+
+ {
+ const nsAutoPtr<TestObject> pobj(new TestObject());
+ DoSomethingWithTestObjectBaseB(pobj);
+ DoSomethingWithConstTestObjectBaseB(pobj);
+ }
+
+ ASSERT_EQ(4, TestObject::destructed);
+}
+
+TEST(AutoPtr, ArrowOperator)
+{
+ // This test is basically successful if it builds. We add a few assertions
+ // to make gtest happy.
+ TestObject::destructed = 0;
+
+ {
+ int test = 1;
+ void (TestObjectBaseA::*fPtr)( int, int*, int& ) = &TestObjectBaseA::MemberFunction;
+ void (TestObjectBaseA::*fVPtr)( int, int*, int& ) = &TestObjectBaseA::VirtualMemberFunction;
+ void (TestObjectBaseA::*fVCPtr)( int, int*, int& ) const = &TestObjectBaseA::VirtualConstMemberFunction;
+ nsAutoPtr<TestObjectBaseA> pobj(new TestObject());
+ (pobj->*fPtr)(test, &test, test);
+ (pobj->*fVPtr)(test, &test, test);
+ (pobj->*fVCPtr)(test, &test, test);
+ }
+
+ ASSERT_EQ(1, TestObject::destructed);
+}