weak_nsobject_unittest.mm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2013 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 "base/ios/weak_nsobject.h"
  5. #include "base/bind.h"
  6. #include "base/mac/scoped_nsobject.h"
  7. #include "base/run_loop.h"
  8. #include "base/task/single_thread_task_runner.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/threading/thread.h"
  11. #include "base/threading/thread_task_runner_handle.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace base {
  14. namespace {
  15. TEST(WeakNSObjectTest, WeakNSObject) {
  16. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  17. WeakNSObject<NSObject> w1(p1);
  18. EXPECT_TRUE(w1);
  19. p1.reset();
  20. EXPECT_FALSE(w1);
  21. }
  22. TEST(WeakNSObjectTest, MultipleWeakNSObject) {
  23. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  24. WeakNSObject<NSObject> w1(p1);
  25. WeakNSObject<NSObject> w2(w1);
  26. EXPECT_TRUE(w1);
  27. EXPECT_TRUE(w2);
  28. EXPECT_TRUE(w1.get() == w2.get());
  29. p1.reset();
  30. EXPECT_FALSE(w1);
  31. EXPECT_FALSE(w2);
  32. }
  33. TEST(WeakNSObjectTest, WeakNSObjectDies) {
  34. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  35. {
  36. WeakNSObject<NSObject> w1(p1);
  37. EXPECT_TRUE(w1);
  38. }
  39. }
  40. TEST(WeakNSObjectTest, WeakNSObjectReset) {
  41. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  42. WeakNSObject<NSObject> w1(p1);
  43. EXPECT_TRUE(w1);
  44. w1.reset();
  45. EXPECT_FALSE(w1);
  46. EXPECT_TRUE(p1);
  47. EXPECT_TRUE([p1 description]);
  48. }
  49. TEST(WeakNSObjectTest, WeakNSObjectResetWithObject) {
  50. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  51. scoped_nsobject<NSObject> p2([[NSObject alloc] init]);
  52. WeakNSObject<NSObject> w1(p1);
  53. EXPECT_TRUE(w1);
  54. w1.reset(p2);
  55. EXPECT_TRUE(w1);
  56. EXPECT_TRUE([p1 description]);
  57. EXPECT_TRUE([p2 description]);
  58. }
  59. TEST(WeakNSObjectTest, WeakNSObjectEmpty) {
  60. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  61. WeakNSObject<NSObject> w1;
  62. EXPECT_FALSE(w1);
  63. w1.reset(p1);
  64. EXPECT_TRUE(w1);
  65. p1.reset();
  66. EXPECT_FALSE(w1);
  67. }
  68. TEST(WeakNSObjectTest, WeakNSObjectCopy) {
  69. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  70. WeakNSObject<NSObject> w1(p1);
  71. WeakNSObject<NSObject> w2(w1);
  72. EXPECT_TRUE(w1);
  73. EXPECT_TRUE(w2);
  74. p1.reset();
  75. EXPECT_FALSE(w1);
  76. EXPECT_FALSE(w2);
  77. }
  78. TEST(WeakNSObjectTest, WeakNSObjectAssignment) {
  79. scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
  80. WeakNSObject<NSObject> w1(p1);
  81. WeakNSObject<NSObject> w2;
  82. EXPECT_FALSE(w2);
  83. w2 = w1;
  84. EXPECT_TRUE(w1);
  85. EXPECT_TRUE(w2);
  86. p1.reset();
  87. EXPECT_FALSE(w1);
  88. EXPECT_FALSE(w2);
  89. }
  90. // Touches |weak_data| by increasing its length by 1. Used to check that the
  91. // weak object can be dereferenced.
  92. void TouchWeakData(const WeakNSObject<NSMutableData>& weak_data) {
  93. if (!weak_data)
  94. return;
  95. [weak_data increaseLengthBy:1];
  96. }
  97. // Makes a copy of |weak_object| on the current thread and posts a task to touch
  98. // the weak object on its original thread.
  99. void CopyWeakNSObjectAndPost(const WeakNSObject<NSMutableData>& weak_object,
  100. scoped_refptr<SingleThreadTaskRunner> runner) {
  101. // Copy using constructor.
  102. WeakNSObject<NSMutableData> weak_copy1(weak_object);
  103. runner->PostTask(FROM_HERE, BindOnce(&TouchWeakData, weak_copy1));
  104. // Copy using assignment operator.
  105. WeakNSObject<NSMutableData> weak_copy2 = weak_object;
  106. runner->PostTask(FROM_HERE, BindOnce(&TouchWeakData, weak_copy2));
  107. }
  108. // Tests that the weak object can be copied on a different thread.
  109. TEST(WeakNSObjectTest, WeakNSObjectCopyOnOtherThread) {
  110. test::TaskEnvironment task_environment;
  111. Thread other_thread("WeakNSObjectCopyOnOtherThread");
  112. other_thread.Start();
  113. scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]);
  114. WeakNSObject<NSMutableData> weak(data);
  115. scoped_refptr<SingleThreadTaskRunner> runner = ThreadTaskRunnerHandle::Get();
  116. other_thread.task_runner()->PostTask(
  117. FROM_HERE, BindOnce(&CopyWeakNSObjectAndPost, weak, runner));
  118. other_thread.Stop();
  119. RunLoop().RunUntilIdle();
  120. // Check that TouchWeakData was called and the object touched twice.
  121. EXPECT_EQ(2u, [data length]);
  122. }
  123. } // namespace
  124. } // namespace base