callback_unittest.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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.
  4. #include "butil/bind.h"
  5. #include "butil/callback.h"
  6. #include "butil/callback_helpers.h"
  7. #include "butil/callback_internal.h"
  8. #include "butil/memory/ref_counted.h"
  9. #include "butil/memory/scoped_ptr.h"
  10. #include <gtest/gtest.h>
  11. namespace butil {
  12. namespace {
  13. struct FakeInvoker {
  14. typedef void(RunType)(internal::BindStateBase*);
  15. static void Run(internal::BindStateBase*) {
  16. }
  17. };
  18. } // namespace
  19. namespace internal {
  20. template <typename Runnable, typename RunType, typename BoundArgsType>
  21. struct BindState;
  22. // White-box testpoints to inject into a Callback<> object for checking
  23. // comparators and emptiness APIs. Use a BindState that is specialized
  24. // based on a type we declared in the anonymous namespace above to remove any
  25. // chance of colliding with another instantiation and breaking the
  26. // one-definition-rule.
  27. template <>
  28. struct BindState<void(void), void(void), void(FakeInvoker)>
  29. : public BindStateBase {
  30. public:
  31. typedef FakeInvoker InvokerType;
  32. };
  33. template <>
  34. struct BindState<void(void), void(void),
  35. void(FakeInvoker, FakeInvoker)>
  36. : public BindStateBase {
  37. public:
  38. typedef FakeInvoker InvokerType;
  39. };
  40. } // namespace internal
  41. namespace {
  42. typedef internal::BindState<void(void), void(void), void(FakeInvoker)>
  43. FakeBindState1;
  44. typedef internal::BindState<void(void), void(void),
  45. void(FakeInvoker, FakeInvoker)>
  46. FakeBindState2;
  47. class CallbackTest : public ::testing::Test {
  48. public:
  49. CallbackTest()
  50. : callback_a_(new FakeBindState1()),
  51. callback_b_(new FakeBindState2()) {
  52. }
  53. virtual ~CallbackTest() {
  54. }
  55. protected:
  56. Callback<void(void)> callback_a_;
  57. const Callback<void(void)> callback_b_; // Ensure APIs work with const.
  58. Callback<void(void)> null_callback_;
  59. };
  60. // Ensure we can create unbound callbacks. We need this to be able to store
  61. // them in class members that can be initialized later.
  62. TEST_F(CallbackTest, DefaultConstruction) {
  63. Callback<void(void)> c0;
  64. Callback<void(int)> c1;
  65. Callback<void(int,int)> c2;
  66. Callback<void(int,int,int)> c3;
  67. Callback<void(int,int,int,int)> c4;
  68. Callback<void(int,int,int,int,int)> c5;
  69. Callback<void(int,int,int,int,int,int)> c6;
  70. EXPECT_TRUE(c0.is_null());
  71. EXPECT_TRUE(c1.is_null());
  72. EXPECT_TRUE(c2.is_null());
  73. EXPECT_TRUE(c3.is_null());
  74. EXPECT_TRUE(c4.is_null());
  75. EXPECT_TRUE(c5.is_null());
  76. EXPECT_TRUE(c6.is_null());
  77. }
  78. TEST_F(CallbackTest, IsNull) {
  79. EXPECT_TRUE(null_callback_.is_null());
  80. EXPECT_FALSE(callback_a_.is_null());
  81. EXPECT_FALSE(callback_b_.is_null());
  82. }
  83. TEST_F(CallbackTest, Equals) {
  84. EXPECT_TRUE(callback_a_.Equals(callback_a_));
  85. EXPECT_FALSE(callback_a_.Equals(callback_b_));
  86. EXPECT_FALSE(callback_b_.Equals(callback_a_));
  87. // We should compare based on instance, not type.
  88. Callback<void(void)> callback_c(new FakeBindState1());
  89. Callback<void(void)> callback_a2 = callback_a_;
  90. EXPECT_TRUE(callback_a_.Equals(callback_a2));
  91. EXPECT_FALSE(callback_a_.Equals(callback_c));
  92. // Empty, however, is always equal to empty.
  93. Callback<void(void)> empty2;
  94. EXPECT_TRUE(null_callback_.Equals(empty2));
  95. }
  96. TEST_F(CallbackTest, Reset) {
  97. // Resetting should bring us back to empty.
  98. ASSERT_FALSE(callback_a_.is_null());
  99. ASSERT_FALSE(callback_a_.Equals(null_callback_));
  100. callback_a_.Reset();
  101. EXPECT_TRUE(callback_a_.is_null());
  102. EXPECT_TRUE(callback_a_.Equals(null_callback_));
  103. }
  104. struct TestForReentrancy {
  105. TestForReentrancy()
  106. : cb_already_run(false),
  107. cb(Bind(&TestForReentrancy::AssertCBIsNull, Unretained(this))) {
  108. }
  109. void AssertCBIsNull() {
  110. ASSERT_TRUE(cb.is_null());
  111. cb_already_run = true;
  112. }
  113. bool cb_already_run;
  114. Closure cb;
  115. };
  116. TEST_F(CallbackTest, ResetAndReturn) {
  117. TestForReentrancy tfr;
  118. ASSERT_FALSE(tfr.cb.is_null());
  119. ASSERT_FALSE(tfr.cb_already_run);
  120. ResetAndReturn(&tfr.cb).Run();
  121. ASSERT_TRUE(tfr.cb.is_null());
  122. ASSERT_TRUE(tfr.cb_already_run);
  123. }
  124. class CallbackOwner : public butil::RefCounted<CallbackOwner> {
  125. public:
  126. explicit CallbackOwner(bool* deleted) {
  127. callback_ = Bind(&CallbackOwner::Unused, this);
  128. deleted_ = deleted;
  129. }
  130. void Reset() {
  131. callback_.Reset();
  132. // We are deleted here if no-one else had a ref to us.
  133. }
  134. private:
  135. friend class butil::RefCounted<CallbackOwner>;
  136. virtual ~CallbackOwner() {
  137. *deleted_ = true;
  138. }
  139. void Unused() {
  140. FAIL() << "Should never be called";
  141. }
  142. Closure callback_;
  143. bool* deleted_;
  144. };
  145. TEST_F(CallbackTest, CallbackHasLastRefOnContainingObject) {
  146. bool deleted = false;
  147. CallbackOwner* owner = new CallbackOwner(&deleted);
  148. owner->Reset();
  149. ASSERT_TRUE(deleted);
  150. }
  151. } // namespace
  152. } // namespace butil