callback_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2009 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 "base/callback.h"
6#include "base/callback_internal.h"
7#include "base/scoped_ptr.h"
8
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace base {
12namespace {
13
14class HelperObject {
15 public:
16  HelperObject() : next_number_(0) { }
17  int GetNextNumber() { return ++next_number_; }
18  void GetNextNumberArg(int* number) { *number = GetNextNumber(); }
19
20 private:
21  int next_number_;
22};
23
24struct FakeInvoker {
25  static void DoInvoke(internal::InvokerStorageBase*) {
26  }
27};
28
29// White-box testpoints to inject into a Callback<> object for checking
30// comparators and emptiness APIs.
31class FakeInvokerStorage1 : public internal::InvokerStorageBase {
32 public:
33  typedef FakeInvoker Invoker;
34};
35
36class FakeInvokerStorage2 : public internal::InvokerStorageBase {
37 public:
38  typedef FakeInvoker Invoker;
39};
40
41TEST(CallbackOld, OneArg) {
42  HelperObject obj;
43  scoped_ptr<Callback1<int*>::Type> callback(
44      NewCallback(&obj, &HelperObject::GetNextNumberArg));
45
46  int number = 0;
47  callback->Run(&number);
48  EXPECT_EQ(number, 1);
49}
50
51TEST(CallbackOld, ReturnValue) {
52  HelperObject obj;
53  scoped_ptr<CallbackWithReturnValue<int>::Type> callback(
54      NewCallbackWithReturnValue(&obj, &HelperObject::GetNextNumber));
55
56  EXPECT_EQ(callback->Run(), 1);
57}
58
59class CallbackTest : public ::testing::Test {
60 public:
61  CallbackTest()
62      : callback_a_(MakeInvokerStorageHolder(new FakeInvokerStorage1())),
63        callback_b_(MakeInvokerStorageHolder(new FakeInvokerStorage2())) {
64  }
65
66  virtual ~CallbackTest() {
67  }
68
69 protected:
70  Callback<void(void)> callback_a_;
71  const Callback<void(void)> callback_b_;  // Ensure APIs work with const.
72  Callback<void(void)> null_callback_;
73};
74
75// Ensure we can create unbound callbacks. We need this to be able to store
76// them in class members that can be initialized later.
77TEST_F(CallbackTest, DefaultConstruction) {
78  Callback<void(void)> c0;
79  Callback<void(int)> c1;
80  Callback<void(int,int)> c2;
81  Callback<void(int,int,int)> c3;
82  Callback<void(int,int,int,int)> c4;
83  Callback<void(int,int,int,int,int)> c5;
84  Callback<void(int,int,int,int,int,int)> c6;
85
86  EXPECT_TRUE(c0.is_null());
87  EXPECT_TRUE(c1.is_null());
88  EXPECT_TRUE(c2.is_null());
89  EXPECT_TRUE(c3.is_null());
90  EXPECT_TRUE(c4.is_null());
91  EXPECT_TRUE(c5.is_null());
92  EXPECT_TRUE(c6.is_null());
93}
94
95TEST_F(CallbackTest, IsNull) {
96  EXPECT_TRUE(null_callback_.is_null());
97  EXPECT_FALSE(callback_a_.is_null());
98  EXPECT_FALSE(callback_b_.is_null());
99}
100
101TEST_F(CallbackTest, Equals) {
102  EXPECT_TRUE(callback_a_.Equals(callback_a_));
103  EXPECT_FALSE(callback_a_.Equals(callback_b_));
104  EXPECT_FALSE(callback_b_.Equals(callback_a_));
105
106  // We should compare based on instance, not type.
107  Callback<void(void)> callback_c(
108      MakeInvokerStorageHolder(new FakeInvokerStorage1()));
109  Callback<void(void)> callback_a2 = callback_a_;
110  EXPECT_TRUE(callback_a_.Equals(callback_a2));
111  EXPECT_FALSE(callback_a_.Equals(callback_c));
112
113  // Empty, however, is always equal to empty.
114  Callback<void(void)> empty2;
115  EXPECT_TRUE(null_callback_.Equals(empty2));
116}
117
118TEST_F(CallbackTest, Reset) {
119  // Resetting should bring us back to empty.
120  ASSERT_FALSE(callback_a_.is_null());
121  ASSERT_FALSE(callback_a_.Equals(null_callback_));
122
123  callback_a_.Reset();
124
125  EXPECT_TRUE(callback_a_.is_null());
126  EXPECT_TRUE(callback_a_.Equals(null_callback_));
127}
128
129}  // namespace
130}  // namespace base
131