OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 using ::testing::Mock; | 17 using ::testing::Mock; |
18 using ::testing::Return; | 18 using ::testing::Return; |
19 using ::testing::StrictMock; | 19 using ::testing::StrictMock; |
20 | 20 |
21 namespace base { | 21 namespace base { |
22 namespace { | 22 namespace { |
23 | 23 |
24 class IncompleteType; | 24 class IncompleteType; |
25 | 25 |
26 class NoRef { | 26 class NoRef { |
27 public: | 27 public: |
28 NoRef() {} | 28 NoRef() {} |
29 | 29 |
30 MOCK_METHOD0(VoidMethod0, void(void)); | 30 MOCK_METHOD0(VoidMethod0, void()); |
31 MOCK_CONST_METHOD0(VoidConstMethod0, void(void)); | 31 MOCK_CONST_METHOD0(VoidConstMethod0, void()); |
32 | 32 |
33 MOCK_METHOD0(IntMethod0, int(void)); | 33 MOCK_METHOD0(IntMethod0, int()); |
34 MOCK_CONST_METHOD0(IntConstMethod0, int(void)); | 34 MOCK_CONST_METHOD0(IntConstMethod0, int()); |
35 | 35 |
36 private: | 36 private: |
37 // Particularly important in this test to ensure no copies are made. | 37 // Particularly important in this test to ensure no copies are made. |
38 DISALLOW_COPY_AND_ASSIGN(NoRef); | 38 DISALLOW_COPY_AND_ASSIGN(NoRef); |
39 }; | 39 }; |
40 | 40 |
41 class HasRef : public NoRef { | 41 class HasRef : public NoRef { |
42 public: | 42 public: |
43 HasRef() {} | 43 HasRef() {} |
44 | 44 |
45 MOCK_CONST_METHOD0(AddRef, void(void)); | 45 MOCK_CONST_METHOD0(AddRef, void()); |
46 MOCK_CONST_METHOD0(Release, bool(void)); | 46 MOCK_CONST_METHOD0(Release, bool()); |
47 | 47 |
48 private: | 48 private: |
49 // Particularly important in this test to ensure no copies are made. | 49 // Particularly important in this test to ensure no copies are made. |
50 DISALLOW_COPY_AND_ASSIGN(HasRef); | 50 DISALLOW_COPY_AND_ASSIGN(HasRef); |
51 }; | 51 }; |
52 | 52 |
53 class HasRefPrivateDtor : public HasRef { | 53 class HasRefPrivateDtor : public HasRef { |
54 private: | 54 private: |
55 ~HasRefPrivateDtor() {} | 55 ~HasRefPrivateDtor() {} |
56 }; | 56 }; |
57 | 57 |
58 static const int kParentValue = 1; | 58 static const int kParentValue = 1; |
59 static const int kChildValue = 2; | 59 static const int kChildValue = 2; |
60 | 60 |
61 class Parent { | 61 class Parent { |
62 public: | 62 public: |
63 void AddRef(void) const {} | 63 void AddRef() const {} |
64 void Release(void) const {} | 64 void Release() const {} |
65 virtual void VirtualSet() { value = kParentValue; } | 65 virtual void VirtualSet() { value = kParentValue; } |
66 void NonVirtualSet() { value = kParentValue; } | 66 void NonVirtualSet() { value = kParentValue; } |
67 int value; | 67 int value; |
68 }; | 68 }; |
69 | 69 |
70 class Child : public Parent { | 70 class Child : public Parent { |
71 public: | 71 public: |
72 void VirtualSet() override { value = kChildValue; } | 72 void VirtualSet() override { value = kChildValue; } |
73 void NonVirtualSet() { value = kChildValue; } | 73 void NonVirtualSet() { value = kChildValue; } |
74 }; | 74 }; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 public: | 223 public: |
224 BindTest() { | 224 BindTest() { |
225 const_has_ref_ptr_ = &has_ref_; | 225 const_has_ref_ptr_ = &has_ref_; |
226 const_no_ref_ptr_ = &no_ref_; | 226 const_no_ref_ptr_ = &no_ref_; |
227 static_func_mock_ptr = &static_func_mock_; | 227 static_func_mock_ptr = &static_func_mock_; |
228 } | 228 } |
229 | 229 |
230 virtual ~BindTest() { | 230 virtual ~BindTest() { |
231 } | 231 } |
232 | 232 |
233 static void VoidFunc0(void) { | 233 static void VoidFunc0() { |
234 static_func_mock_ptr->VoidMethod0(); | 234 static_func_mock_ptr->VoidMethod0(); |
235 } | 235 } |
236 | 236 |
237 static int IntFunc0(void) { return static_func_mock_ptr->IntMethod0(); } | 237 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); } |
238 | 238 |
239 protected: | 239 protected: |
240 StrictMock<NoRef> no_ref_; | 240 StrictMock<NoRef> no_ref_; |
241 StrictMock<HasRef> has_ref_; | 241 StrictMock<HasRef> has_ref_; |
242 const HasRef* const_has_ref_ptr_; | 242 const HasRef* const_has_ref_ptr_; |
243 const NoRef* const_no_ref_ptr_; | 243 const NoRef* const_no_ref_ptr_; |
244 StrictMock<NoRef> static_func_mock_; | 244 StrictMock<NoRef> static_func_mock_; |
245 | 245 |
246 // Used by the static functions to perform expectations. | 246 // Used by the static functions to perform expectations. |
247 static StrictMock<NoRef>* static_func_mock_ptr; | 247 static StrictMock<NoRef>* static_func_mock_ptr; |
248 | 248 |
249 private: | 249 private: |
250 DISALLOW_COPY_AND_ASSIGN(BindTest); | 250 DISALLOW_COPY_AND_ASSIGN(BindTest); |
251 }; | 251 }; |
252 | 252 |
253 StrictMock<NoRef>* BindTest::static_func_mock_ptr; | 253 StrictMock<NoRef>* BindTest::static_func_mock_ptr; |
254 | 254 |
255 // Sanity check that we can instantiate a callback for each arity. | 255 // Sanity check that we can instantiate a callback for each arity. |
256 TEST_F(BindTest, ArityTest) { | 256 TEST_F(BindTest, ArityTest) { |
257 Callback<int(void)> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1); | 257 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1); |
258 EXPECT_EQ(63, c0.Run()); | 258 EXPECT_EQ(63, c0.Run()); |
259 | 259 |
260 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2); | 260 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2); |
261 EXPECT_EQ(75, c1.Run(13)); | 261 EXPECT_EQ(75, c1.Run(13)); |
262 | 262 |
263 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4); | 263 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4); |
264 EXPECT_EQ(85, c2.Run(13, 12)); | 264 EXPECT_EQ(85, c2.Run(13, 12)); |
265 | 265 |
266 Callback<int(int,int,int)> c3 = Bind(&Sum, 32, 16, 8); | 266 Callback<int(int,int,int)> c3 = Bind(&Sum, 32, 16, 8); |
267 EXPECT_EQ(92, c3.Run(13, 12, 11)); | 267 EXPECT_EQ(92, c3.Run(13, 12, 11)); |
(...skipping 21 matching lines...) Expand all Loading... |
289 | 289 |
290 Callback<int(int,int,int)> c3 = Bind(c4, 8); | 290 Callback<int(int,int,int)> c3 = Bind(c4, 8); |
291 EXPECT_EQ(92, c3.Run(13, 12, 11)); | 291 EXPECT_EQ(92, c3.Run(13, 12, 11)); |
292 | 292 |
293 Callback<int(int,int)> c2 = Bind(c3, 4); | 293 Callback<int(int,int)> c2 = Bind(c3, 4); |
294 EXPECT_EQ(85, c2.Run(13, 12)); | 294 EXPECT_EQ(85, c2.Run(13, 12)); |
295 | 295 |
296 Callback<int(int)> c1 = Bind(c2, 2); | 296 Callback<int(int)> c1 = Bind(c2, 2); |
297 EXPECT_EQ(75, c1.Run(13)); | 297 EXPECT_EQ(75, c1.Run(13)); |
298 | 298 |
299 Callback<int(void)> c0 = Bind(c1, 1); | 299 Callback<int()> c0 = Bind(c1, 1); |
300 EXPECT_EQ(63, c0.Run()); | 300 EXPECT_EQ(63, c0.Run()); |
301 } | 301 } |
302 | 302 |
303 // Test that currying the rvalue result of another Bind() works correctly. | 303 // Test that currying the rvalue result of another Bind() works correctly. |
304 // - rvalue should be usable as argument to Bind(). | 304 // - rvalue should be usable as argument to Bind(). |
305 // - multiple runs of resulting Callback remain valid. | 305 // - multiple runs of resulting Callback remain valid. |
306 TEST_F(BindTest, CurryingRvalueResultOfBind) { | 306 TEST_F(BindTest, CurryingRvalueResultOfBind) { |
307 int n = 0; | 307 int n = 0; |
308 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); | 308 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); |
309 | 309 |
(...skipping 20 matching lines...) Expand all Loading... |
330 // - Derived classes can be used with pointers to virtual base functions (and | 330 // - Derived classes can be used with pointers to virtual base functions (and |
331 // preserve virtual dispatch). | 331 // preserve virtual dispatch). |
332 TEST_F(BindTest, FunctionTypeSupport) { | 332 TEST_F(BindTest, FunctionTypeSupport) { |
333 EXPECT_CALL(static_func_mock_, VoidMethod0()); | 333 EXPECT_CALL(static_func_mock_, VoidMethod0()); |
334 EXPECT_CALL(has_ref_, AddRef()).Times(5); | 334 EXPECT_CALL(has_ref_, AddRef()).Times(5); |
335 EXPECT_CALL(has_ref_, Release()).Times(5); | 335 EXPECT_CALL(has_ref_, Release()).Times(5); |
336 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); | 336 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); |
337 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); | 337 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); |
338 | 338 |
339 Closure normal_cb = Bind(&VoidFunc0); | 339 Closure normal_cb = Bind(&VoidFunc0); |
340 Callback<NoRef*(void)> normal_non_refcounted_cb = | 340 Callback<NoRef*()> normal_non_refcounted_cb = |
341 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); | 341 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); |
342 normal_cb.Run(); | 342 normal_cb.Run(); |
343 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); | 343 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); |
344 | 344 |
345 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); | 345 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); |
346 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, | 346 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, |
347 make_scoped_refptr(&has_ref_)); | 347 make_scoped_refptr(&has_ref_)); |
348 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0, | 348 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0, |
349 &has_ref_); | 349 &has_ref_); |
350 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0, | 350 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0, |
(...skipping 21 matching lines...) Expand all Loading... |
372 // - Const method with return value. | 372 // - Const method with return value. |
373 TEST_F(BindTest, ReturnValues) { | 373 TEST_F(BindTest, ReturnValues) { |
374 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); | 374 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); |
375 EXPECT_CALL(has_ref_, AddRef()).Times(3); | 375 EXPECT_CALL(has_ref_, AddRef()).Times(3); |
376 EXPECT_CALL(has_ref_, Release()).Times(3); | 376 EXPECT_CALL(has_ref_, Release()).Times(3); |
377 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337)); | 377 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337)); |
378 EXPECT_CALL(has_ref_, IntConstMethod0()) | 378 EXPECT_CALL(has_ref_, IntConstMethod0()) |
379 .WillOnce(Return(41337)) | 379 .WillOnce(Return(41337)) |
380 .WillOnce(Return(51337)); | 380 .WillOnce(Return(51337)); |
381 | 381 |
382 Callback<int(void)> normal_cb = Bind(&IntFunc0); | 382 Callback<int()> normal_cb = Bind(&IntFunc0); |
383 Callback<int(void)> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); | 383 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); |
384 Callback<int(void)> const_method_nonconst_obj_cb = | 384 Callback<int()> const_method_nonconst_obj_cb = |
385 Bind(&HasRef::IntConstMethod0, &has_ref_); | 385 Bind(&HasRef::IntConstMethod0, &has_ref_); |
386 Callback<int(void)> const_method_const_obj_cb = | 386 Callback<int()> const_method_const_obj_cb = |
387 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); | 387 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); |
388 EXPECT_EQ(1337, normal_cb.Run()); | 388 EXPECT_EQ(1337, normal_cb.Run()); |
389 EXPECT_EQ(31337, method_cb.Run()); | 389 EXPECT_EQ(31337, method_cb.Run()); |
390 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); | 390 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); |
391 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); | 391 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); |
392 } | 392 } |
393 | 393 |
394 // IgnoreResult adapter test. | 394 // IgnoreResult adapter test. |
395 // - Function with return value. | 395 // - Function with return value. |
396 // - Method with return value. | 396 // - Method with return value. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 // - Argument binding to a literal string. | 440 // - Argument binding to a literal string. |
441 // - Argument binding with template function. | 441 // - Argument binding with template function. |
442 // - Argument binding to an object. | 442 // - Argument binding to an object. |
443 // - Argument binding to pointer to incomplete type. | 443 // - Argument binding to pointer to incomplete type. |
444 // - Argument gets type converted. | 444 // - Argument gets type converted. |
445 // - Pointer argument gets converted. | 445 // - Pointer argument gets converted. |
446 // - Const Reference forces conversion. | 446 // - Const Reference forces conversion. |
447 TEST_F(BindTest, ArgumentBinding) { | 447 TEST_F(BindTest, ArgumentBinding) { |
448 int n = 2; | 448 int n = 2; |
449 | 449 |
450 Callback<int(void)> bind_primitive_cb = Bind(&Identity, n); | 450 Callback<int()> bind_primitive_cb = Bind(&Identity, n); |
451 EXPECT_EQ(n, bind_primitive_cb.Run()); | 451 EXPECT_EQ(n, bind_primitive_cb.Run()); |
452 | 452 |
453 Callback<int*(void)> bind_primitive_pointer_cb = | 453 Callback<int*()> bind_primitive_pointer_cb = |
454 Bind(&PolymorphicIdentity<int*>, &n); | 454 Bind(&PolymorphicIdentity<int*>, &n); |
455 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); | 455 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); |
456 | 456 |
457 Callback<int(void)> bind_int_literal_cb = Bind(&Identity, 3); | 457 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); |
458 EXPECT_EQ(3, bind_int_literal_cb.Run()); | 458 EXPECT_EQ(3, bind_int_literal_cb.Run()); |
459 | 459 |
460 Callback<const char*(void)> bind_string_literal_cb = | 460 Callback<const char*()> bind_string_literal_cb = |
461 Bind(&CStringIdentity, "hi"); | 461 Bind(&CStringIdentity, "hi"); |
462 EXPECT_STREQ("hi", bind_string_literal_cb.Run()); | 462 EXPECT_STREQ("hi", bind_string_literal_cb.Run()); |
463 | 463 |
464 Callback<int(void)> bind_template_function_cb = | 464 Callback<int()> bind_template_function_cb = |
465 Bind(&PolymorphicIdentity<int>, 4); | 465 Bind(&PolymorphicIdentity<int>, 4); |
466 EXPECT_EQ(4, bind_template_function_cb.Run()); | 466 EXPECT_EQ(4, bind_template_function_cb.Run()); |
467 | 467 |
468 NoRefParent p; | 468 NoRefParent p; |
469 p.value = 5; | 469 p.value = 5; |
470 Callback<int(void)> bind_object_cb = Bind(&UnwrapNoRefParent, p); | 470 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); |
471 EXPECT_EQ(5, bind_object_cb.Run()); | 471 EXPECT_EQ(5, bind_object_cb.Run()); |
472 | 472 |
473 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); | 473 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); |
474 Callback<IncompleteType*(void)> bind_incomplete_ptr_cb = | 474 Callback<IncompleteType*()> bind_incomplete_ptr_cb = |
475 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); | 475 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); |
476 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); | 476 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); |
477 | 477 |
478 NoRefChild c; | 478 NoRefChild c; |
479 c.value = 6; | 479 c.value = 6; |
480 Callback<int(void)> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); | 480 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); |
481 EXPECT_EQ(6, bind_promotes_cb.Run()); | 481 EXPECT_EQ(6, bind_promotes_cb.Run()); |
482 | 482 |
483 c.value = 7; | 483 c.value = 7; |
484 Callback<int(void)> bind_pointer_promotes_cb = | 484 Callback<int()> bind_pointer_promotes_cb = |
485 Bind(&UnwrapNoRefParentPtr, &c); | 485 Bind(&UnwrapNoRefParentPtr, &c); |
486 EXPECT_EQ(7, bind_pointer_promotes_cb.Run()); | 486 EXPECT_EQ(7, bind_pointer_promotes_cb.Run()); |
487 | 487 |
488 c.value = 8; | 488 c.value = 8; |
489 Callback<int(void)> bind_const_reference_promotes_cb = | 489 Callback<int()> bind_const_reference_promotes_cb = |
490 Bind(&UnwrapNoRefParentConstRef, c); | 490 Bind(&UnwrapNoRefParentConstRef, c); |
491 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run()); | 491 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run()); |
492 } | 492 } |
493 | 493 |
494 // Unbound argument type support tests. | 494 // Unbound argument type support tests. |
495 // - Unbound value. | 495 // - Unbound value. |
496 // - Unbound pointer. | 496 // - Unbound pointer. |
497 // - Unbound reference. | 497 // - Unbound reference. |
498 // - Unbound const reference. | 498 // - Unbound const reference. |
499 // - Unbound unsized array. | 499 // - Unbound unsized array. |
(...skipping 26 matching lines...) Expand all Loading... |
526 } | 526 } |
527 | 527 |
528 // Functions that take reference parameters. | 528 // Functions that take reference parameters. |
529 // - Forced reference parameter type still stores a copy. | 529 // - Forced reference parameter type still stores a copy. |
530 // - Forced const reference parameter type still stores a copy. | 530 // - Forced const reference parameter type still stores a copy. |
531 TEST_F(BindTest, ReferenceArgumentBinding) { | 531 TEST_F(BindTest, ReferenceArgumentBinding) { |
532 int n = 1; | 532 int n = 1; |
533 int& ref_n = n; | 533 int& ref_n = n; |
534 const int& const_ref_n = n; | 534 const int& const_ref_n = n; |
535 | 535 |
536 Callback<int(void)> ref_copies_cb = Bind(&Identity, ref_n); | 536 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); |
537 EXPECT_EQ(n, ref_copies_cb.Run()); | 537 EXPECT_EQ(n, ref_copies_cb.Run()); |
538 n++; | 538 n++; |
539 EXPECT_EQ(n - 1, ref_copies_cb.Run()); | 539 EXPECT_EQ(n - 1, ref_copies_cb.Run()); |
540 | 540 |
541 Callback<int(void)> const_ref_copies_cb = Bind(&Identity, const_ref_n); | 541 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); |
542 EXPECT_EQ(n, const_ref_copies_cb.Run()); | 542 EXPECT_EQ(n, const_ref_copies_cb.Run()); |
543 n++; | 543 n++; |
544 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); | 544 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); |
545 } | 545 } |
546 | 546 |
547 // Check that we can pass in arrays and have them be stored as a pointer. | 547 // Check that we can pass in arrays and have them be stored as a pointer. |
548 // - Array of values stores a pointer. | 548 // - Array of values stores a pointer. |
549 // - Array of const values stores a pointer. | 549 // - Array of const values stores a pointer. |
550 TEST_F(BindTest, ArrayArgumentBinding) { | 550 TEST_F(BindTest, ArrayArgumentBinding) { |
551 int array[4] = {1, 1, 1, 1}; | 551 int array[4] = {1, 1, 1, 1}; |
552 const int (*const_array_ptr)[4] = &array; | 552 const int (*const_array_ptr)[4] = &array; |
553 | 553 |
554 Callback<int(void)> array_cb = Bind(&ArrayGet, array, 1); | 554 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); |
555 EXPECT_EQ(1, array_cb.Run()); | 555 EXPECT_EQ(1, array_cb.Run()); |
556 | 556 |
557 Callback<int(void)> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); | 557 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); |
558 EXPECT_EQ(1, const_array_cb.Run()); | 558 EXPECT_EQ(1, const_array_cb.Run()); |
559 | 559 |
560 array[1] = 3; | 560 array[1] = 3; |
561 EXPECT_EQ(3, array_cb.Run()); | 561 EXPECT_EQ(3, array_cb.Run()); |
562 EXPECT_EQ(3, const_array_cb.Run()); | 562 EXPECT_EQ(3, const_array_cb.Run()); |
563 } | 563 } |
564 | 564 |
565 // Verify SupportsAddRefAndRelease correctly introspects the class type for | 565 // Verify SupportsAddRefAndRelease correctly introspects the class type for |
566 // AddRef() and Release(). | 566 // AddRef() and Release(). |
567 // - Class with AddRef() and Release() | 567 // - Class with AddRef() and Release() |
(...skipping 17 matching lines...) Expand all Loading... |
585 } | 585 } |
586 | 586 |
587 // Unretained() wrapper support. | 587 // Unretained() wrapper support. |
588 // - Method bound to Unretained() non-const object. | 588 // - Method bound to Unretained() non-const object. |
589 // - Const method bound to Unretained() non-const object. | 589 // - Const method bound to Unretained() non-const object. |
590 // - Const method bound to Unretained() const object. | 590 // - Const method bound to Unretained() const object. |
591 TEST_F(BindTest, Unretained) { | 591 TEST_F(BindTest, Unretained) { |
592 EXPECT_CALL(no_ref_, VoidMethod0()); | 592 EXPECT_CALL(no_ref_, VoidMethod0()); |
593 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); | 593 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); |
594 | 594 |
595 Callback<void(void)> method_cb = | 595 Callback<void()> method_cb = |
596 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); | 596 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); |
597 method_cb.Run(); | 597 method_cb.Run(); |
598 | 598 |
599 Callback<void(void)> const_method_cb = | 599 Callback<void()> const_method_cb = |
600 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); | 600 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); |
601 const_method_cb.Run(); | 601 const_method_cb.Run(); |
602 | 602 |
603 Callback<void(void)> const_method_const_ptr_cb = | 603 Callback<void()> const_method_const_ptr_cb = |
604 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_)); | 604 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_)); |
605 const_method_const_ptr_cb.Run(); | 605 const_method_const_ptr_cb.Run(); |
606 } | 606 } |
607 | 607 |
608 // WeakPtr() support. | 608 // WeakPtr() support. |
609 // - Method bound to WeakPtr<> to non-const object. | 609 // - Method bound to WeakPtr<> to non-const object. |
610 // - Const method bound to WeakPtr<> to non-const object. | 610 // - Const method bound to WeakPtr<> to non-const object. |
611 // - Const method bound to WeakPtr<> to const object. | 611 // - Const method bound to WeakPtr<> to const object. |
612 // - Normal Function with WeakPtr<> as P1 can have return type and is | 612 // - Normal Function with WeakPtr<> as P1 can have return type and is |
613 // not canceled. | 613 // not canceled. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 EXPECT_EQ(2, normal_func_cb.Run(2)); | 645 EXPECT_EQ(2, normal_func_cb.Run(2)); |
646 } | 646 } |
647 | 647 |
648 // ConstRef() wrapper support. | 648 // ConstRef() wrapper support. |
649 // - Binding w/o ConstRef takes a copy. | 649 // - Binding w/o ConstRef takes a copy. |
650 // - Binding a ConstRef takes a reference. | 650 // - Binding a ConstRef takes a reference. |
651 // - Binding ConstRef to a function ConstRef does not copy on invoke. | 651 // - Binding ConstRef to a function ConstRef does not copy on invoke. |
652 TEST_F(BindTest, ConstRef) { | 652 TEST_F(BindTest, ConstRef) { |
653 int n = 1; | 653 int n = 1; |
654 | 654 |
655 Callback<int(void)> copy_cb = Bind(&Identity, n); | 655 Callback<int()> copy_cb = Bind(&Identity, n); |
656 Callback<int(void)> const_ref_cb = Bind(&Identity, ConstRef(n)); | 656 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); |
657 EXPECT_EQ(n, copy_cb.Run()); | 657 EXPECT_EQ(n, copy_cb.Run()); |
658 EXPECT_EQ(n, const_ref_cb.Run()); | 658 EXPECT_EQ(n, const_ref_cb.Run()); |
659 n++; | 659 n++; |
660 EXPECT_EQ(n - 1, copy_cb.Run()); | 660 EXPECT_EQ(n - 1, copy_cb.Run()); |
661 EXPECT_EQ(n, const_ref_cb.Run()); | 661 EXPECT_EQ(n, const_ref_cb.Run()); |
662 | 662 |
663 int copies = 0; | 663 int copies = 0; |
664 int assigns = 0; | 664 int assigns = 0; |
665 CopyCounter counter(&copies, &assigns); | 665 CopyCounter counter(&copies, &assigns); |
666 Callback<int(void)> all_const_ref_cb = | 666 Callback<int()> all_const_ref_cb = |
667 Bind(&GetCopies, ConstRef(counter)); | 667 Bind(&GetCopies, ConstRef(counter)); |
668 EXPECT_EQ(0, all_const_ref_cb.Run()); | 668 EXPECT_EQ(0, all_const_ref_cb.Run()); |
669 EXPECT_EQ(0, copies); | 669 EXPECT_EQ(0, copies); |
670 EXPECT_EQ(0, assigns); | 670 EXPECT_EQ(0, assigns); |
671 } | 671 } |
672 | 672 |
673 TEST_F(BindTest, ScopedRefptr) { | 673 TEST_F(BindTest, ScopedRefptr) { |
674 // BUG: The scoped_refptr should cause the only AddRef()/Release() pair. But | 674 // BUG: The scoped_refptr should cause the only AddRef()/Release() pair. But |
675 // due to a bug in base::Bind(), there's an extra call when invoking the | 675 // due to a bug in base::Bind(), there's an extra call when invoking the |
676 // callback. | 676 // callback. |
677 // https://code.google.com/p/chromium/issues/detail?id=251937 | 677 // https://code.google.com/p/chromium/issues/detail?id=251937 |
678 EXPECT_CALL(has_ref_, AddRef()).Times(2); | 678 EXPECT_CALL(has_ref_, AddRef()).Times(2); |
679 EXPECT_CALL(has_ref_, Release()).Times(2); | 679 EXPECT_CALL(has_ref_, Release()).Times(2); |
680 | 680 |
681 const scoped_refptr<StrictMock<HasRef> > refptr(&has_ref_); | 681 const scoped_refptr<StrictMock<HasRef> > refptr(&has_ref_); |
682 | 682 |
683 Callback<int(void)> scoped_refptr_const_ref_cb = | 683 Callback<int()> scoped_refptr_const_ref_cb = |
684 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); | 684 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); |
685 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); | 685 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); |
686 } | 686 } |
687 | 687 |
688 // Test Owned() support. | 688 // Test Owned() support. |
689 TEST_F(BindTest, Owned) { | 689 TEST_F(BindTest, Owned) { |
690 int deletes = 0; | 690 int deletes = 0; |
691 DeleteCounter* counter = new DeleteCounter(&deletes); | 691 DeleteCounter* counter = new DeleteCounter(&deletes); |
692 | 692 |
693 // If we don't capture, delete happens on Callback destruction/reset. | 693 // If we don't capture, delete happens on Callback destruction/reset. |
694 // return the same value. | 694 // return the same value. |
695 Callback<DeleteCounter*(void)> no_capture_cb = | 695 Callback<DeleteCounter*()> no_capture_cb = |
696 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); | 696 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); |
697 ASSERT_EQ(counter, no_capture_cb.Run()); | 697 ASSERT_EQ(counter, no_capture_cb.Run()); |
698 ASSERT_EQ(counter, no_capture_cb.Run()); | 698 ASSERT_EQ(counter, no_capture_cb.Run()); |
699 EXPECT_EQ(0, deletes); | 699 EXPECT_EQ(0, deletes); |
700 no_capture_cb.Reset(); // This should trigger a delete. | 700 no_capture_cb.Reset(); // This should trigger a delete. |
701 EXPECT_EQ(1, deletes); | 701 EXPECT_EQ(1, deletes); |
702 | 702 |
703 deletes = 0; | 703 deletes = 0; |
704 counter = new DeleteCounter(&deletes); | 704 counter = new DeleteCounter(&deletes); |
705 base::Closure own_object_cb = | 705 base::Closure own_object_cb = |
706 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); | 706 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); |
707 own_object_cb.Run(); | 707 own_object_cb.Run(); |
708 EXPECT_EQ(0, deletes); | 708 EXPECT_EQ(0, deletes); |
709 own_object_cb.Reset(); | 709 own_object_cb.Reset(); |
710 EXPECT_EQ(1, deletes); | 710 EXPECT_EQ(1, deletes); |
711 } | 711 } |
712 | 712 |
713 // Passed() wrapper support. | 713 // Passed() wrapper support. |
714 // - Passed() can be constructed from a pointer to scoper. | 714 // - Passed() can be constructed from a pointer to scoper. |
715 // - Passed() can be constructed from a scoper rvalue. | 715 // - Passed() can be constructed from a scoper rvalue. |
716 // - Using Passed() gives Callback Ownership. | 716 // - Using Passed() gives Callback Ownership. |
717 // - Ownership is transferred from Callback to callee on the first Run(). | 717 // - Ownership is transferred from Callback to callee on the first Run(). |
718 // - Callback supports unbound arguments. | 718 // - Callback supports unbound arguments. |
719 TEST_F(BindTest, ScopedPtr) { | 719 TEST_F(BindTest, ScopedPtr) { |
720 int deletes = 0; | 720 int deletes = 0; |
721 | 721 |
722 // Tests the Passed() function's support for pointers. | 722 // Tests the Passed() function's support for pointers. |
723 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | 723 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); |
724 Callback<scoped_ptr<DeleteCounter>(void)> unused_callback = | 724 Callback<scoped_ptr<DeleteCounter>()> unused_callback = |
725 Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr)); | 725 Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr)); |
726 EXPECT_FALSE(ptr.get()); | 726 EXPECT_FALSE(ptr.get()); |
727 EXPECT_EQ(0, deletes); | 727 EXPECT_EQ(0, deletes); |
728 | 728 |
729 // If we never invoke the Callback, it retains ownership and deletes. | 729 // If we never invoke the Callback, it retains ownership and deletes. |
730 unused_callback.Reset(); | 730 unused_callback.Reset(); |
731 EXPECT_EQ(1, deletes); | 731 EXPECT_EQ(1, deletes); |
732 | 732 |
733 // Tests the Passed() function's support for rvalues. | 733 // Tests the Passed() function's support for rvalues. |
734 deletes = 0; | 734 deletes = 0; |
735 DeleteCounter* counter = new DeleteCounter(&deletes); | 735 DeleteCounter* counter = new DeleteCounter(&deletes); |
736 Callback<scoped_ptr<DeleteCounter>(void)> callback = | 736 Callback<scoped_ptr<DeleteCounter>()> callback = |
737 Bind(&PassThru<scoped_ptr<DeleteCounter> >, | 737 Bind(&PassThru<scoped_ptr<DeleteCounter> >, |
738 Passed(scoped_ptr<DeleteCounter>(counter))); | 738 Passed(scoped_ptr<DeleteCounter>(counter))); |
739 EXPECT_FALSE(ptr.get()); | 739 EXPECT_FALSE(ptr.get()); |
740 EXPECT_EQ(0, deletes); | 740 EXPECT_EQ(0, deletes); |
741 | 741 |
742 // Check that ownership can be transferred back out. | 742 // Check that ownership can be transferred back out. |
743 scoped_ptr<DeleteCounter> result = callback.Run(); | 743 scoped_ptr<DeleteCounter> result = callback.Run(); |
744 ASSERT_EQ(counter, result.get()); | 744 ASSERT_EQ(counter, result.get()); |
745 EXPECT_EQ(0, deletes); | 745 EXPECT_EQ(0, deletes); |
746 | 746 |
(...skipping 10 matching lines...) Expand all Loading... |
757 Bind(&PassThru<scoped_ptr<DeleteCounter> >); | 757 Bind(&PassThru<scoped_ptr<DeleteCounter> >); |
758 ptr.reset(new DeleteCounter(&deletes)); | 758 ptr.reset(new DeleteCounter(&deletes)); |
759 cb_unbound.Run(std::move(ptr)); | 759 cb_unbound.Run(std::move(ptr)); |
760 } | 760 } |
761 | 761 |
762 TEST_F(BindTest, UniquePtr) { | 762 TEST_F(BindTest, UniquePtr) { |
763 int deletes = 0; | 763 int deletes = 0; |
764 | 764 |
765 // Tests the Passed() function's support for pointers. | 765 // Tests the Passed() function's support for pointers. |
766 std::unique_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | 766 std::unique_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); |
767 Callback<std::unique_ptr<DeleteCounter>(void)> unused_callback = | 767 Callback<std::unique_ptr<DeleteCounter>()> unused_callback = |
768 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, Passed(&ptr)); | 768 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, Passed(&ptr)); |
769 EXPECT_FALSE(ptr.get()); | 769 EXPECT_FALSE(ptr.get()); |
770 EXPECT_EQ(0, deletes); | 770 EXPECT_EQ(0, deletes); |
771 | 771 |
772 // If we never invoke the Callback, it retains ownership and deletes. | 772 // If we never invoke the Callback, it retains ownership and deletes. |
773 unused_callback.Reset(); | 773 unused_callback.Reset(); |
774 EXPECT_EQ(1, deletes); | 774 EXPECT_EQ(1, deletes); |
775 | 775 |
776 // Tests the Passed() function's support for rvalues. | 776 // Tests the Passed() function's support for rvalues. |
777 deletes = 0; | 777 deletes = 0; |
778 DeleteCounter* counter = new DeleteCounter(&deletes); | 778 DeleteCounter* counter = new DeleteCounter(&deletes); |
779 Callback<std::unique_ptr<DeleteCounter>(void)> callback = | 779 Callback<std::unique_ptr<DeleteCounter>()> callback = |
780 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, | 780 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, |
781 Passed(std::unique_ptr<DeleteCounter>(counter))); | 781 Passed(std::unique_ptr<DeleteCounter>(counter))); |
782 EXPECT_FALSE(ptr.get()); | 782 EXPECT_FALSE(ptr.get()); |
783 EXPECT_EQ(0, deletes); | 783 EXPECT_EQ(0, deletes); |
784 | 784 |
785 // Check that ownership can be transferred back out. | 785 // Check that ownership can be transferred back out. |
786 std::unique_ptr<DeleteCounter> result = callback.Run(); | 786 std::unique_ptr<DeleteCounter> result = callback.Run(); |
787 ASSERT_EQ(counter, result.get()); | 787 ASSERT_EQ(counter, result.get()); |
788 EXPECT_EQ(0, deletes); | 788 EXPECT_EQ(0, deletes); |
789 | 789 |
(...skipping 16 matching lines...) Expand all Loading... |
806 // - Bound arguments are only copied once. | 806 // - Bound arguments are only copied once. |
807 // - Forwarded arguments are only copied once. | 807 // - Forwarded arguments are only copied once. |
808 // - Forwarded arguments with coercions are only copied twice (once for the | 808 // - Forwarded arguments with coercions are only copied twice (once for the |
809 // coercion, and one for the final dispatch). | 809 // coercion, and one for the final dispatch). |
810 TEST_F(BindTest, ArgumentCopies) { | 810 TEST_F(BindTest, ArgumentCopies) { |
811 int copies = 0; | 811 int copies = 0; |
812 int assigns = 0; | 812 int assigns = 0; |
813 | 813 |
814 CopyCounter counter(&copies, &assigns); | 814 CopyCounter counter(&copies, &assigns); |
815 | 815 |
816 Callback<void(void)> copy_cb = | 816 Callback<void()> copy_cb = |
817 Bind(&VoidPolymorphic<CopyCounter>::Run, counter); | 817 Bind(&VoidPolymorphic<CopyCounter>::Run, counter); |
818 EXPECT_GE(1, copies); | 818 EXPECT_GE(1, copies); |
819 EXPECT_EQ(0, assigns); | 819 EXPECT_EQ(0, assigns); |
820 | 820 |
821 copies = 0; | 821 copies = 0; |
822 assigns = 0; | 822 assigns = 0; |
823 Callback<void(CopyCounter)> forward_cb = | 823 Callback<void(CopyCounter)> forward_cb = |
824 Bind(&VoidPolymorphic<CopyCounter>::Run); | 824 Bind(&VoidPolymorphic<CopyCounter>::Run); |
825 forward_cb.Run(counter); | 825 forward_cb.Run(counter); |
826 EXPECT_GE(1, copies); | 826 EXPECT_GE(1, copies); |
(...skipping 21 matching lines...) Expand all Loading... |
848 } | 848 } |
849 | 849 |
850 int __stdcall StdCallFunc(int n) { | 850 int __stdcall StdCallFunc(int n) { |
851 return n; | 851 return n; |
852 } | 852 } |
853 | 853 |
854 // Windows specific calling convention support. | 854 // Windows specific calling convention support. |
855 // - Can bind a __fastcall function. | 855 // - Can bind a __fastcall function. |
856 // - Can bind a __stdcall function. | 856 // - Can bind a __stdcall function. |
857 TEST_F(BindTest, WindowsCallingConventions) { | 857 TEST_F(BindTest, WindowsCallingConventions) { |
858 Callback<int(void)> fastcall_cb = Bind(&FastCallFunc, 1); | 858 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1); |
859 EXPECT_EQ(1, fastcall_cb.Run()); | 859 EXPECT_EQ(1, fastcall_cb.Run()); |
860 | 860 |
861 Callback<int(void)> stdcall_cb = Bind(&StdCallFunc, 2); | 861 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2); |
862 EXPECT_EQ(2, stdcall_cb.Run()); | 862 EXPECT_EQ(2, stdcall_cb.Run()); |
863 } | 863 } |
864 #endif | 864 #endif |
865 | 865 |
866 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST | 866 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST |
867 | 867 |
868 // Test null callbacks cause a DCHECK. | 868 // Test null callbacks cause a DCHECK. |
869 TEST(BindDeathTest, NullCallback) { | 869 TEST(BindDeathTest, NullCallback) { |
870 base::Callback<void(int)> null_cb; | 870 base::Callback<void(int)> null_cb; |
871 ASSERT_TRUE(null_cb.is_null()); | 871 ASSERT_TRUE(null_cb.is_null()); |
872 EXPECT_DEATH(base::Bind(null_cb, 42), ""); | 872 EXPECT_DEATH(base::Bind(null_cb, 42), ""); |
873 } | 873 } |
874 | 874 |
875 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && | 875 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && |
876 // GTEST_HAS_DEATH_TEST | 876 // GTEST_HAS_DEATH_TEST |
877 | 877 |
878 } // namespace | 878 } // namespace |
879 } // namespace base | 879 } // namespace base |
OLD | NEW |