Tweak/Wontfix a few tests that we could care less about.
[chromium-blink-merge.git] / base / singleton_unittest.cc
blobbb46bee83bbb16338399ee16b76cc1985ed3abf9
1 // Copyright (c) 2006-2008 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/at_exit.h"
6 #include "base/file_util.h"
7 #include "base/path_service.h"
8 #include "base/singleton.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace {
13 COMPILE_ASSERT(DefaultSingletonTraits<int>::kRegisterAtExit == true, a);
15 template<typename Type>
16 struct LockTrait : public DefaultSingletonTraits<Type> {
19 struct Init5Trait : public DefaultSingletonTraits<int> {
20 static int* New() {
21 return new int(5);
25 typedef void (*CallbackFunc)();
27 struct CallbackTrait : public DefaultSingletonTraits<CallbackFunc> {
28 static void Delete(CallbackFunc* p) {
29 if (*p)
30 (*p)();
31 DefaultSingletonTraits<CallbackFunc>::Delete(p);
35 struct NoLeakTrait : public CallbackTrait {
38 struct LeakTrait : public CallbackTrait {
39 static const bool kRegisterAtExit = false;
42 int* SingletonInt1() {
43 return Singleton<int>::get();
46 int* SingletonInt2() {
47 // Force to use a different singleton than SingletonInt1.
48 return Singleton<int, DefaultSingletonTraits<int> >::get();
51 class DummyDifferentiatingClass {
54 int* SingletonInt3() {
55 // Force to use a different singleton than SingletonInt1 and SingletonInt2.
56 // Note that any type can be used; int, float, std::wstring...
57 return Singleton<int, DefaultSingletonTraits<int>,
58 DummyDifferentiatingClass>::get();
61 int* SingletonInt4() {
62 return Singleton<int, LockTrait<int> >::get();
65 int* SingletonInt5() {
66 return Singleton<int, Init5Trait>::get();
69 void SingletonNoLeak(CallbackFunc CallOnQuit) {
70 *Singleton<CallbackFunc, NoLeakTrait>::get() = CallOnQuit;
73 void SingletonLeak(CallbackFunc CallOnQuit) {
74 *Singleton<CallbackFunc, LeakTrait>::get() = CallOnQuit;
77 CallbackFunc* GetLeakySingleton() {
78 return Singleton<CallbackFunc, LeakTrait>::get();
81 } // namespace
83 class SingletonTest : public testing::Test {
84 public:
85 SingletonTest() { }
87 virtual void SetUp() {
88 non_leak_called_ = false;
89 leaky_called_ = false;
92 protected:
93 void VerifiesCallbacks() {
94 EXPECT_TRUE(non_leak_called_);
95 EXPECT_FALSE(leaky_called_);
96 non_leak_called_ = false;
97 leaky_called_ = false;
100 void VerifiesCallbacksNotCalled() {
101 EXPECT_FALSE(non_leak_called_);
102 EXPECT_FALSE(leaky_called_);
103 non_leak_called_ = false;
104 leaky_called_ = false;
107 static void CallbackNoLeak() {
108 non_leak_called_ = true;
111 static void CallbackLeak() {
112 leaky_called_ = true;
115 private:
116 static bool non_leak_called_;
117 static bool leaky_called_;
120 bool SingletonTest::non_leak_called_ = false;
121 bool SingletonTest::leaky_called_ = false;
123 TEST_F(SingletonTest, Basic) {
124 int* singleton_int_1;
125 int* singleton_int_2;
126 int* singleton_int_3;
127 int* singleton_int_4;
128 int* singleton_int_5;
129 CallbackFunc* leaky_singleton;
132 base::ShadowingAtExitManager sem;
134 singleton_int_1 = SingletonInt1();
136 // Ensure POD type initialization.
137 EXPECT_EQ(*singleton_int_1, 0);
138 *singleton_int_1 = 1;
140 EXPECT_EQ(singleton_int_1, SingletonInt1());
141 EXPECT_EQ(*singleton_int_1, 1);
144 singleton_int_2 = SingletonInt2();
146 // Same instance that 1.
147 EXPECT_EQ(*singleton_int_2, 1);
148 EXPECT_EQ(singleton_int_1, singleton_int_2);
151 singleton_int_3 = SingletonInt3();
153 // Different instance than 1 and 2.
154 EXPECT_EQ(*singleton_int_3, 0);
155 EXPECT_NE(singleton_int_1, singleton_int_3);
156 *singleton_int_3 = 3;
157 EXPECT_EQ(*singleton_int_1, 1);
158 EXPECT_EQ(*singleton_int_2, 1);
161 singleton_int_4 = SingletonInt4();
163 // Use a lock for creation. Not really tested at length.
164 EXPECT_EQ(*singleton_int_4, 0);
165 *singleton_int_4 = 4;
166 EXPECT_NE(singleton_int_1, singleton_int_4);
167 EXPECT_NE(singleton_int_3, singleton_int_4);
170 singleton_int_5 = SingletonInt5();
172 // Is default initialized to 5.
173 EXPECT_EQ(*singleton_int_5, 5);
174 EXPECT_NE(singleton_int_1, singleton_int_5);
175 EXPECT_NE(singleton_int_3, singleton_int_5);
176 EXPECT_NE(singleton_int_4, singleton_int_5);
178 SingletonNoLeak(&CallbackNoLeak);
179 SingletonLeak(&CallbackLeak);
180 leaky_singleton = GetLeakySingleton();
181 EXPECT_TRUE(leaky_singleton);
184 // Verify that only the expected callback has been called.
185 VerifiesCallbacks();
186 // Delete the leaky singleton. It is interesting to note that Purify does
187 // *not* detect the leak when this call is commented out. :(
188 DefaultSingletonTraits<CallbackFunc>::Delete(leaky_singleton);
191 base::ShadowingAtExitManager sem;
192 // Verifiy that the variables were reset.
194 singleton_int_1 = SingletonInt1();
195 EXPECT_EQ(*singleton_int_1, 0);
198 singleton_int_5 = SingletonInt5();
199 EXPECT_EQ(*singleton_int_5, 5);
202 // The leaky singleton shouldn't leak since SingletonLeak has not been called.
203 VerifiesCallbacksNotCalled();