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