Index: base/memory/pass_scoped_ptr_unittest.cc |
diff --git a/base/memory/pass_scoped_ptr_unittest.cc b/base/memory/pass_scoped_ptr_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6b7ac6950db68bc112fc7d89d4239b7389124ff3 |
--- /dev/null |
+++ b/base/memory/pass_scoped_ptr_unittest.cc |
@@ -0,0 +1,158 @@ |
+// Copyright (c) 2011 The Chromium 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 "base/memory/pass_scoped_ptr.h" |
+ |
+#include "base/basictypes.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+ |
+namespace { |
+ |
+class ConDecLogger { |
+ public: |
+ ConDecLogger() : ptr_(NULL) { } |
+ explicit ConDecLogger(int* ptr) { set_ptr(ptr); } |
+ ~ConDecLogger() { --*ptr_; } |
+ |
+ private: |
+ void set_ptr(int* ptr) { ptr_ = ptr; ++*ptr_; } |
+ |
+ int* ptr_; |
+ DISALLOW_COPY_AND_ASSIGN(ConDecLogger); |
+}; |
+ |
+PassScopedPtr<ConDecLogger> PassThru(PassScopedPtr<ConDecLogger> logger) { |
+ return logger.Pass(); |
+} |
+ |
+void GrabAndDrop(PassScopedPtr<ConDecLogger> logger) { |
+} |
+ |
+} // namespace |
+ |
+TEST(PassScopedPtrTest, BasicMethods) { |
+ int constructed = 0; |
+ |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_EQ(logger, pass_scoped_ptr.value_.raw_ptr); |
+ EXPECT_TRUE(pass_scoped_ptr.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test ToScopedPtr(); |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ scoped_ptr<ConDecLogger> scoped; |
+ pass_scoped_ptr.ToScopedPtr(&scoped); |
+ EXPECT_EQ(logger, scoped.get()); |
+ EXPECT_TRUE(pass_scoped_ptr.value_.raw_ptr == NULL); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ EXPECT_EQ(1, constructed); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(PassScopedPtrTest, PassBehavior) { |
+ int constructed = 0; |
+ // Test Pass constructor; |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr2(pass_scoped_ptr.Pass()); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ EXPECT_TRUE(pass_scoped_ptr2.is_valid()); |
+ } |
+ |
+ // Test uncaught Pass() does not leak. |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ // Should auto-destruct logger by end of scope. |
+ pass_scoped_ptr.Pass(); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test that passing to function which does nothing does not leak. |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ // Should auto-destruct logger by end of scope. |
+ GrabAndDrop(pass_scoped_ptr.Pass()); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(PassScopedPtrTest, ReturnTypeBehavior) { |
+ int constructed = 0; |
+ |
+ // Test that we can return a PassScopedPtr. |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ PassThru(pass_scoped_ptr.Pass()); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ |
+ // Test uncaught return type not leak. |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ |
+ // Should auto-destruct logger by end of scope. |
+ PassThru(pass_scoped_ptr.Pass()); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(PassScopedPtrTest, AnchorBehavior) { |
+ int constructed = 0; |
+ // Test destruction semantics when anchored. |
+ { |
+ ConDecLogger* logger = new ConDecLogger(&constructed); |
+ subtle::PassScopedPtrAnchor<ConDecLogger> anchor( |
+ MakePassScopedPtr(logger)); |
+ EXPECT_EQ(1, constructed); |
+ { |
+ // Deletion of PassScopedPtr when anchored does nothing. |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(&anchor); |
+ EXPECT_EQ(1, constructed); |
+ } |
+ EXPECT_EQ(1, constructed); |
+ |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr(&anchor); |
+ pass_scoped_ptr.Pass(); |
+ EXPECT_EQ(0, constructed); |
+ EXPECT_FALSE(pass_scoped_ptr.is_valid()); |
+ |
+ // A second PassScopedPtr for an anchor should be immediately invalid. |
+ PassScopedPtr<ConDecLogger> pass_scoped_ptr2(&anchor); |
+ EXPECT_FALSE(pass_scoped_ptr2.is_valid()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+} // namespace base |