Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1189)

Side by Side Diff: base/ios/crb_protocol_observers_unittest.mm

Issue 1157863009: CRBProtocolObservers can now be mutated while forwarding methods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/ios/crb_protocol_observers.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "base/ios/crb_protocol_observers.h" 5 #import "base/ios/crb_protocol_observers.h"
6 #include "base/ios/weak_nsobject.h" 6 #include "base/ios/weak_nsobject.h"
7 #include "base/mac/scoped_nsautorelease_pool.h" 7 #include "base/mac/scoped_nsautorelease_pool.h"
8 #include "base/mac/scoped_nsobject.h" 8 #include "base/mac/scoped_nsobject.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/gtest_mac.h" 10 #include "testing/gtest_mac.h"
11 #include "testing/platform_test.h" 11 #include "testing/platform_test.h"
12 12
13 @protocol TestObserver 13 @protocol TestObserver
14 14
15 @required 15 @required
16 - (void)requiredMethod; 16 - (void)requiredMethod;
17 - (void)reset; 17 - (void)reset;
18 18
19 @optional 19 @optional
20 - (void)optionalMethod; 20 - (void)optionalMethod;
21 - (void)mutateByAddingObserver:(id<TestObserver>)observer;
22 - (void)mutateByRemovingObserver:(id<TestObserver>)observer;
23 - (void)nestedMutateByAddingObserver:(id<TestObserver>)observer;
24 - (void)nestedMutateByRemovingObserver:(id<TestObserver>)observer;
21 25
22 @end 26 @end
23 27
24 // Implements only the required methods in the TestObserver protocol. 28 // Implements only the required methods in the TestObserver protocol.
25 @interface TestPartialObserver : NSObject<TestObserver> 29 @interface TestPartialObserver : NSObject<TestObserver>
26 @property(nonatomic, readonly) BOOL requiredMethodInvoked; 30 @property(nonatomic, readonly) BOOL requiredMethodInvoked;
27 @end 31 @end
28 32
29 // Implements all the methods in the TestObserver protocol. 33 // Implements all the methods in the TestObserver protocol.
30 @interface TestCompleteObserver : TestPartialObserver<TestObserver> 34 @interface TestCompleteObserver : TestPartialObserver<TestObserver>
31 @property(nonatomic, readonly) BOOL optionalMethodInvoked; 35 @property(nonatomic, readonly) BOOL optionalMethodInvoked;
32 @end 36 @end
33 37
38 @interface TestMutateObserver : TestCompleteObserver
39
40 - (instancetype)initWithObserver:(CRBProtocolObservers*)observer
41 NS_DESIGNATED_INITIALIZER;
42
43 @end
44
34 namespace { 45 namespace {
35 46
36 class CRBProtocolObserversTest : public PlatformTest { 47 class CRBProtocolObserversTest : public PlatformTest {
37 public: 48 public:
38 CRBProtocolObserversTest() {} 49 CRBProtocolObserversTest() {}
39 50
40 protected: 51 protected:
41 void SetUp() override { 52 void SetUp() override {
42 PlatformTest::SetUp(); 53 PlatformTest::SetUp();
43 54
44 observers_.reset([[CRBProtocolObservers observersWithProtocol: 55 observers_.reset([[CRBProtocolObservers observersWithProtocol:
45 @protocol(TestObserver)] retain]); 56 @protocol(TestObserver)] retain]);
46 57
47 partial_observer_.reset([[TestPartialObserver alloc] init]); 58 partial_observer_.reset([[TestPartialObserver alloc] init]);
48 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]); 59 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
49 60
50 complete_observer_.reset([[TestCompleteObserver alloc] init]); 61 complete_observer_.reset([[TestCompleteObserver alloc] init]);
51 EXPECT_FALSE([complete_observer_ requiredMethodInvoked]); 62 EXPECT_FALSE([complete_observer_ requiredMethodInvoked]);
52 EXPECT_FALSE([complete_observer_ optionalMethodInvoked]); 63 EXPECT_FALSE([complete_observer_ optionalMethodInvoked]);
64
65 mutate_observer_.reset(
66 [[TestMutateObserver alloc] initWithObserver:observers_.get()]);
67 EXPECT_FALSE([mutate_observer_ requiredMethodInvoked]);
53 } 68 }
54 69
55 base::scoped_nsobject<id> observers_; 70 base::scoped_nsobject<id> observers_;
56 base::scoped_nsobject<TestPartialObserver> partial_observer_; 71 base::scoped_nsobject<TestPartialObserver> partial_observer_;
57 base::scoped_nsobject<TestCompleteObserver> complete_observer_; 72 base::scoped_nsobject<TestCompleteObserver> complete_observer_;
73 base::scoped_nsobject<TestMutateObserver> mutate_observer_;
58 }; 74 };
59 75
60 // Verifies basic functionality of -[CRBProtocolObservers addObserver:] and 76 // Verifies basic functionality of -[CRBProtocolObservers addObserver:] and
61 // -[CRBProtocolObservers removeObserver:]. 77 // -[CRBProtocolObservers removeObserver:].
62 TEST_F(CRBProtocolObserversTest, AddRemoveObserver) { 78 TEST_F(CRBProtocolObserversTest, AddRemoveObserver) {
63 // Add an observer and verify that the CRBProtocolObservers instance forwards 79 // Add an observer and verify that the CRBProtocolObservers instance forwards
64 // an invocation to it. 80 // an invocation to it.
65 [observers_ addObserver:partial_observer_]; 81 [observers_ addObserver:partial_observer_];
66 [observers_ requiredMethod]; 82 [observers_ requiredMethod];
67 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]); 83 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 // autoreleased array that holds all the observers. 128 // autoreleased array that holds all the observers.
113 base::mac::ScopedNSAutoreleasePool pool; 129 base::mac::ScopedNSAutoreleasePool pool;
114 [observers_ requiredMethod]; 130 [observers_ requiredMethod];
115 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]); 131 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
116 } 132 }
117 133
118 partial_observer_.reset(); 134 partial_observer_.reset();
119 EXPECT_FALSE(weak_observer.get()); 135 EXPECT_FALSE(weak_observer.get());
120 } 136 }
121 137
138 // Verifies that an observer can safely remove itself as observer while being
139 // notified.
140 TEST_F(CRBProtocolObserversTest, SelfMutateObservers) {
141 [observers_ addObserver:mutate_observer_];
142 EXPECT_FALSE([observers_ empty]);
143
144 [observers_ requiredMethod];
145 EXPECT_TRUE([mutate_observer_ requiredMethodInvoked]);
146
147 [mutate_observer_ reset];
148
149 [observers_ nestedMutateByRemovingObserver:mutate_observer_];
150 EXPECT_FALSE([mutate_observer_ requiredMethodInvoked]);
151
152 [observers_ addObserver:partial_observer_];
153
154 [observers_ requiredMethod];
155 EXPECT_FALSE([mutate_observer_ requiredMethodInvoked]);
156 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
157
158 [observers_ removeObserver:partial_observer_];
159 EXPECT_TRUE([observers_ empty]);
160 }
161
162 // Verifies that - [CRBProtocolObservers addObserver:] and
163 // - [CRBProtocolObservers removeObserver:] can be called while methods are
164 // being forwarded.
165 TEST_F(CRBProtocolObserversTest, MutateObservers) {
166 // Indirectly add an observer while forwarding an observer method.
167 [observers_ addObserver:mutate_observer_];
168
169 [observers_ mutateByAddingObserver:partial_observer_];
170 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
171
172 // Check that methods are correctly forwared to the indirectly added observer.
173 [mutate_observer_ reset];
174 [observers_ requiredMethod];
175 EXPECT_TRUE([mutate_observer_ requiredMethodInvoked]);
176 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
177
178 [mutate_observer_ reset];
179 [partial_observer_ reset];
180
181 // Indirectly remove an observer while forwarding an observer method.
182 [observers_ mutateByRemovingObserver:partial_observer_];
183
184 // Check that method is not forwared to the indirectly removed observer.
185 [observers_ requiredMethod];
186 EXPECT_TRUE([mutate_observer_ requiredMethodInvoked]);
187 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
188 }
189
190 // Verifies that - [CRBProtocolObservers addObserver:] and
191 // - [CRBProtocolObservers removeObserver:] can be called while methods are
192 // being forwarded with a nested invocation depth > 0.
193 TEST_F(CRBProtocolObserversTest, NestedMutateObservers) {
194 // Indirectly add an observer while forwarding an observer method.
195 [observers_ addObserver:mutate_observer_];
196
197 [observers_ nestedMutateByAddingObserver:partial_observer_];
198 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
199
200 // Check that methods are correctly forwared to the indirectly added observer.
201 [mutate_observer_ reset];
202 [observers_ requiredMethod];
203 EXPECT_TRUE([mutate_observer_ requiredMethodInvoked]);
204 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
205
206 [mutate_observer_ reset];
207 [partial_observer_ reset];
208
209 // Indirectly remove an observer while forwarding an observer method.
210 [observers_ nestedMutateByRemovingObserver:partial_observer_];
211
212 // Check that method is not forwared to the indirectly removed observer.
213 [observers_ requiredMethod];
214 EXPECT_TRUE([mutate_observer_ requiredMethodInvoked]);
215 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
216 }
217
122 } // namespace 218 } // namespace
123 219
124 @implementation TestPartialObserver { 220 @implementation TestPartialObserver {
125 BOOL _requiredMethodInvoked; 221 BOOL _requiredMethodInvoked;
126 } 222 }
127 223
128 - (BOOL)requiredMethodInvoked { 224 - (BOOL)requiredMethodInvoked {
129 return _requiredMethodInvoked; 225 return _requiredMethodInvoked;
130 } 226 }
131 227
(...skipping 18 matching lines...) Expand all
150 - (void)optionalMethod { 246 - (void)optionalMethod {
151 _optionalMethodInvoked = YES; 247 _optionalMethodInvoked = YES;
152 } 248 }
153 249
154 - (void)reset { 250 - (void)reset {
155 [super reset]; 251 [super reset];
156 _optionalMethodInvoked = NO; 252 _optionalMethodInvoked = NO;
157 } 253 }
158 254
159 @end 255 @end
256
257 @implementation TestMutateObserver {
258 __weak id _observers;
259 }
260
261 - (instancetype)initWithObserver:(CRBProtocolObservers*)observers {
262 self = [super init];
263 if (self) {
264 _observers = observers;
265 }
266 return self;
267 }
268
269 - (void)mutateByAddingObserver:(id<TestObserver>)observer {
270 [_observers addObserver:observer];
271 }
272
273 - (void)mutateByRemovingObserver:(id<TestObserver>)observer {
274 [_observers removeObserver:observer];
275 }
276
277 - (void)nestedMutateByAddingObserver:(id<TestObserver>)observer {
278 [_observers mutateByAddingObserver:observer];
279 }
280
281 - (void)nestedMutateByRemovingObserver:(id<TestObserver>)observer {
282 [_observers mutateByRemovingObserver:observer];
283 }
284
285 @end
OLDNEW
« no previous file with comments | « base/ios/crb_protocol_observers.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698