cros: Implement default app ordering.
[chromium-blink-merge.git] / base / cancelable_callback_unittest.cc
blob51a2a090d800223dd6188ba21ceee7472156d328
1 // Copyright (c) 2011 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/cancelable_callback.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace base {
14 namespace {
16 class TestRefCounted : public RefCountedThreadSafe<TestRefCounted> {
17 private:
18 friend class RefCountedThreadSafe<TestRefCounted>;
19 ~TestRefCounted() {};
22 void Increment(int* count) { (*count)++; }
23 void IncrementBy(int* count, int n) { (*count) += n; }
24 void RefCountedParam(const scoped_refptr<TestRefCounted>& ref_counted) {}
26 // Cancel().
27 // - Callback can be run multiple times.
28 // - After Cancel(), Run() completes but has no effect.
29 TEST(CancelableCallbackTest, Cancel) {
30 int count = 0;
31 CancelableClosure cancelable(
32 base::Bind(&Increment, base::Unretained(&count)));
34 base::Closure callback = cancelable.callback();
35 callback.Run();
36 EXPECT_EQ(1, count);
38 callback.Run();
39 EXPECT_EQ(2, count);
41 cancelable.Cancel();
42 callback.Run();
43 EXPECT_EQ(2, count);
46 // Cancel() called multiple times.
47 // - Cancel() cancels all copies of the wrapped callback.
48 // - Calling Cancel() more than once has no effect.
49 // - After Cancel(), callback() returns a null callback.
50 TEST(CancelableCallbackTest, MultipleCancel) {
51 int count = 0;
52 CancelableClosure cancelable(
53 base::Bind(&Increment, base::Unretained(&count)));
55 base::Closure callback1 = cancelable.callback();
56 base::Closure callback2 = cancelable.callback();
57 cancelable.Cancel();
59 callback1.Run();
60 EXPECT_EQ(0, count);
62 callback2.Run();
63 EXPECT_EQ(0, count);
65 // Calling Cancel() again has no effect.
66 cancelable.Cancel();
68 // callback() of a cancelled callback is null.
69 base::Closure callback3 = cancelable.callback();
70 EXPECT_TRUE(callback3.is_null());
73 // CancelableCallback destroyed before callback is run.
74 // - Destruction of CancelableCallback cancels outstanding callbacks.
75 TEST(CancelableCallbackTest, CallbackCanceledOnDestruction) {
76 int count = 0;
77 base::Closure callback;
80 CancelableClosure cancelable(
81 base::Bind(&Increment, base::Unretained(&count)));
83 callback = cancelable.callback();
84 callback.Run();
85 EXPECT_EQ(1, count);
88 callback.Run();
89 EXPECT_EQ(1, count);
92 // Cancel() called on bound closure with a RefCounted parameter.
93 // - Cancel drops wrapped callback (and, implicitly, its bound arguments).
94 TEST(CancelableCallbackTest, CancelDropsCallback) {
95 scoped_refptr<TestRefCounted> ref_counted = new TestRefCounted;
96 EXPECT_TRUE(ref_counted->HasOneRef());
98 CancelableClosure cancelable(base::Bind(RefCountedParam, ref_counted));
99 EXPECT_FALSE(cancelable.IsCancelled());
100 EXPECT_TRUE(ref_counted.get());
101 EXPECT_FALSE(ref_counted->HasOneRef());
103 // There is only one reference to |ref_counted| after the Cancel().
104 cancelable.Cancel();
105 EXPECT_TRUE(cancelable.IsCancelled());
106 EXPECT_TRUE(ref_counted.get());
107 EXPECT_TRUE(ref_counted->HasOneRef());
110 // Reset().
111 // - Reset() replaces the existing wrapped callback with a new callback.
112 // - Reset() deactivates outstanding callbacks.
113 TEST(CancelableCallbackTest, Reset) {
114 int count = 0;
115 CancelableClosure cancelable(
116 base::Bind(&Increment, base::Unretained(&count)));
118 base::Closure callback = cancelable.callback();
119 callback.Run();
120 EXPECT_EQ(1, count);
122 callback.Run();
123 EXPECT_EQ(2, count);
125 cancelable.Reset(
126 base::Bind(&IncrementBy, base::Unretained(&count), 3));
127 EXPECT_FALSE(cancelable.IsCancelled());
129 // The stale copy of the cancelable callback is non-null.
130 ASSERT_FALSE(callback.is_null());
132 // The stale copy of the cancelable callback is no longer active.
133 callback.Run();
134 EXPECT_EQ(2, count);
136 base::Closure callback2 = cancelable.callback();
137 ASSERT_FALSE(callback2.is_null());
139 callback2.Run();
140 EXPECT_EQ(5, count);
143 // IsCanceled().
144 // - Cancel() transforms the CancelableCallback into a cancelled state.
145 TEST(CancelableCallbackTest, IsNull) {
146 CancelableClosure cancelable;
147 EXPECT_TRUE(cancelable.IsCancelled());
149 int count = 0;
150 cancelable.Reset(base::Bind(&Increment,
151 base::Unretained(&count)));
152 EXPECT_FALSE(cancelable.IsCancelled());
154 cancelable.Cancel();
155 EXPECT_TRUE(cancelable.IsCancelled());
158 // CancelableCallback posted to a MessageLoop with PostTask.
159 // - Callbacks posted to a MessageLoop can be cancelled.
160 TEST(CancelableCallbackTest, PostTask) {
161 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
163 int count = 0;
164 CancelableClosure cancelable(base::Bind(&Increment,
165 base::Unretained(&count)));
167 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
168 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
169 MessageLoop::current()->Run();
171 EXPECT_EQ(1, count);
173 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
174 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
176 // Cancel before running the message loop.
177 cancelable.Cancel();
178 MessageLoop::current()->Run();
180 // Callback never ran due to cancellation; count is the same.
181 EXPECT_EQ(1, count);
184 } // namespace
185 } // namespace base