Index: base/containers/scoped_ptr_map_unittest.cc |
diff --git a/base/containers/scoped_ptr_map_unittest.cc b/base/containers/scoped_ptr_map_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..46843b3f2529f288ec3ef9cdef1884608cfa2524 |
--- /dev/null |
+++ b/base/containers/scoped_ptr_map_unittest.cc |
@@ -0,0 +1,240 @@ |
+// Copyright 2015 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/containers/scoped_ptr_map.h" |
+ |
+#include <functional> |
+#include <map> |
+#include <utility> |
+ |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+namespace { |
+ |
+// A ScopedDestroyer sets a Boolean to true upon destruction. |
+class ScopedDestroyer { |
+ public: |
+ ScopedDestroyer(bool* destroyed) : destroyed_(destroyed) { |
+ *destroyed_ = false; |
+ } |
+ |
+ ~ScopedDestroyer() { *destroyed_ = true; } |
+ |
+ private: |
+ bool* destroyed_; |
+}; |
+ |
+TEST(ScopedPtrMapTest, Insert) { |
+ bool destroyed1 = false; |
+ bool destroyed2 = false; |
+ { |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ |
+ // Insert to new key. |
+ ScopedDestroyer* elem1 = new ScopedDestroyer(&destroyed1); |
+ EXPECT_FALSE(destroyed1); |
+ EXPECT_TRUE(scoped_map.insert(0, make_scoped_ptr(elem1)).second); |
+ EXPECT_EQ(elem1, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed1); |
+ |
+ // Insert to existing key. |
+ ScopedDestroyer* elem2 = new ScopedDestroyer(&destroyed2); |
+ EXPECT_FALSE(destroyed2); |
+ EXPECT_FALSE(scoped_map.insert(0, make_scoped_ptr(elem2)).second); |
+ EXPECT_EQ(elem1, scoped_map.find(0)->second); |
+ |
+ EXPECT_FALSE(destroyed1); |
+ EXPECT_TRUE(destroyed2); |
+ } |
+ EXPECT_TRUE(destroyed1); |
+} |
+ |
+TEST(ScopedPtrMapTest, Set) { |
+ bool destroyed1 = false; |
+ bool destroyed2 = false; |
+ { |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ |
+ // Set a new key. |
+ ScopedDestroyer* elem1 = new ScopedDestroyer(&destroyed1); |
+ EXPECT_FALSE(destroyed1); |
+ scoped_map.set(0, make_scoped_ptr(elem1)); |
+ EXPECT_EQ(elem1, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed1); |
+ |
+ // Set to replace an existing key. |
+ ScopedDestroyer* elem2 = new ScopedDestroyer(&destroyed2); |
+ EXPECT_FALSE(destroyed2); |
+ scoped_map.set(0, make_scoped_ptr(elem2)); |
+ EXPECT_EQ(elem2, scoped_map.find(0)->second); |
+ |
+ EXPECT_TRUE(destroyed1); |
+ EXPECT_FALSE(destroyed2); |
+ } |
+ EXPECT_TRUE(destroyed1); |
+ EXPECT_TRUE(destroyed2); |
+} |
+ |
+TEST(ScopedPtrMapTest, EraseIterator) { |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ EXPECT_FALSE(destroyed); |
+ scoped_map.erase(scoped_map.find(0)); |
+ EXPECT_TRUE(destroyed); |
+ EXPECT_TRUE(scoped_map.empty()); |
+} |
+ |
+TEST(ScopedPtrMapTest, EraseKey) { |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ EXPECT_FALSE(destroyed); |
+ EXPECT_EQ(1u, scoped_map.erase(0)); |
+ EXPECT_TRUE(destroyed); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ |
+ // Test erase of a non-existent key. |
+ EXPECT_EQ(0u, scoped_map.erase(7)); |
+} |
+ |
+TEST(ScopedPtrMapTest, EraseRange) { |
+ bool destroyed1 = false; |
+ bool destroyed2 = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed1))); |
+ EXPECT_FALSE(destroyed1); |
+ |
+ scoped_map.insert(1, make_scoped_ptr(new ScopedDestroyer(&destroyed2))); |
+ EXPECT_FALSE(destroyed2); |
+ |
+ scoped_map.erase(scoped_map.find(0), scoped_map.end()); |
+ EXPECT_TRUE(destroyed1); |
+ EXPECT_TRUE(destroyed2); |
+ EXPECT_TRUE(scoped_map.empty()); |
+} |
+ |
+TEST(ScopedPtrMapTest, TakeAndErase) { |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); |
+ scoped_map.insert(0, make_scoped_ptr(elem)); |
+ EXPECT_EQ(elem, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ scoped_ptr<ScopedDestroyer> object = scoped_map.take_and_erase(0); |
+ EXPECT_EQ(elem, object.get()); |
+ EXPECT_FALSE(destroyed); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ object.reset(); |
+ EXPECT_TRUE(destroyed); |
+} |
+ |
+TEST(ScopedPtrMapTest, Clear) { |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ EXPECT_FALSE(destroyed); |
+ scoped_map.clear(); |
+ EXPECT_TRUE(destroyed); |
+ EXPECT_TRUE(scoped_map.empty()); |
+} |
+ |
+TEST(ScopedPtrMapTest, Compare) { |
+ // Construct a ScopedPtrMap with a custom comparison function. |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>, std::greater<int>> scoped_map; |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ scoped_map.insert(1, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ |
+ auto it = scoped_map.begin(); |
+ EXPECT_EQ(1, it->first); |
+ ++it; |
+ EXPECT_EQ(0, it->first); |
+} |
+ |
+TEST(ScopedPtrMapTest, Scope) { |
+ bool destroyed = false; |
+ { |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); |
+ EXPECT_FALSE(destroyed); |
+ } |
+ EXPECT_TRUE(destroyed); |
+} |
+ |
+TEST(ScopedPtrMapTest, MoveConstruct) { |
+ bool destroyed = false; |
+ { |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); |
+ scoped_map.insert(0, make_scoped_ptr(elem)); |
+ EXPECT_EQ(elem, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ EXPECT_FALSE(scoped_map.empty()); |
+ |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map_copy( |
+ scoped_map.Pass()); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ EXPECT_FALSE(scoped_map_copy.empty()); |
+ EXPECT_EQ(elem, scoped_map_copy.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ } |
+ EXPECT_TRUE(destroyed); |
+} |
+ |
+TEST(ScopedPtrMapTest, MoveAssign) { |
+ bool destroyed = false; |
+ { |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); |
+ scoped_map.insert(0, make_scoped_ptr(elem)); |
+ EXPECT_EQ(elem, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ EXPECT_FALSE(scoped_map.empty()); |
+ |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map_assign; |
+ scoped_map_assign = scoped_map.Pass(); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ EXPECT_FALSE(scoped_map_assign.empty()); |
+ EXPECT_EQ(elem, scoped_map_assign.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ } |
+ EXPECT_TRUE(destroyed); |
+} |
+ |
+template <typename Key, typename ScopedPtr> |
+ScopedPtrMap<Key, ScopedPtr> PassThru(ScopedPtrMap<Key, ScopedPtr> scoper) { |
+ return scoper; |
+} |
+ |
+TEST(ScopedPtrMapTest, Passed) { |
+ bool destroyed = false; |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; |
+ ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); |
+ scoped_map.insert(0, make_scoped_ptr(elem)); |
+ EXPECT_EQ(elem, scoped_map.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ |
+ base::Callback<ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>>(void)> |
+ callback = base::Bind(&PassThru<int, scoped_ptr<ScopedDestroyer>>, |
+ base::Passed(&scoped_map)); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ EXPECT_FALSE(destroyed); |
+ |
+ ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> result = callback.Run(); |
+ EXPECT_TRUE(scoped_map.empty()); |
+ EXPECT_EQ(elem, result.find(0)->second); |
+ EXPECT_FALSE(destroyed); |
+ |
+ result.clear(); |
+ EXPECT_TRUE(destroyed); |
+}; |
+ |
+} // namespace |
+} // namespace base |