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> {
~Targetbase::__anonc993071d0111::Target25   virtual ~Target() {}
26 };
27 struct DerivedTarget : public Target {};
28 struct Arrow {
29   WeakPtr<Target> target;
30 };
31 struct TargetWithFactory : public Target {
TargetWithFactorybase::__anonc993071d0111::TargetWithFactory32   TargetWithFactory() : factory(this) {}
33   WeakPtrFactory<Target> factory;
34 };
35 
36 }  // namespace
37 
TEST(WeakPtrFactoryTest,Basic)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 
TEST(WeakPtrFactoryTest,Comparison)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 
TEST(WeakPtrFactoryTest,OutOfScope)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 
TEST(WeakPtrFactoryTest,Multiple)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 
TEST(WeakPtrFactoryTest,MultipleStaged)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 
TEST(WeakPtrFactoryTest,Dereference)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 
TEST(WeakPtrFactoryTest,UpCast)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 
TEST(WeakPtrTest,SupportsWeakPtr)110 TEST(WeakPtrTest, SupportsWeakPtr) {
111   Target target;
112   WeakPtr<Target> ptr = target.AsWeakPtr();
113   EXPECT_EQ(&target, ptr.get());
114 }
115 
TEST(WeakPtrTest,DerivedTarget)116 TEST(WeakPtrTest, DerivedTarget) {
117   DerivedTarget target;
118   WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
119   EXPECT_EQ(&target, ptr.get());
120 }
121 
TEST(WeakPtrTest,InvalidateWeakPtrs)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 
TEST(WeakPtrTest,HasWeakPtrs)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