1 // Copyright (c) 2012 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 "base/memory/weak_ptr.h" 6 7 #include <string> 8 9 #include <gtest/gtest.h> 10 11 #include "base/bind.h" 12 #include "base/location.h" 13 #include "base/memory/scoped_ptr.h" 14 15 namespace base { 16 namespace { 17 18 struct Base { 19 std::string member; 20 }; 21 struct Derived : public Base {}; 22 23 struct TargetBase {}; 24 struct Target : public TargetBase, public SupportsWeakPtr<Target> { 25 virtual ~Target() {} 26 }; 27 struct DerivedTarget : public Target {}; 28 struct Arrow { 29 WeakPtr<Target> target; 30 }; 31 struct TargetWithFactory : public Target { 32 TargetWithFactory() : factory(this) {} 33 WeakPtrFactory<Target> factory; 34 }; 35 36 } // namespace 37 38 TEST(WeakPtrFactoryTest, Basic) { 39 int data; 40 WeakPtrFactory<int> factory(&data); 41 WeakPtr<int> ptr = factory.GetWeakPtr(); 42 EXPECT_EQ(&data, ptr.get()); 43 } 44 45 TEST(WeakPtrFactoryTest, Comparison) { 46 int data; 47 WeakPtrFactory<int> factory(&data); 48 WeakPtr<int> ptr = factory.GetWeakPtr(); 49 WeakPtr<int> ptr2 = ptr; 50 EXPECT_EQ(ptr.get(), ptr2.get()); 51 } 52 53 TEST(WeakPtrFactoryTest, OutOfScope) { 54 WeakPtr<int> ptr; 55 EXPECT_EQ(NULL, ptr.get()); 56 { 57 int data; 58 WeakPtrFactory<int> factory(&data); 59 ptr = factory.GetWeakPtr(); 60 } 61 EXPECT_EQ(NULL, ptr.get()); 62 } 63 64 TEST(WeakPtrFactoryTest, Multiple) { 65 WeakPtr<int> a, b; 66 { 67 int data; 68 WeakPtrFactory<int> factory(&data); 69 a = factory.GetWeakPtr(); 70 b = factory.GetWeakPtr(); 71 EXPECT_EQ(&data, a.get()); 72 EXPECT_EQ(&data, b.get()); 73 } 74 EXPECT_EQ(NULL, a.get()); 75 EXPECT_EQ(NULL, b.get()); 76 } 77 78 TEST(WeakPtrFactoryTest, MultipleStaged) { 79 WeakPtr<int> a; 80 { 81 int data; 82 WeakPtrFactory<int> factory(&data); 83 a = factory.GetWeakPtr(); 84 { 85 WeakPtr<int> b = factory.GetWeakPtr(); 86 } 87 EXPECT_TRUE(NULL != a.get()); 88 } 89 EXPECT_EQ(NULL, a.get()); 90 } 91 92 TEST(WeakPtrFactoryTest, Dereference) { 93 Base data; 94 data.member = "123456"; 95 WeakPtrFactory<Base> factory(&data); 96 WeakPtr<Base> ptr = factory.GetWeakPtr(); 97 EXPECT_EQ(&data, ptr.get()); 98 EXPECT_EQ(data.member, (*ptr).member); 99 EXPECT_EQ(data.member, ptr->member); 100 } 101 102 TEST(WeakPtrFactoryTest, UpCast) { 103 Derived data; 104 WeakPtrFactory<Derived> factory(&data); 105 WeakPtr<Base> ptr = factory.GetWeakPtr(); 106 ptr = factory.GetWeakPtr(); 107 EXPECT_EQ(ptr.get(), &data); 108 } 109 110 TEST(WeakPtrTest, SupportsWeakPtr) { 111 Target target; 112 WeakPtr<Target> ptr = target.AsWeakPtr(); 113 EXPECT_EQ(&target, ptr.get()); 114 } 115 116 TEST(WeakPtrTest, DerivedTarget) { 117 DerivedTarget target; 118 WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target); 119 EXPECT_EQ(&target, ptr.get()); 120 } 121 122 TEST(WeakPtrTest, InvalidateWeakPtrs) { 123 int data; 124 WeakPtrFactory<int> factory(&data); 125 WeakPtr<int> ptr = factory.GetWeakPtr(); 126 EXPECT_EQ(&data, ptr.get()); 127 EXPECT_TRUE(factory.HasWeakPtrs()); 128 factory.InvalidateWeakPtrs(); 129 EXPECT_EQ(NULL, ptr.get()); 130 EXPECT_FALSE(factory.HasWeakPtrs()); 131 132 // Test that the factory can create new weak pointers after a 133 // InvalidateWeakPtrs call, and they remain valid until the next 134 // InvalidateWeakPtrs call. 135 WeakPtr<int> ptr2 = factory.GetWeakPtr(); 136 EXPECT_EQ(&data, ptr2.get()); 137 EXPECT_TRUE(factory.HasWeakPtrs()); 138 factory.InvalidateWeakPtrs(); 139 EXPECT_EQ(NULL, ptr2.get()); 140 EXPECT_FALSE(factory.HasWeakPtrs()); 141 } 142 143 TEST(WeakPtrTest, HasWeakPtrs) { 144 int data; 145 WeakPtrFactory<int> factory(&data); 146 { 147 WeakPtr<int> ptr = factory.GetWeakPtr(); 148 EXPECT_TRUE(factory.HasWeakPtrs()); 149 } 150 EXPECT_FALSE(factory.HasWeakPtrs()); 151 } 152 153 } // namespace base 154