1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/scoped_generic.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace base { 11 12 namespace { 13 14 struct IntTraits { 15 IntTraits(std::vector<int>* freed) : freed_ints(freed) {} 16 17 static int InvalidValue() { 18 return -1; 19 } 20 void Free(int value) { 21 freed_ints->push_back(value); 22 } 23 24 std::vector<int>* freed_ints; 25 }; 26 27 typedef ScopedGeneric<int, IntTraits> ScopedInt; 28 29 } // namespace 30 31 TEST(ScopedGenericTest, ScopedGeneric) { 32 std::vector<int> values_freed; 33 IntTraits traits(&values_freed); 34 35 // Invalid case, delete should not be called. 36 { 37 ScopedInt a(IntTraits::InvalidValue(), traits); 38 } 39 EXPECT_TRUE(values_freed.empty()); 40 41 // Simple deleting case. 42 static const int kFirst = 0; 43 { 44 ScopedInt a(kFirst, traits); 45 } 46 ASSERT_EQ(1u, values_freed.size()); 47 ASSERT_EQ(kFirst, values_freed[0]); 48 values_freed.clear(); 49 50 // Release should return the right value and leave the object empty. 51 { 52 ScopedInt a(kFirst, traits); 53 EXPECT_EQ(kFirst, a.release()); 54 55 ScopedInt b(IntTraits::InvalidValue(), traits); 56 EXPECT_EQ(IntTraits::InvalidValue(), b.release()); 57 } 58 ASSERT_TRUE(values_freed.empty()); 59 60 // Reset should free the old value, then the new one should go away when 61 // it goes out of scope. 62 static const int kSecond = 1; 63 { 64 ScopedInt b(kFirst, traits); 65 b.reset(kSecond); 66 ASSERT_EQ(1u, values_freed.size()); 67 ASSERT_EQ(kFirst, values_freed[0]); 68 } 69 ASSERT_EQ(2u, values_freed.size()); 70 ASSERT_EQ(kSecond, values_freed[1]); 71 values_freed.clear(); 72 73 // Swap. 74 { 75 ScopedInt a(kFirst, traits); 76 ScopedInt b(kSecond, traits); 77 a.swap(b); 78 EXPECT_TRUE(values_freed.empty()); // Nothing should be freed. 79 EXPECT_EQ(kSecond, a.get()); 80 EXPECT_EQ(kFirst, b.get()); 81 } 82 // Values should be deleted in the opposite order. 83 ASSERT_EQ(2u, values_freed.size()); 84 EXPECT_EQ(kFirst, values_freed[0]); 85 EXPECT_EQ(kSecond, values_freed[1]); 86 values_freed.clear(); 87 88 // Pass. 89 { 90 ScopedInt a(kFirst, traits); 91 ScopedInt b(a.Pass()); 92 EXPECT_TRUE(values_freed.empty()); // Nothing should be freed. 93 ASSERT_EQ(IntTraits::InvalidValue(), a.get()); 94 ASSERT_EQ(kFirst, b.get()); 95 } 96 ASSERT_EQ(1u, values_freed.size()); 97 ASSERT_EQ(kFirst, values_freed[0]); 98 } 99 100 TEST(ScopedGenericTest, Operators) { 101 std::vector<int> values_freed; 102 IntTraits traits(&values_freed); 103 104 static const int kFirst = 0; 105 static const int kSecond = 1; 106 { 107 ScopedInt a(kFirst, traits); 108 EXPECT_TRUE(a == kFirst); 109 EXPECT_FALSE(a != kFirst); 110 EXPECT_FALSE(a == kSecond); 111 EXPECT_TRUE(a != kSecond); 112 113 EXPECT_TRUE(kFirst == a); 114 EXPECT_FALSE(kFirst != a); 115 EXPECT_FALSE(kSecond == a); 116 EXPECT_TRUE(kSecond != a); 117 } 118 119 // is_valid(). 120 { 121 ScopedInt a(kFirst, traits); 122 EXPECT_TRUE(a.is_valid()); 123 a.reset(); 124 EXPECT_FALSE(a.is_valid()); 125 } 126 } 127 128 // Cheesy manual "no compile" test for manually validating changes. 129 #if 0 130 TEST(ScopedGenericTest, NoCompile) { 131 // Assignment shouldn't work. 132 /*{ 133 ScopedInt a(kFirst, traits); 134 ScopedInt b(a); 135 }*/ 136 137 // Comparison shouldn't work. 138 /*{ 139 ScopedInt a(kFirst, traits); 140 ScopedInt b(kFirst, traits); 141 if (a == b) { 142 } 143 }*/ 144 145 // Implicit conversion to bool shouldn't work. 146 /*{ 147 ScopedInt a(kFirst, traits); 148 bool result = a; 149 }*/ 150 } 151 #endif 152 153 } // namespace base 154