From 602aebc11a615971800d38f8d427a4e4f95c1134 Mon Sep 17 00:00:00 2001 From: tsepez Date: Tue, 29 Mar 2016 15:04:21 -0700 Subject: Add a Retained Pointer smart class. It's going to be hard to fix some XFA object leaks without this. Put this in fxcrt/ as we should be able to make the FX strings take advantage of this. BUG=pdfium:55 Review URL: https://codereview.chromium.org/1805683002 --- core/fxcrt/cfx_retain_ptr_unittest.cpp | 215 +++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 core/fxcrt/cfx_retain_ptr_unittest.cpp (limited to 'core/fxcrt/cfx_retain_ptr_unittest.cpp') diff --git a/core/fxcrt/cfx_retain_ptr_unittest.cpp b/core/fxcrt/cfx_retain_ptr_unittest.cpp new file mode 100644 index 0000000000..4e74e52768 --- /dev/null +++ b/core/fxcrt/cfx_retain_ptr_unittest.cpp @@ -0,0 +1,215 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fxcrt/include/cfx_retain_ptr.h" + +#include + +#include "testing/fx_string_testhelpers.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class PseudoRetainable { + public: + PseudoRetainable() : retain_count_(0), release_count_(0) {} + void Retain() { ++retain_count_; } + void Release() { ++release_count_; } + int retain_count() const { return retain_count_; } + int release_count() const { return release_count_; } + + private: + int retain_count_; + int release_count_; +}; + +} // namespace + +TEST(fxcrt, RetainPtrNull) { + CFX_RetainPtr ptr; + EXPECT_EQ(nullptr, ptr.Get()); +} + +TEST(fxcrt, RetainPtrNormal) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr(&obj); + EXPECT_EQ(&obj, ptr.Get()); + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(0, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); +} + +TEST(fxcrt, RetainPtrCopyCtor) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr1(&obj); + { + CFX_RetainPtr ptr2(ptr1); + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(0, obj.release_count()); + } + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); + } + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(2, obj.release_count()); +} + +TEST(fxcrt, RetainPtrMoveCtor) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr1(&obj); + { + CFX_RetainPtr ptr2(std::move(ptr1)); + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(0, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); +} + +TEST(fxcrt, RetainPtrResetNull) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr(&obj); + ptr.Reset(); + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); +} + +TEST(fxcrt, RetainPtrReset) { + PseudoRetainable obj1; + PseudoRetainable obj2; + { + CFX_RetainPtr ptr(&obj1); + ptr.Reset(&obj2); + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); + EXPECT_EQ(1, obj2.retain_count()); + EXPECT_EQ(0, obj2.release_count()); + } + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); + EXPECT_EQ(1, obj2.retain_count()); + EXPECT_EQ(1, obj2.release_count()); +} + +TEST(fxcrt, RetainPtrSwap) { + PseudoRetainable obj1; + PseudoRetainable obj2; + { + CFX_RetainPtr ptr1(&obj1); + { + CFX_RetainPtr ptr2(&obj2); + ptr1.Swap(ptr2); + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(0, obj1.release_count()); + EXPECT_EQ(1, obj2.retain_count()); + EXPECT_EQ(0, obj2.release_count()); + } + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); + EXPECT_EQ(1, obj2.retain_count()); + EXPECT_EQ(0, obj2.release_count()); + } + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); + EXPECT_EQ(1, obj2.retain_count()); + EXPECT_EQ(1, obj2.release_count()); +} + +TEST(fxcrt, RetainPtrSwapNull) { + PseudoRetainable obj1; + { + CFX_RetainPtr ptr1(&obj1); + { + CFX_RetainPtr ptr2; + ptr1.Swap(ptr2); + EXPECT_FALSE(ptr1); + EXPECT_TRUE(ptr2); + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(0, obj1.release_count()); + } + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); + } + EXPECT_EQ(1, obj1.retain_count()); + EXPECT_EQ(1, obj1.release_count()); +} + +TEST(fxcrt, RetainPtrAssign) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr(&obj); + { + CFX_RetainPtr ptr2; + ptr2 = ptr; + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(0, obj.release_count()); + } + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); + } + EXPECT_EQ(2, obj.retain_count()); + EXPECT_EQ(2, obj.release_count()); +} + +TEST(fxcrt, RetainPtrEquals) { + PseudoRetainable obj1; + PseudoRetainable obj2; + CFX_RetainPtr null_ptr1; + CFX_RetainPtr obj1_ptr1(&obj1); + CFX_RetainPtr obj2_ptr1(&obj2); + { + CFX_RetainPtr null_ptr2; + EXPECT_TRUE(null_ptr1 == null_ptr2); + + CFX_RetainPtr obj1_ptr2(&obj1); + EXPECT_TRUE(obj1_ptr1 == obj1_ptr2); + + CFX_RetainPtr obj2_ptr2(&obj2); + EXPECT_TRUE(obj2_ptr1 == obj2_ptr2); + } + EXPECT_FALSE(null_ptr1 == obj1_ptr1); + EXPECT_FALSE(null_ptr1 == obj2_ptr1); + EXPECT_FALSE(obj1_ptr1 == obj2_ptr1); +} + +TEST(fxcrt, RetainPtrNotEquals) { + PseudoRetainable obj1; + PseudoRetainable obj2; + CFX_RetainPtr null_ptr1; + CFX_RetainPtr obj1_ptr1(&obj1); + CFX_RetainPtr obj2_ptr1(&obj2); + { + CFX_RetainPtr null_ptr2; + CFX_RetainPtr obj1_ptr2(&obj1); + CFX_RetainPtr obj2_ptr2(&obj2); + EXPECT_FALSE(null_ptr1 != null_ptr2); + EXPECT_FALSE(obj1_ptr1 != obj1_ptr2); + EXPECT_FALSE(obj2_ptr1 != obj2_ptr2); + } + EXPECT_TRUE(null_ptr1 != obj1_ptr1); + EXPECT_TRUE(null_ptr1 != obj2_ptr1); + EXPECT_TRUE(obj1_ptr1 != obj2_ptr1); +} + +TEST(fxcrt, RetainPtrBool) { + PseudoRetainable obj1; + CFX_RetainPtr null_ptr; + CFX_RetainPtr obj1_ptr(&obj1); + bool null_bool = null_ptr; + bool obj1_bool = obj1_ptr; + EXPECT_FALSE(null_bool); + EXPECT_TRUE(obj1_bool); +} -- cgit v1.2.3