xref: /aosp_15_r20/external/openscreen/util/weak_ptr_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "util/weak_ptr.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
8*3f982cf4SFabien Sanglard 
9*3f982cf4SFabien Sanglard namespace openscreen {
10*3f982cf4SFabien Sanglard namespace {
11*3f982cf4SFabien Sanglard 
12*3f982cf4SFabien Sanglard class SomeClass {
13*3f982cf4SFabien Sanglard  public:
14*3f982cf4SFabien Sanglard   virtual ~SomeClass() = default;
GetValue() const15*3f982cf4SFabien Sanglard   virtual int GetValue() const { return 42; }
16*3f982cf4SFabien Sanglard };
17*3f982cf4SFabien Sanglard 
18*3f982cf4SFabien Sanglard struct SomeSubclass final : public SomeClass {
19*3f982cf4SFabien Sanglard  public:
20*3f982cf4SFabien Sanglard   ~SomeSubclass() final = default;
GetValueopenscreen::__anond27955e50111::SomeSubclass21*3f982cf4SFabien Sanglard   int GetValue() const override { return 999; }
22*3f982cf4SFabien Sanglard };
23*3f982cf4SFabien Sanglard 
TEST(WeakPtrTest,InteractsWithNullptr)24*3f982cf4SFabien Sanglard TEST(WeakPtrTest, InteractsWithNullptr) {
25*3f982cf4SFabien Sanglard   WeakPtr<const int> default_constructed;  // Invoke default constructor.
26*3f982cf4SFabien Sanglard   EXPECT_TRUE(default_constructed == nullptr);
27*3f982cf4SFabien Sanglard   EXPECT_TRUE(nullptr == default_constructed);
28*3f982cf4SFabien Sanglard   EXPECT_FALSE(default_constructed != nullptr);
29*3f982cf4SFabien Sanglard   EXPECT_FALSE(nullptr != default_constructed);
30*3f982cf4SFabien Sanglard 
31*3f982cf4SFabien Sanglard   WeakPtr<const int> null_constructed = nullptr;  // Invoke construct-from-null.
32*3f982cf4SFabien Sanglard   EXPECT_TRUE(null_constructed == nullptr);
33*3f982cf4SFabien Sanglard   EXPECT_TRUE(nullptr == null_constructed);
34*3f982cf4SFabien Sanglard   EXPECT_FALSE(null_constructed != nullptr);
35*3f982cf4SFabien Sanglard   EXPECT_FALSE(nullptr != null_constructed);
36*3f982cf4SFabien Sanglard 
37*3f982cf4SFabien Sanglard   const int foo = 42;
38*3f982cf4SFabien Sanglard   WeakPtrFactory<const int> factory(&foo);
39*3f982cf4SFabien Sanglard   WeakPtr<const int> not_null = factory.GetWeakPtr();
40*3f982cf4SFabien Sanglard   EXPECT_TRUE(not_null != nullptr);
41*3f982cf4SFabien Sanglard   EXPECT_TRUE(nullptr != not_null);
42*3f982cf4SFabien Sanglard   EXPECT_FALSE(not_null == nullptr);
43*3f982cf4SFabien Sanglard   EXPECT_FALSE(nullptr == not_null);
44*3f982cf4SFabien Sanglard }
45*3f982cf4SFabien Sanglard 
TEST(WeakPtrTest,CopyConstructsAndAssigns)46*3f982cf4SFabien Sanglard TEST(WeakPtrTest, CopyConstructsAndAssigns) {
47*3f982cf4SFabien Sanglard   SomeSubclass foo;
48*3f982cf4SFabien Sanglard   WeakPtrFactory<SomeSubclass> factory(&foo);
49*3f982cf4SFabien Sanglard 
50*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> weak_ptr = factory.GetWeakPtr();
51*3f982cf4SFabien Sanglard   EXPECT_TRUE(weak_ptr);
52*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, weak_ptr.get());
53*3f982cf4SFabien Sanglard 
54*3f982cf4SFabien Sanglard   // Normal copy constructor.
55*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> copied0 = weak_ptr;
56*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, weak_ptr.get());  // Did not mutate original.
57*3f982cf4SFabien Sanglard   EXPECT_TRUE(copied0);
58*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, copied0.get());
59*3f982cf4SFabien Sanglard 
60*3f982cf4SFabien Sanglard   // Copy constructor, adding const qualifier.
61*3f982cf4SFabien Sanglard   WeakPtr<const SomeSubclass> copied1 = weak_ptr;
62*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, weak_ptr.get());  // Did not mutate original.
63*3f982cf4SFabien Sanglard   EXPECT_TRUE(copied1);
64*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, copied1.get());
65*3f982cf4SFabien Sanglard 
66*3f982cf4SFabien Sanglard   // Normal copy assignment.
67*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> assigned0;
68*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned0);
69*3f982cf4SFabien Sanglard   assigned0 = copied0;
70*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, copied0.get());  // Did not mutate original.
71*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned0);
72*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned0.get());
73*3f982cf4SFabien Sanglard 
74*3f982cf4SFabien Sanglard   // Copy assignment, adding const qualifier.
75*3f982cf4SFabien Sanglard   WeakPtr<const SomeSubclass> assigned1;
76*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned1);
77*3f982cf4SFabien Sanglard   assigned1 = copied0;
78*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, copied0.get());  // Did not mutate original.
79*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned1);
80*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned1.get());
81*3f982cf4SFabien Sanglard 
82*3f982cf4SFabien Sanglard   // Upcast copy constructor.
83*3f982cf4SFabien Sanglard   WeakPtr<SomeClass> copied2 = weak_ptr;
84*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, weak_ptr.get());  // Did not mutate original.
85*3f982cf4SFabien Sanglard   EXPECT_TRUE(copied2);
86*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, copied2.get());
87*3f982cf4SFabien Sanglard   EXPECT_EQ(999, (*copied2).GetValue());
88*3f982cf4SFabien Sanglard   EXPECT_EQ(999, copied2->GetValue());
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard   // Upcast copy assignment.
91*3f982cf4SFabien Sanglard   WeakPtr<SomeClass> assigned2;
92*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned2);
93*3f982cf4SFabien Sanglard   assigned2 = weak_ptr;
94*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, weak_ptr.get());  // Did not mutate original.
95*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned2);
96*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned2.get());
97*3f982cf4SFabien Sanglard   EXPECT_EQ(999, (*assigned2).GetValue());
98*3f982cf4SFabien Sanglard   EXPECT_EQ(999, assigned2->GetValue());
99*3f982cf4SFabien Sanglard }
100*3f982cf4SFabien Sanglard 
TEST(WeakPtrTest,MoveConstructsAndAssigns)101*3f982cf4SFabien Sanglard TEST(WeakPtrTest, MoveConstructsAndAssigns) {
102*3f982cf4SFabien Sanglard   SomeSubclass foo;
103*3f982cf4SFabien Sanglard   WeakPtrFactory<SomeSubclass> factory(&foo);
104*3f982cf4SFabien Sanglard 
105*3f982cf4SFabien Sanglard   // Normal move constructor.
106*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> weak_ptr = factory.GetWeakPtr();
107*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> moved0 = std::move(weak_ptr);
108*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
109*3f982cf4SFabien Sanglard   EXPECT_TRUE(moved0);
110*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, moved0.get());
111*3f982cf4SFabien Sanglard 
112*3f982cf4SFabien Sanglard   // Move constructor, adding const qualifier.
113*3f982cf4SFabien Sanglard   weak_ptr = factory.GetWeakPtr();
114*3f982cf4SFabien Sanglard   WeakPtr<const SomeSubclass> moved1 = std::move(weak_ptr);
115*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
116*3f982cf4SFabien Sanglard   EXPECT_TRUE(moved1);
117*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, moved1.get());
118*3f982cf4SFabien Sanglard 
119*3f982cf4SFabien Sanglard   // Normal move assignment.
120*3f982cf4SFabien Sanglard   weak_ptr = factory.GetWeakPtr();
121*3f982cf4SFabien Sanglard   WeakPtr<SomeSubclass> assigned0;
122*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned0);
123*3f982cf4SFabien Sanglard   assigned0 = std::move(weak_ptr);
124*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
125*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned0);
126*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned0.get());
127*3f982cf4SFabien Sanglard 
128*3f982cf4SFabien Sanglard   // Move assignment, adding const qualifier.
129*3f982cf4SFabien Sanglard   weak_ptr = factory.GetWeakPtr();
130*3f982cf4SFabien Sanglard   WeakPtr<const SomeSubclass> assigned1;
131*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned1);
132*3f982cf4SFabien Sanglard   assigned1 = std::move(weak_ptr);
133*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
134*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned1);
135*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned1.get());
136*3f982cf4SFabien Sanglard 
137*3f982cf4SFabien Sanglard   // Upcast move constructor.
138*3f982cf4SFabien Sanglard   weak_ptr = factory.GetWeakPtr();
139*3f982cf4SFabien Sanglard   WeakPtr<SomeClass> moved2 = std::move(weak_ptr);
140*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
141*3f982cf4SFabien Sanglard   EXPECT_TRUE(moved2);
142*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, moved2.get());
143*3f982cf4SFabien Sanglard   EXPECT_EQ(999, (*moved2).GetValue());  // Result from subclass's GetValue().
144*3f982cf4SFabien Sanglard   EXPECT_EQ(999, moved2->GetValue());    // Result from subclass's GetValue().
145*3f982cf4SFabien Sanglard 
146*3f982cf4SFabien Sanglard   // Upcast move assignment.
147*3f982cf4SFabien Sanglard   weak_ptr = factory.GetWeakPtr();
148*3f982cf4SFabien Sanglard   WeakPtr<SomeClass> assigned2;
149*3f982cf4SFabien Sanglard   EXPECT_FALSE(assigned2);
150*3f982cf4SFabien Sanglard   assigned2 = std::move(weak_ptr);
151*3f982cf4SFabien Sanglard   EXPECT_FALSE(weak_ptr);  // Original becomes null.
152*3f982cf4SFabien Sanglard   EXPECT_TRUE(assigned2);
153*3f982cf4SFabien Sanglard   EXPECT_EQ(&foo, assigned2.get());
154*3f982cf4SFabien Sanglard   EXPECT_EQ(999,
155*3f982cf4SFabien Sanglard             (*assigned2).GetValue());     // Result from subclass's GetValue().
156*3f982cf4SFabien Sanglard   EXPECT_EQ(999, assigned2->GetValue());  // Result from subclass's GetValue().
157*3f982cf4SFabien Sanglard }
158*3f982cf4SFabien Sanglard 
TEST(WeakPtrTest,InvalidatesWeakPtrs)159*3f982cf4SFabien Sanglard TEST(WeakPtrTest, InvalidatesWeakPtrs) {
160*3f982cf4SFabien Sanglard   const int foo = 1337;
161*3f982cf4SFabien Sanglard   WeakPtrFactory<const int> factory(&foo);
162*3f982cf4SFabien Sanglard 
163*3f982cf4SFabien Sanglard   // Thrice: Create weak pointers and invalidate them. This is done more than
164*3f982cf4SFabien Sanglard   // once to confirm the factory can create valid WeakPtrs again after each
165*3f982cf4SFabien Sanglard   // InvalidateWeakPtrs() call.
166*3f982cf4SFabien Sanglard   for (int i = 0; i < 3; ++i) {
167*3f982cf4SFabien Sanglard     // Create three WeakPtrs, two from the factory, one as a copy of another
168*3f982cf4SFabien Sanglard     // WeakPtr.
169*3f982cf4SFabien Sanglard     WeakPtr<const int> ptr0 = factory.GetWeakPtr();
170*3f982cf4SFabien Sanglard     WeakPtr<const int> ptr1 = factory.GetWeakPtr();
171*3f982cf4SFabien Sanglard     WeakPtr<const int> ptr2 = ptr1;
172*3f982cf4SFabien Sanglard     EXPECT_EQ(&foo, ptr0.get());
173*3f982cf4SFabien Sanglard     EXPECT_EQ(&foo, ptr1.get());
174*3f982cf4SFabien Sanglard     EXPECT_EQ(&foo, ptr2.get());
175*3f982cf4SFabien Sanglard 
176*3f982cf4SFabien Sanglard     // Invalidate all outstanding WeakPtrs from the factory, and confirm all
177*3f982cf4SFabien Sanglard     // outstanding WeakPtrs become null.
178*3f982cf4SFabien Sanglard     factory.InvalidateWeakPtrs();
179*3f982cf4SFabien Sanglard     EXPECT_FALSE(ptr0);
180*3f982cf4SFabien Sanglard     EXPECT_FALSE(ptr1);
181*3f982cf4SFabien Sanglard     EXPECT_FALSE(ptr2);
182*3f982cf4SFabien Sanglard   }
183*3f982cf4SFabien Sanglard }
184*3f982cf4SFabien Sanglard 
185*3f982cf4SFabien Sanglard }  // namespace
186*3f982cf4SFabien Sanglard }  // namespace openscreen
187