Update .DEPS.git
[chromium-blink-merge.git] / base / memory / scoped_ptr_unittest.cc
blob3da6f15273181070fa51cc25107708def2fffa1f
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.
5 #include "base/basictypes.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "testing/gtest/include/gtest/gtest.h"
9 namespace {
11 // Used to test depth subtyping.
12 class ConDecLoggerParent {
13 public:
14 virtual ~ConDecLoggerParent() {}
16 virtual void SetPtr(int* ptr) = 0;
18 virtual int SomeMeth(int x) const = 0;
21 class ConDecLogger : public ConDecLoggerParent {
22 public:
23 ConDecLogger() : ptr_(NULL) { }
24 explicit ConDecLogger(int* ptr) { SetPtr(ptr); }
25 virtual ~ConDecLogger() { --*ptr_; }
27 virtual void SetPtr(int* ptr) OVERRIDE { ptr_ = ptr; ++*ptr_; }
29 virtual int SomeMeth(int x) const OVERRIDE { return x; }
31 private:
32 int* ptr_;
34 DISALLOW_COPY_AND_ASSIGN(ConDecLogger);
37 scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
38 return logger.Pass();
41 void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
44 // Do not delete this function! It's existence is to test that you can
45 // return a temporarily constructed version of the scoper.
46 scoped_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
47 return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
50 scoped_ptr<ConDecLoggerParent> UpcastUsingPassAs(
51 scoped_ptr<ConDecLogger> object) {
52 return object.PassAs<ConDecLoggerParent>();
55 } // namespace
57 TEST(ScopedPtrTest, ScopedPtr) {
58 int constructed = 0;
61 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
62 EXPECT_EQ(1, constructed);
63 EXPECT_TRUE(scoper.get());
65 EXPECT_EQ(10, scoper->SomeMeth(10));
66 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
67 EXPECT_EQ(10, (*scoper).SomeMeth(10));
69 EXPECT_EQ(0, constructed);
71 // Test reset() and release()
73 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
74 EXPECT_EQ(1, constructed);
75 EXPECT_TRUE(scoper.get());
77 scoper.reset(new ConDecLogger(&constructed));
78 EXPECT_EQ(1, constructed);
79 EXPECT_TRUE(scoper.get());
81 scoper.reset();
82 EXPECT_EQ(0, constructed);
83 EXPECT_FALSE(scoper.get());
85 scoper.reset(new ConDecLogger(&constructed));
86 EXPECT_EQ(1, constructed);
87 EXPECT_TRUE(scoper.get());
89 ConDecLogger* take = scoper.release();
90 EXPECT_EQ(1, constructed);
91 EXPECT_FALSE(scoper.get());
92 delete take;
93 EXPECT_EQ(0, constructed);
95 scoper.reset(new ConDecLogger(&constructed));
96 EXPECT_EQ(1, constructed);
97 EXPECT_TRUE(scoper.get());
99 EXPECT_EQ(0, constructed);
101 // Test swap(), == and !=
103 scoped_ptr<ConDecLogger> scoper1;
104 scoped_ptr<ConDecLogger> scoper2;
105 EXPECT_TRUE(scoper1 == scoper2.get());
106 EXPECT_FALSE(scoper1 != scoper2.get());
108 ConDecLogger* logger = new ConDecLogger(&constructed);
109 scoper1.reset(logger);
110 EXPECT_EQ(logger, scoper1.get());
111 EXPECT_FALSE(scoper2.get());
112 EXPECT_FALSE(scoper1 == scoper2.get());
113 EXPECT_TRUE(scoper1 != scoper2.get());
115 scoper2.swap(scoper1);
116 EXPECT_EQ(logger, scoper2.get());
117 EXPECT_FALSE(scoper1.get());
118 EXPECT_FALSE(scoper1 == scoper2.get());
119 EXPECT_TRUE(scoper1 != scoper2.get());
121 EXPECT_EQ(0, constructed);
124 TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
125 int constructed = 0;
127 // Test construction from a scoped_ptr to a derived class.
129 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
130 EXPECT_EQ(1, constructed);
131 EXPECT_TRUE(scoper.get());
133 scoped_ptr<ConDecLoggerParent> scoper_parent(scoper.Pass());
134 EXPECT_EQ(1, constructed);
135 EXPECT_TRUE(scoper_parent.get());
136 EXPECT_FALSE(scoper.get());
138 EXPECT_EQ(10, scoper_parent->SomeMeth(10));
139 EXPECT_EQ(10, scoper_parent.get()->SomeMeth(10));
140 EXPECT_EQ(10, (*scoper_parent).SomeMeth(10));
142 EXPECT_EQ(0, constructed);
144 // Test assignment from a scoped_ptr to a derived class.
146 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
147 EXPECT_EQ(1, constructed);
148 EXPECT_TRUE(scoper.get());
150 scoped_ptr<ConDecLoggerParent> scoper_parent;
151 scoper_parent = scoper.Pass();
152 EXPECT_EQ(1, constructed);
153 EXPECT_TRUE(scoper_parent.get());
154 EXPECT_FALSE(scoper.get());
156 EXPECT_EQ(0, constructed);
158 // Test construction of a scoped_ptr with an additional const annotation.
160 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
161 EXPECT_EQ(1, constructed);
162 EXPECT_TRUE(scoper.get());
164 scoped_ptr<const ConDecLogger> scoper_const(scoper.Pass());
165 EXPECT_EQ(1, constructed);
166 EXPECT_TRUE(scoper_const.get());
167 EXPECT_FALSE(scoper.get());
169 EXPECT_EQ(10, scoper_const->SomeMeth(10));
170 EXPECT_EQ(10, scoper_const.get()->SomeMeth(10));
171 EXPECT_EQ(10, (*scoper_const).SomeMeth(10));
173 EXPECT_EQ(0, constructed);
175 // Test assignment to a scoped_ptr with an additional const annotation.
177 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
178 EXPECT_EQ(1, constructed);
179 EXPECT_TRUE(scoper.get());
181 scoped_ptr<const ConDecLogger> scoper_const;
182 scoper_const = scoper.Pass();
183 EXPECT_EQ(1, constructed);
184 EXPECT_TRUE(scoper_const.get());
185 EXPECT_FALSE(scoper.get());
187 EXPECT_EQ(0, constructed);
190 TEST(ScopedPtrTest, ScopedArray) {
191 static const int kNumLoggers = 12;
193 int constructed = 0;
196 scoped_array<ConDecLogger> scoper(new ConDecLogger[kNumLoggers]);
197 EXPECT_TRUE(scoper.get());
198 EXPECT_EQ(&scoper[0], scoper.get());
199 for (int i = 0; i < kNumLoggers; ++i) {
200 scoper[i].SetPtr(&constructed);
202 EXPECT_EQ(12, constructed);
204 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
205 EXPECT_EQ(10, scoper[2].SomeMeth(10));
207 EXPECT_EQ(0, constructed);
209 // Test reset() and release()
211 scoped_array<ConDecLogger> scoper;
212 EXPECT_FALSE(scoper.get());
213 EXPECT_FALSE(scoper.release());
214 EXPECT_FALSE(scoper.get());
215 scoper.reset();
216 EXPECT_FALSE(scoper.get());
218 scoper.reset(new ConDecLogger[kNumLoggers]);
219 for (int i = 0; i < kNumLoggers; ++i) {
220 scoper[i].SetPtr(&constructed);
222 EXPECT_EQ(12, constructed);
223 scoper.reset();
224 EXPECT_EQ(0, constructed);
226 scoper.reset(new ConDecLogger[kNumLoggers]);
227 for (int i = 0; i < kNumLoggers; ++i) {
228 scoper[i].SetPtr(&constructed);
230 EXPECT_EQ(12, constructed);
231 ConDecLogger* ptr = scoper.release();
232 EXPECT_EQ(12, constructed);
233 delete[] ptr;
234 EXPECT_EQ(0, constructed);
236 EXPECT_EQ(0, constructed);
238 // Test swap(), == and !=
240 scoped_array<ConDecLogger> scoper1;
241 scoped_array<ConDecLogger> scoper2;
242 EXPECT_TRUE(scoper1 == scoper2.get());
243 EXPECT_FALSE(scoper1 != scoper2.get());
245 ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
246 for (int i = 0; i < kNumLoggers; ++i) {
247 loggers[i].SetPtr(&constructed);
249 scoper1.reset(loggers);
250 EXPECT_EQ(loggers, scoper1.get());
251 EXPECT_FALSE(scoper2.get());
252 EXPECT_FALSE(scoper1 == scoper2.get());
253 EXPECT_TRUE(scoper1 != scoper2.get());
255 scoper2.swap(scoper1);
256 EXPECT_EQ(loggers, scoper2.get());
257 EXPECT_FALSE(scoper1.get());
258 EXPECT_FALSE(scoper1 == scoper2.get());
259 EXPECT_TRUE(scoper1 != scoper2.get());
261 EXPECT_EQ(0, constructed);
264 TEST(ScopedPtrTest, PassBehavior) {
265 int constructed = 0;
267 ConDecLogger* logger = new ConDecLogger(&constructed);
268 scoped_ptr<ConDecLogger> scoper(logger);
269 EXPECT_EQ(1, constructed);
271 // Test Pass() with constructor;
272 scoped_ptr<ConDecLogger> scoper2(scoper.Pass());
273 EXPECT_EQ(1, constructed);
275 // Test Pass() with assignment;
276 scoped_ptr<ConDecLogger> scoper3;
277 scoper3 = scoper2.Pass();
278 EXPECT_EQ(1, constructed);
279 EXPECT_FALSE(scoper.get());
280 EXPECT_FALSE(scoper2.get());
281 EXPECT_TRUE(scoper3.get());
284 // Test uncaught Pass() does not leak.
286 ConDecLogger* logger = new ConDecLogger(&constructed);
287 scoped_ptr<ConDecLogger> scoper(logger);
288 EXPECT_EQ(1, constructed);
290 // Should auto-destruct logger by end of scope.
291 scoper.Pass();
292 EXPECT_FALSE(scoper.get());
294 EXPECT_EQ(0, constructed);
296 // Test that passing to function which does nothing does not leak.
298 ConDecLogger* logger = new ConDecLogger(&constructed);
299 scoped_ptr<ConDecLogger> scoper(logger);
300 EXPECT_EQ(1, constructed);
302 // Should auto-destruct logger by end of scope.
303 GrabAndDrop(scoper.Pass());
304 EXPECT_FALSE(scoper.get());
306 EXPECT_EQ(0, constructed);
309 TEST(ScopedPtrTest, ReturnTypeBehavior) {
310 int constructed = 0;
312 // Test that we can return a scoped_ptr.
314 ConDecLogger* logger = new ConDecLogger(&constructed);
315 scoped_ptr<ConDecLogger> scoper(logger);
316 EXPECT_EQ(1, constructed);
318 PassThru(scoper.Pass());
319 EXPECT_FALSE(scoper.get());
321 EXPECT_EQ(0, constructed);
323 // Test uncaught return type not leak.
325 ConDecLogger* logger = new ConDecLogger(&constructed);
326 scoped_ptr<ConDecLogger> scoper(logger);
327 EXPECT_EQ(1, constructed);
329 // Should auto-destruct logger by end of scope.
330 PassThru(scoper.Pass());
331 EXPECT_FALSE(scoper.get());
333 EXPECT_EQ(0, constructed);
335 // Call TestReturnOfType() so the compiler doesn't warn for an unused
336 // function.
338 TestReturnOfType(&constructed);
340 EXPECT_EQ(0, constructed);
343 TEST(ScopedPtrTest, PassAs) {
344 int constructed = 0;
346 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
347 EXPECT_EQ(1, constructed);
348 EXPECT_TRUE(scoper.get());
350 scoped_ptr<ConDecLoggerParent> scoper_parent;
351 scoper_parent = UpcastUsingPassAs(scoper.Pass());
352 EXPECT_EQ(1, constructed);
353 EXPECT_TRUE(scoper_parent.get());
354 EXPECT_FALSE(scoper.get());
356 EXPECT_EQ(0, constructed);
359 // TODO scoped_ptr_malloc