1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/scoped_generic.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <utility>
8*635a8641SAndroid Build Coastguard Worker #include <vector>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker namespace base {
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard Worker namespace {
15*635a8641SAndroid Build Coastguard Worker
16*635a8641SAndroid Build Coastguard Worker struct IntTraits {
IntTraitsbase::__anon9b230a620111::IntTraits17*635a8641SAndroid Build Coastguard Worker IntTraits(std::vector<int>* freed) : freed_ints(freed) {}
18*635a8641SAndroid Build Coastguard Worker
InvalidValuebase::__anon9b230a620111::IntTraits19*635a8641SAndroid Build Coastguard Worker static int InvalidValue() {
20*635a8641SAndroid Build Coastguard Worker return -1;
21*635a8641SAndroid Build Coastguard Worker }
Freebase::__anon9b230a620111::IntTraits22*635a8641SAndroid Build Coastguard Worker void Free(int value) {
23*635a8641SAndroid Build Coastguard Worker freed_ints->push_back(value);
24*635a8641SAndroid Build Coastguard Worker }
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker std::vector<int>* freed_ints;
27*635a8641SAndroid Build Coastguard Worker };
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker typedef ScopedGeneric<int, IntTraits> ScopedInt;
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker } // namespace
32*635a8641SAndroid Build Coastguard Worker
TEST(ScopedGenericTest,ScopedGeneric)33*635a8641SAndroid Build Coastguard Worker TEST(ScopedGenericTest, ScopedGeneric) {
34*635a8641SAndroid Build Coastguard Worker std::vector<int> values_freed;
35*635a8641SAndroid Build Coastguard Worker IntTraits traits(&values_freed);
36*635a8641SAndroid Build Coastguard Worker
37*635a8641SAndroid Build Coastguard Worker // Invalid case, delete should not be called.
38*635a8641SAndroid Build Coastguard Worker {
39*635a8641SAndroid Build Coastguard Worker ScopedInt a(IntTraits::InvalidValue(), traits);
40*635a8641SAndroid Build Coastguard Worker }
41*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(values_freed.empty());
42*635a8641SAndroid Build Coastguard Worker
43*635a8641SAndroid Build Coastguard Worker // Simple deleting case.
44*635a8641SAndroid Build Coastguard Worker static const int kFirst = 0;
45*635a8641SAndroid Build Coastguard Worker {
46*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
47*635a8641SAndroid Build Coastguard Worker }
48*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1u, values_freed.size());
49*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kFirst, values_freed[0]);
50*635a8641SAndroid Build Coastguard Worker values_freed.clear();
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker // Release should return the right value and leave the object empty.
53*635a8641SAndroid Build Coastguard Worker {
54*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
55*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kFirst, a.release());
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker ScopedInt b(IntTraits::InvalidValue(), traits);
58*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(IntTraits::InvalidValue(), b.release());
59*635a8641SAndroid Build Coastguard Worker }
60*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(values_freed.empty());
61*635a8641SAndroid Build Coastguard Worker
62*635a8641SAndroid Build Coastguard Worker // Reset should free the old value, then the new one should go away when
63*635a8641SAndroid Build Coastguard Worker // it goes out of scope.
64*635a8641SAndroid Build Coastguard Worker static const int kSecond = 1;
65*635a8641SAndroid Build Coastguard Worker {
66*635a8641SAndroid Build Coastguard Worker ScopedInt b(kFirst, traits);
67*635a8641SAndroid Build Coastguard Worker b.reset(kSecond);
68*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1u, values_freed.size());
69*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kFirst, values_freed[0]);
70*635a8641SAndroid Build Coastguard Worker }
71*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2u, values_freed.size());
72*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kSecond, values_freed[1]);
73*635a8641SAndroid Build Coastguard Worker values_freed.clear();
74*635a8641SAndroid Build Coastguard Worker
75*635a8641SAndroid Build Coastguard Worker // Swap.
76*635a8641SAndroid Build Coastguard Worker {
77*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
78*635a8641SAndroid Build Coastguard Worker ScopedInt b(kSecond, traits);
79*635a8641SAndroid Build Coastguard Worker a.swap(b);
80*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(values_freed.empty()); // Nothing should be freed.
81*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kSecond, a.get());
82*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kFirst, b.get());
83*635a8641SAndroid Build Coastguard Worker }
84*635a8641SAndroid Build Coastguard Worker // Values should be deleted in the opposite order.
85*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2u, values_freed.size());
86*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kFirst, values_freed[0]);
87*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kSecond, values_freed[1]);
88*635a8641SAndroid Build Coastguard Worker values_freed.clear();
89*635a8641SAndroid Build Coastguard Worker
90*635a8641SAndroid Build Coastguard Worker // Move constructor.
91*635a8641SAndroid Build Coastguard Worker {
92*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
93*635a8641SAndroid Build Coastguard Worker ScopedInt b(std::move(a));
94*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(values_freed.empty()); // Nothing should be freed.
95*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(IntTraits::InvalidValue(), a.get());
96*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kFirst, b.get());
97*635a8641SAndroid Build Coastguard Worker }
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1u, values_freed.size());
100*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kFirst, values_freed[0]);
101*635a8641SAndroid Build Coastguard Worker values_freed.clear();
102*635a8641SAndroid Build Coastguard Worker
103*635a8641SAndroid Build Coastguard Worker // Move assign.
104*635a8641SAndroid Build Coastguard Worker {
105*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
106*635a8641SAndroid Build Coastguard Worker ScopedInt b(kSecond, traits);
107*635a8641SAndroid Build Coastguard Worker b = std::move(a);
108*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(1u, values_freed.size());
109*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kSecond, values_freed[0]);
110*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(IntTraits::InvalidValue(), a.get());
111*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kFirst, b.get());
112*635a8641SAndroid Build Coastguard Worker }
113*635a8641SAndroid Build Coastguard Worker
114*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(2u, values_freed.size());
115*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kFirst, values_freed[1]);
116*635a8641SAndroid Build Coastguard Worker values_freed.clear();
117*635a8641SAndroid Build Coastguard Worker }
118*635a8641SAndroid Build Coastguard Worker
TEST(ScopedGenericTest,Operators)119*635a8641SAndroid Build Coastguard Worker TEST(ScopedGenericTest, Operators) {
120*635a8641SAndroid Build Coastguard Worker std::vector<int> values_freed;
121*635a8641SAndroid Build Coastguard Worker IntTraits traits(&values_freed);
122*635a8641SAndroid Build Coastguard Worker
123*635a8641SAndroid Build Coastguard Worker static const int kFirst = 0;
124*635a8641SAndroid Build Coastguard Worker static const int kSecond = 1;
125*635a8641SAndroid Build Coastguard Worker {
126*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
127*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(a == kFirst);
128*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(a != kFirst);
129*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(a == kSecond);
130*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(a != kSecond);
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(kFirst == a);
133*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(kFirst != a);
134*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(kSecond == a);
135*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(kSecond != a);
136*635a8641SAndroid Build Coastguard Worker }
137*635a8641SAndroid Build Coastguard Worker
138*635a8641SAndroid Build Coastguard Worker // is_valid().
139*635a8641SAndroid Build Coastguard Worker {
140*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
141*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(a.is_valid());
142*635a8641SAndroid Build Coastguard Worker a.reset();
143*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(a.is_valid());
144*635a8641SAndroid Build Coastguard Worker }
145*635a8641SAndroid Build Coastguard Worker }
146*635a8641SAndroid Build Coastguard Worker
147*635a8641SAndroid Build Coastguard Worker // Cheesy manual "no compile" test for manually validating changes.
148*635a8641SAndroid Build Coastguard Worker #if 0
149*635a8641SAndroid Build Coastguard Worker TEST(ScopedGenericTest, NoCompile) {
150*635a8641SAndroid Build Coastguard Worker // Assignment shouldn't work.
151*635a8641SAndroid Build Coastguard Worker /*{
152*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
153*635a8641SAndroid Build Coastguard Worker ScopedInt b(a);
154*635a8641SAndroid Build Coastguard Worker }*/
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker // Comparison shouldn't work.
157*635a8641SAndroid Build Coastguard Worker /*{
158*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
159*635a8641SAndroid Build Coastguard Worker ScopedInt b(kFirst, traits);
160*635a8641SAndroid Build Coastguard Worker if (a == b) {
161*635a8641SAndroid Build Coastguard Worker }
162*635a8641SAndroid Build Coastguard Worker }*/
163*635a8641SAndroid Build Coastguard Worker
164*635a8641SAndroid Build Coastguard Worker // Implicit conversion to bool shouldn't work.
165*635a8641SAndroid Build Coastguard Worker /*{
166*635a8641SAndroid Build Coastguard Worker ScopedInt a(kFirst, traits);
167*635a8641SAndroid Build Coastguard Worker bool result = a;
168*635a8641SAndroid Build Coastguard Worker }*/
169*635a8641SAndroid Build Coastguard Worker }
170*635a8641SAndroid Build Coastguard Worker #endif
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker } // namespace base
173