1 // Copyright (c) 2016 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 "quiche/common/platform/api/quiche_reference_counted.h"
6 
7 #include "quiche/common/platform/api/quiche_test.h"
8 
9 namespace quiche {
10 namespace test {
11 namespace {
12 
13 class Base : public QuicheReferenceCounted {
14  public:
Base(bool * destroyed)15   explicit Base(bool* destroyed) : destroyed_(destroyed) {
16     *destroyed_ = false;
17   }
18 
19  protected:
~Base()20   ~Base() override { *destroyed_ = true; }
21 
22  private:
23   bool* destroyed_;
24 };
25 
26 class Derived : public Base {
27  public:
Derived(bool * destroyed)28   explicit Derived(bool* destroyed) : Base(destroyed) {}
29 
30  private:
~Derived()31   ~Derived() override {}
32 };
33 
34 class QuicheReferenceCountedTest : public QuicheTest {};
35 
TEST_F(QuicheReferenceCountedTest,DefaultConstructor)36 TEST_F(QuicheReferenceCountedTest, DefaultConstructor) {
37   QuicheReferenceCountedPointer<Base> a;
38   EXPECT_EQ(nullptr, a);
39   EXPECT_EQ(nullptr, a.get());
40   EXPECT_FALSE(a);
41 }
42 
TEST_F(QuicheReferenceCountedTest,ConstructFromRawPointer)43 TEST_F(QuicheReferenceCountedTest, ConstructFromRawPointer) {
44   bool destroyed = false;
45   {
46     QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
47     EXPECT_FALSE(destroyed);
48   }
49   EXPECT_TRUE(destroyed);
50 }
51 
TEST_F(QuicheReferenceCountedTest,RawPointerAssignment)52 TEST_F(QuicheReferenceCountedTest, RawPointerAssignment) {
53   bool destroyed = false;
54   {
55     QuicheReferenceCountedPointer<Base> a;
56     Base* rct = new Base(&destroyed);
57     a = rct;
58     EXPECT_FALSE(destroyed);
59   }
60   EXPECT_TRUE(destroyed);
61 }
62 
TEST_F(QuicheReferenceCountedTest,PointerCopy)63 TEST_F(QuicheReferenceCountedTest, PointerCopy) {
64   bool destroyed = false;
65   {
66     QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
67     {
68       QuicheReferenceCountedPointer<Base> b(a);
69       EXPECT_EQ(a, b);
70       EXPECT_FALSE(destroyed);
71     }
72     EXPECT_FALSE(destroyed);
73   }
74   EXPECT_TRUE(destroyed);
75 }
76 
TEST_F(QuicheReferenceCountedTest,PointerCopyAssignment)77 TEST_F(QuicheReferenceCountedTest, PointerCopyAssignment) {
78   bool destroyed = false;
79   {
80     QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
81     {
82       QuicheReferenceCountedPointer<Base> b = a;
83       EXPECT_EQ(a, b);
84       EXPECT_FALSE(destroyed);
85     }
86     EXPECT_FALSE(destroyed);
87   }
88   EXPECT_TRUE(destroyed);
89 }
90 
TEST_F(QuicheReferenceCountedTest,PointerCopyFromOtherType)91 TEST_F(QuicheReferenceCountedTest, PointerCopyFromOtherType) {
92   bool destroyed = false;
93   {
94     QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
95     {
96       QuicheReferenceCountedPointer<Base> b(a);
97       EXPECT_EQ(a.get(), b.get());
98       EXPECT_FALSE(destroyed);
99     }
100     EXPECT_FALSE(destroyed);
101   }
102   EXPECT_TRUE(destroyed);
103 }
104 
TEST_F(QuicheReferenceCountedTest,PointerCopyAssignmentFromOtherType)105 TEST_F(QuicheReferenceCountedTest, PointerCopyAssignmentFromOtherType) {
106   bool destroyed = false;
107   {
108     QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
109     {
110       QuicheReferenceCountedPointer<Base> b = a;
111       EXPECT_EQ(a.get(), b.get());
112       EXPECT_FALSE(destroyed);
113     }
114     EXPECT_FALSE(destroyed);
115   }
116   EXPECT_TRUE(destroyed);
117 }
118 
TEST_F(QuicheReferenceCountedTest,PointerMove)119 TEST_F(QuicheReferenceCountedTest, PointerMove) {
120   bool destroyed = false;
121   QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
122   EXPECT_FALSE(destroyed);
123   QuicheReferenceCountedPointer<Base> b(std::move(a));
124   EXPECT_FALSE(destroyed);
125   EXPECT_NE(nullptr, b);
126   EXPECT_EQ(nullptr, a);  // NOLINT
127 
128   b = nullptr;
129   EXPECT_TRUE(destroyed);
130 }
131 
TEST_F(QuicheReferenceCountedTest,PointerMoveAssignment)132 TEST_F(QuicheReferenceCountedTest, PointerMoveAssignment) {
133   bool destroyed = false;
134   QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
135   EXPECT_FALSE(destroyed);
136   QuicheReferenceCountedPointer<Base> b = std::move(a);
137   EXPECT_FALSE(destroyed);
138   EXPECT_NE(nullptr, b);
139   EXPECT_EQ(nullptr, a);  // NOLINT
140 
141   b = nullptr;
142   EXPECT_TRUE(destroyed);
143 }
144 
TEST_F(QuicheReferenceCountedTest,PointerMoveFromOtherType)145 TEST_F(QuicheReferenceCountedTest, PointerMoveFromOtherType) {
146   bool destroyed = false;
147   QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
148   EXPECT_FALSE(destroyed);
149   QuicheReferenceCountedPointer<Base> b(std::move(a));
150   EXPECT_FALSE(destroyed);
151   EXPECT_NE(nullptr, b);
152   EXPECT_EQ(nullptr, a);  // NOLINT
153 
154   b = nullptr;
155   EXPECT_TRUE(destroyed);
156 }
157 
TEST_F(QuicheReferenceCountedTest,PointerMoveAssignmentFromOtherType)158 TEST_F(QuicheReferenceCountedTest, PointerMoveAssignmentFromOtherType) {
159   bool destroyed = false;
160   QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
161   EXPECT_FALSE(destroyed);
162   QuicheReferenceCountedPointer<Base> b = std::move(a);
163   EXPECT_FALSE(destroyed);
164   EXPECT_NE(nullptr, b);
165   EXPECT_EQ(nullptr, a);  // NOLINT
166 
167   b = nullptr;
168   EXPECT_TRUE(destroyed);
169 }
170 
171 }  // namespace
172 }  // namespace test
173 }  // namespace quiche
174