Index: base/ios/crb_protocol_observers_unittest.mm |
diff --git a/base/ios/crb_protocol_observers_unittest.mm b/base/ios/crb_protocol_observers_unittest.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d235c98b21f0919a2742cd40eb07e371486a5345 |
--- /dev/null |
+++ b/base/ios/crb_protocol_observers_unittest.mm |
@@ -0,0 +1,159 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "base/ios/crb_protocol_observers.h" |
+#include "base/ios/weak_nsobject.h" |
+#include "base/mac/scoped_nsautorelease_pool.h" |
+#include "base/mac/scoped_nsobject.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "testing/gtest_mac.h" |
+#include "testing/platform_test.h" |
+ |
+@protocol TestObserver |
+ |
+@required |
+- (void)requiredMethod; |
+- (void)reset; |
+ |
+@optional |
+- (void)optionalMethod; |
+ |
+@end |
+ |
+// Implements only the required methods in the TestObserver protocol. |
+@interface TestPartialObserver : NSObject<TestObserver> |
+@property(nonatomic, readonly) BOOL requiredMethodInvoked; |
+@end |
+ |
+// Implements all the methods in the TestObserver protocol. |
+@interface TestCompleteObserver : TestPartialObserver<TestObserver> |
+@property(nonatomic, readonly) BOOL optionalMethodInvoked; |
+@end |
+ |
+namespace { |
+ |
+class CRBProtocolObserversTest : public PlatformTest { |
+ public: |
+ CRBProtocolObserversTest() {} |
+ |
+ protected: |
+ void SetUp() override { |
+ PlatformTest::SetUp(); |
+ |
+ observers_.reset([[CRBProtocolObservers observersWithProtocol: |
+ @protocol(TestObserver)] retain]); |
+ |
+ partial_observer_.reset([[TestPartialObserver alloc] init]); |
+ EXPECT_FALSE([partial_observer_ requiredMethodInvoked]); |
+ |
+ complete_observer_.reset([[TestCompleteObserver alloc] init]); |
+ EXPECT_FALSE([complete_observer_ requiredMethodInvoked]); |
+ EXPECT_FALSE([complete_observer_ optionalMethodInvoked]); |
+ } |
+ |
+ base::scoped_nsobject<id> observers_; |
+ base::scoped_nsobject<TestPartialObserver> partial_observer_; |
+ base::scoped_nsobject<TestCompleteObserver> complete_observer_; |
+}; |
+ |
+// Verifies basic functionality of -[CRBProtocolObservers addObserver:] and |
+// -[CRBProtocolObservers removeObserver:]. |
+TEST_F(CRBProtocolObserversTest, AddRemoveObserver) { |
+ // Add an observer and verify that the CRBProtocolObservers instance forwards |
+ // an invocation to it. |
+ [observers_ addObserver:partial_observer_]; |
+ [observers_ requiredMethod]; |
+ EXPECT_TRUE([partial_observer_ requiredMethodInvoked]); |
+ |
+ [partial_observer_ reset]; |
+ EXPECT_FALSE([partial_observer_ requiredMethodInvoked]); |
+ |
+ // Remove the observer and verify that the CRBProtocolObservers instance no |
+ // longer forwards an invocation to it. |
+ [observers_ removeObserver:partial_observer_]; |
+ [observers_ requiredMethod]; |
+ EXPECT_FALSE([partial_observer_ requiredMethodInvoked]); |
+} |
+ |
+// Verifies that CRBProtocolObservers correctly forwards the invocation of a |
+// required method in the protocol. |
+TEST_F(CRBProtocolObserversTest, RequiredMethods) { |
+ [observers_ addObserver:partial_observer_]; |
+ [observers_ addObserver:complete_observer_]; |
+ [observers_ requiredMethod]; |
+ EXPECT_TRUE([partial_observer_ requiredMethodInvoked]); |
+ EXPECT_TRUE([complete_observer_ requiredMethodInvoked]); |
+} |
+ |
+// Verifies that CRBProtocolObservers correctly forwards the invocation of an |
+// optional method in the protocol. |
+TEST_F(CRBProtocolObserversTest, OptionalMethods) { |
+ [observers_ addObserver:partial_observer_]; |
+ [observers_ addObserver:complete_observer_]; |
+ [observers_ optionalMethod]; |
+ EXPECT_FALSE([partial_observer_ requiredMethodInvoked]); |
+ EXPECT_FALSE([complete_observer_ requiredMethodInvoked]); |
+ EXPECT_TRUE([complete_observer_ optionalMethodInvoked]); |
+} |
+ |
+// Verifies that CRBProtocolObservers only holds a weak reference to an |
+// observer. |
+TEST_F(CRBProtocolObserversTest, WeakReference) { |
+ base::WeakNSObject<TestPartialObserver> weak_observer( |
+ partial_observer_); |
+ EXPECT_TRUE(weak_observer); |
+ |
+ [observers_ addObserver:partial_observer_]; |
+ |
+ { |
+ // Need an autorelease pool here, because |
+ // -[CRBProtocolObservers forwardInvocation:] creates a temporary |
+ // autoreleased array that holds all the observers. |
+ base::mac::ScopedNSAutoreleasePool pool; |
+ [observers_ requiredMethod]; |
+ EXPECT_TRUE([partial_observer_ requiredMethodInvoked]); |
+ } |
+ |
+ partial_observer_.reset(); |
+ EXPECT_FALSE(weak_observer.get()); |
+} |
+ |
+} // namespace |
+ |
+@implementation TestPartialObserver { |
+ BOOL _requiredMethodInvoked; |
+} |
+ |
+- (BOOL)requiredMethodInvoked { |
+ return _requiredMethodInvoked; |
+} |
+ |
+- (void)requiredMethod { |
+ _requiredMethodInvoked = YES; |
+} |
+ |
+- (void)reset { |
+ _requiredMethodInvoked = NO; |
+} |
+ |
+@end |
+ |
+@implementation TestCompleteObserver { |
+ BOOL _optionalMethodInvoked; |
+} |
+ |
+- (BOOL)optionalMethodInvoked { |
+ return _optionalMethodInvoked; |
+} |
+ |
+- (void)optionalMethod { |
+ _optionalMethodInvoked = YES; |
+} |
+ |
+- (void)reset { |
+ [super reset]; |
+ _optionalMethodInvoked = NO; |
+} |
+ |
+@end |