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
3 // found in the LICENSE file.
5 #import "base/ios/crb_protocol_observers.h"
6 #include "base/ios/weak_nsobject.h"
7 #include "base/mac/scoped_nsautorelease_pool.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/gtest_mac.h"
11 #include "testing/platform_test.h"
13 @protocol TestObserver
16 - (void)requiredMethod;
20 - (void)optionalMethod;
24 // Implements only the required methods in the TestObserver protocol.
25 @interface TestPartialObserver : NSObject<TestObserver>
26 @property(nonatomic, readonly) BOOL requiredMethodInvoked;
29 // Implements all the methods in the TestObserver protocol.
30 @interface TestCompleteObserver : TestPartialObserver<TestObserver>
31 @property(nonatomic, readonly) BOOL optionalMethodInvoked;
36 class CRBProtocolObserversTest : public PlatformTest {
38 CRBProtocolObserversTest() {}
41 void SetUp() override {
42 PlatformTest::SetUp();
44 observers_.reset([[CRBProtocolObservers observersWithProtocol:
45 @protocol(TestObserver)] retain]);
47 partial_observer_.reset([[TestPartialObserver alloc] init]);
48 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
50 complete_observer_.reset([[TestCompleteObserver alloc] init]);
51 EXPECT_FALSE([complete_observer_ requiredMethodInvoked]);
52 EXPECT_FALSE([complete_observer_ optionalMethodInvoked]);
55 base::scoped_nsobject<id> observers_;
56 base::scoped_nsobject<TestPartialObserver> partial_observer_;
57 base::scoped_nsobject<TestCompleteObserver> complete_observer_;
60 // Verifies basic functionality of -[CRBProtocolObservers addObserver:] and
61 // -[CRBProtocolObservers removeObserver:].
62 TEST_F(CRBProtocolObserversTest, AddRemoveObserver) {
63 // Add an observer and verify that the CRBProtocolObservers instance forwards
64 // an invocation to it.
65 [observers_ addObserver:partial_observer_];
66 [observers_ requiredMethod];
67 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
69 [partial_observer_ reset];
70 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
72 // Remove the observer and verify that the CRBProtocolObservers instance no
73 // longer forwards an invocation to it.
74 [observers_ removeObserver:partial_observer_];
75 [observers_ requiredMethod];
76 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
79 // Verifies that CRBProtocolObservers correctly forwards the invocation of a
80 // required method in the protocol.
81 TEST_F(CRBProtocolObserversTest, RequiredMethods) {
82 [observers_ addObserver:partial_observer_];
83 [observers_ addObserver:complete_observer_];
84 [observers_ requiredMethod];
85 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
86 EXPECT_TRUE([complete_observer_ requiredMethodInvoked]);
89 // Verifies that CRBProtocolObservers correctly forwards the invocation of an
90 // optional method in the protocol.
91 TEST_F(CRBProtocolObserversTest, OptionalMethods) {
92 [observers_ addObserver:partial_observer_];
93 [observers_ addObserver:complete_observer_];
94 [observers_ optionalMethod];
95 EXPECT_FALSE([partial_observer_ requiredMethodInvoked]);
96 EXPECT_FALSE([complete_observer_ requiredMethodInvoked]);
97 EXPECT_TRUE([complete_observer_ optionalMethodInvoked]);
100 // Verifies that CRBProtocolObservers only holds a weak reference to an
102 TEST_F(CRBProtocolObserversTest, WeakReference) {
103 base::WeakNSObject<TestPartialObserver> weak_observer(
105 EXPECT_TRUE(weak_observer);
107 [observers_ addObserver:partial_observer_];
110 // Need an autorelease pool here, because
111 // -[CRBProtocolObservers forwardInvocation:] creates a temporary
112 // autoreleased array that holds all the observers.
113 base::mac::ScopedNSAutoreleasePool pool;
114 [observers_ requiredMethod];
115 EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
118 partial_observer_.reset();
119 EXPECT_FALSE(weak_observer.get());
124 @implementation TestPartialObserver {
125 BOOL _requiredMethodInvoked;
128 - (BOOL)requiredMethodInvoked {
129 return _requiredMethodInvoked;
132 - (void)requiredMethod {
133 _requiredMethodInvoked = YES;
137 _requiredMethodInvoked = NO;
142 @implementation TestCompleteObserver {
143 BOOL _optionalMethodInvoked;
146 - (BOOL)optionalMethodInvoked {
147 return _optionalMethodInvoked;
150 - (void)optionalMethod {
151 _optionalMethodInvoked = YES;
156 _optionalMethodInvoked = NO;