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