Index: base/scoped_nullable_generic_unittest.cc |
diff --git a/base/scoped_nullable_generic_unittest.cc b/base/scoped_nullable_generic_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..977c6b1b1dcf572778b16502dbef5cc0aacb5ecc |
--- /dev/null |
+++ b/base/scoped_nullable_generic_unittest.cc |
@@ -0,0 +1,157 @@ |
+// Copyright 2014 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 <vector> |
+ |
+#include "base/scoped_nullable_generic.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+ |
+namespace { |
+ |
+struct IntTraits { |
+ IntTraits(std::vector<int>* freed) : freed_ints(freed) {} |
+ |
+ static int NullValue() { |
+ return -1; |
+ } |
+ void Free(int value) { |
+ freed_ints->push_back(value); |
+ } |
+ |
+ std::vector<int>* freed_ints; |
+}; |
+ |
+typedef ScopedNullableGeneric<int, IntTraits> ScopedInt; |
+ |
+} // namespace |
+ |
+TEST(ScopedGenericHandleTest, ScopedGenericHandle) { |
+ std::vector<int> values_freed; |
+ IntTraits traits(&values_freed); |
+ |
+ // Null case, delete should not be called. |
+ { |
+ ScopedInt a(IntTraits::NullValue(), traits); |
+ } |
+ EXPECT_TRUE(values_freed.empty()); |
+ |
+ // Simple deleting case. |
+ static const int kFirst = 0; |
+ { |
+ ScopedInt a(kFirst, traits); |
+ } |
+ ASSERT_EQ(1u, values_freed.size()); |
+ ASSERT_EQ(kFirst, values_freed[0]); |
+ values_freed.clear(); |
+ |
+ // Release should return the right value and leave the object empty. |
+ { |
+ ScopedInt a(kFirst, traits); |
+ EXPECT_EQ(kFirst, a.release()); |
+ |
+ ScopedInt b(IntTraits::NullValue(), traits); |
+ EXPECT_EQ(IntTraits::NullValue(), b.release()); |
+ } |
+ ASSERT_TRUE(values_freed.empty()); |
+ |
+ // Reset should free the old value, then the new one should go away when |
+ // it goes out of scope. |
+ static const int kSecond = 1; |
+ { |
+ ScopedInt b(kFirst, traits); |
+ b.reset(kSecond); |
+ ASSERT_EQ(1u, values_freed.size()); |
+ ASSERT_EQ(kFirst, values_freed[0]); |
+ } |
+ ASSERT_EQ(2u, values_freed.size()); |
+ ASSERT_EQ(kSecond, values_freed[1]); |
+ values_freed.clear(); |
+ |
+ // Swap. |
+ { |
+ ScopedInt a(kFirst, traits); |
+ ScopedInt b(kSecond, traits); |
+ a.swap(b); |
+ EXPECT_TRUE(values_freed.empty()); // Nothing should be freed. |
+ EXPECT_EQ(kSecond, a.get()); |
+ EXPECT_EQ(kFirst, b.get()); |
+ } |
+ // Values should be deleted in the opposite order. |
+ ASSERT_EQ(2u, values_freed.size()); |
+ EXPECT_EQ(kFirst, values_freed[0]); |
+ EXPECT_EQ(kSecond, values_freed[1]); |
+ values_freed.clear(); |
+ |
+ // Pass. |
+ { |
+ ScopedInt a(kFirst, traits); |
+ ScopedInt b(a.Pass()); |
+ EXPECT_TRUE(values_freed.empty()); // Nothing should be freed. |
+ ASSERT_EQ(IntTraits::NullValue(), a.get()); |
+ ASSERT_EQ(kFirst, b.get()); |
+ } |
+ ASSERT_EQ(1u, values_freed.size()); |
+ ASSERT_EQ(kFirst, values_freed[0]); |
+} |
+ |
+TEST(ScopedGenericHandleTest, Operators) { |
+ std::vector<int> values_freed; |
+ IntTraits traits(&values_freed); |
+ |
+ static const int kFirst = 0; |
+ static const int kSecond = 1; |
+ { |
+ ScopedInt a(kFirst, traits); |
+ EXPECT_TRUE(a == kFirst); |
+ EXPECT_FALSE(a != kFirst); |
+ EXPECT_FALSE(a == kSecond); |
+ EXPECT_TRUE(a != kSecond); |
+ |
+ EXPECT_TRUE(kFirst == a); |
+ EXPECT_FALSE(kFirst != a); |
+ EXPECT_FALSE(kSecond == a); |
+ EXPECT_TRUE(kSecond != a); |
+ } |
+ |
+ // Testable. |
viettrungluu
2014/03/10 17:35:56
This comment no longer really makes sense.
|
+ { |
+ ScopedInt a(kFirst, traits); |
+ if (!a.is_valid()) { |
viettrungluu
2014/03/10 17:35:56
Probably just EXPECT_TRUE(a.is_valid()); (etc., be
|
+ EXPECT_FALSE(true); |
+ } |
+ a.reset(); |
+ if (a.is_valid()) { |
+ EXPECT_FALSE(true); |
+ } |
+ } |
+} |
+ |
+// Cheesy manual "no compile" test for manually validating changes. |
+#if 0 |
+TEST(ScopedGenericHandleTest, NoCompile) { |
+ // Assignment shouldn't work. |
+ /*{ |
+ ScopedInt a(kFirst, traits); |
+ ScopedInt b(a); |
+ }*/ |
+ |
+ // Comparison shouldn't work. |
+ /*{ |
+ ScopedInt a(kFirst, traits); |
+ ScopedInt b(kFirst, traits); |
+ if (a == b) { |
+ } |
+ }*/ |
+ |
+ // Implicit conversion to bool shouldn't work. |
+ /*{ |
+ ScopedInt a(kFirst, traits); |
+ bool result = a; |
+ }*/ |
+} |
+#endif |
+ |
+} // namespace base |