diff options
author | tsepez <tsepez@chromium.org> | 2016-09-28 14:49:01 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-09-28 14:49:01 -0700 |
commit | 4ba37c6f6964f6a24fc4b8b48bc82c02edb70370 (patch) | |
tree | a9b0787c38d9b7dbedcd19390144c6da1c222510 /core/fxcrt/cfx_weak_ptr_unittest.cpp | |
parent | 7c292e0f67e0f0bf4062e0b2adf244e17d7dacb5 (diff) | |
download | pdfium-chromium/2876.tar.xz |
Implement weak pointerschromium/2876chromium/2875
These will be a replacement for CFX_CountRef in future CLs, since
CFX_CountRef is manually incremented and error-prone.
Review-Url: https://codereview.chromium.org/2377143002
Diffstat (limited to 'core/fxcrt/cfx_weak_ptr_unittest.cpp')
-rw-r--r-- | core/fxcrt/cfx_weak_ptr_unittest.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/core/fxcrt/cfx_weak_ptr_unittest.cpp b/core/fxcrt/cfx_weak_ptr_unittest.cpp new file mode 100644 index 0000000000..c4fa514bef --- /dev/null +++ b/core/fxcrt/cfx_weak_ptr_unittest.cpp @@ -0,0 +1,174 @@ +// 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_weak_ptr.h" + +#include <memory> +#include <utility> + +#include "core/fxcrt/include/fx_memory.h" +#include "testing/fx_string_testhelpers.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class PseudoDeletable; +using WeakPtr = CFX_WeakPtr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>; +using UniquePtr = + std::unique_ptr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>; + +class PseudoDeletable { + public: + PseudoDeletable() : delete_count_(0) {} + void Release() { + ++delete_count_; + next_.Reset(); + } + void SetNext(const WeakPtr& next) { next_ = next; } + int delete_count() const { return delete_count_; } + + private: + int delete_count_; + WeakPtr next_; +}; + +} // namespace + +TEST(fxcrt, WeakPtrNull) { + WeakPtr ptr1; + EXPECT_FALSE(ptr1); + + WeakPtr ptr2; + EXPECT_TRUE(ptr1 == ptr2); + EXPECT_FALSE(ptr1 != ptr2); + + WeakPtr ptr3(ptr1); + EXPECT_TRUE(ptr1 == ptr3); + EXPECT_FALSE(ptr1 != ptr3); + + WeakPtr ptr4 = ptr1; + EXPECT_TRUE(ptr1 == ptr4); + EXPECT_FALSE(ptr1 != ptr4); +} + +TEST(fxcrt, WeakPtrNonNull) { + PseudoDeletable thing; + EXPECT_EQ(0, thing.delete_count()); + { + UniquePtr unique(&thing); + WeakPtr ptr1(std::move(unique)); + EXPECT_TRUE(ptr1); + EXPECT_EQ(&thing, ptr1.Get()); + + WeakPtr ptr2; + EXPECT_FALSE(ptr1 == ptr2); + EXPECT_TRUE(ptr1 != ptr2); + { + WeakPtr ptr3(ptr1); + EXPECT_TRUE(ptr1 == ptr3); + EXPECT_FALSE(ptr1 != ptr3); + EXPECT_EQ(&thing, ptr3.Get()); + { + WeakPtr ptr4 = ptr1; + EXPECT_TRUE(ptr1 == ptr4); + EXPECT_FALSE(ptr1 != ptr4); + EXPECT_EQ(&thing, ptr4.Get()); + } + } + EXPECT_EQ(0, thing.delete_count()); + } + EXPECT_EQ(1, thing.delete_count()); +} + +TEST(fxcrt, WeakPtrResetNull) { + PseudoDeletable thing; + { + UniquePtr unique(&thing); + WeakPtr ptr1(std::move(unique)); + WeakPtr ptr2 = ptr1; + ptr1.Reset(); + EXPECT_FALSE(ptr1); + EXPECT_EQ(nullptr, ptr1.Get()); + EXPECT_TRUE(ptr2); + EXPECT_EQ(&thing, ptr2.Get()); + EXPECT_FALSE(ptr1 == ptr2); + EXPECT_TRUE(ptr1 != ptr2); + EXPECT_EQ(0, thing.delete_count()); + } + EXPECT_EQ(1, thing.delete_count()); +} + +TEST(fxcrt, WeakPtrResetNonNull) { + PseudoDeletable thing1; + PseudoDeletable thing2; + { + UniquePtr unique1(&thing1); + WeakPtr ptr1(std::move(unique1)); + WeakPtr ptr2 = ptr1; + UniquePtr unique2(&thing2); + ptr2.Reset(std::move(unique2)); + EXPECT_TRUE(ptr1); + EXPECT_EQ(&thing1, ptr1.Get()); + EXPECT_TRUE(ptr2); + EXPECT_EQ(&thing2, ptr2.Get()); + EXPECT_FALSE(ptr1 == ptr2); + EXPECT_TRUE(ptr1 != ptr2); + EXPECT_EQ(0, thing1.delete_count()); + EXPECT_EQ(0, thing2.delete_count()); + } + EXPECT_EQ(1, thing1.delete_count()); + EXPECT_EQ(1, thing2.delete_count()); +} + +TEST(fxcrt, WeakPtrClear) { + PseudoDeletable thing; + { + UniquePtr unique(&thing); + WeakPtr ptr1(std::move(unique)); + WeakPtr ptr2 = ptr1; + ptr1.Clear(); + EXPECT_FALSE(ptr1); + EXPECT_EQ(nullptr, ptr1.Get()); + EXPECT_FALSE(ptr2); + EXPECT_EQ(nullptr, ptr2.Get()); + EXPECT_FALSE(ptr1 == ptr2); + EXPECT_TRUE(ptr1 != ptr2); + EXPECT_EQ(1, thing.delete_count()); + } + EXPECT_EQ(1, thing.delete_count()); +} + +TEST(fxcrt, WeakPtrCyclic) { + PseudoDeletable thing1; + PseudoDeletable thing2; + { + UniquePtr unique1(&thing1); + UniquePtr unique2(&thing2); + WeakPtr ptr1(std::move(unique1)); + WeakPtr ptr2(std::move(unique2)); + ptr1->SetNext(ptr2); + ptr2->SetNext(ptr1); + } + // Leaks without explicit clear. + EXPECT_EQ(0, thing1.delete_count()); + EXPECT_EQ(0, thing2.delete_count()); +} + +TEST(fxcrt, WeakPtrCyclicClear) { + PseudoDeletable thing1; + PseudoDeletable thing2; + { + UniquePtr unique1(&thing1); + UniquePtr unique2(&thing2); + WeakPtr ptr1(std::move(unique1)); + WeakPtr ptr2(std::move(unique2)); + ptr1->SetNext(ptr2); + ptr2->SetNext(ptr1); + ptr1.Clear(); + EXPECT_EQ(1, thing1.delete_count()); + EXPECT_EQ(0, thing2.delete_count()); + } + EXPECT_EQ(1, thing1.delete_count()); + EXPECT_EQ(1, thing2.delete_count()); +} |