Flutter Engine
The Flutter Engine
Instance Methods | List of all members
FlutterKeyboardManagerTest Class Reference
Inheritance diagram for FlutterKeyboardManagerTest:

Instance Methods

(id< FlutterKeyPrimaryResponder >) - mockPrimaryResponder: [implementation]
 
(id< FlutterKeySecondaryResponder >) - mockSecondaryResponder: [implementation]
 
(void) - testNextResponderShouldThrowOnPressesEnded [implementation]
 
(void) - testSinglePrimaryResponder [implementation]
 
(void) - testDoublePrimaryResponder [implementation]
 
(void) - testSingleSecondaryResponder [implementation]
 
(void) - testEventsProcessedSequentially [implementation]
 

Detailed Description

Definition at line 36 of file FlutterKeyboardManagerTest.mm.

Method Documentation

◆ mockPrimaryResponder:

- (id< FlutterKeyPrimaryResponder >) mockPrimaryResponder: (KeyCallbackSetter)  callbackSetter
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

41 :(KeyCallbackSetter)callbackSetter {
42 id<FlutterKeyPrimaryResponder> mock =
43 OCMStrictProtocolMock(@protocol(FlutterKeyPrimaryResponder));
44 OCMStub([mock handlePress:[OCMArg any] callback:[OCMArg any]])
45 .andDo((^(NSInvocation* invocation) {
46 __unsafe_unretained FlutterUIPressProxy* pressUnsafe;
47 __unsafe_unretained FlutterAsyncKeyCallback callbackUnsafe;
48
49 [invocation getArgument:&pressUnsafe atIndex:2];
50 [invocation getArgument:&callbackUnsafe atIndex:3];
51
52 // Retain the unretained parameters so they can
53 // be run in the perform block when this invocation goes out of scope.
54 FlutterUIPressProxy* press = pressUnsafe;
55 FlutterAsyncKeyCallback callback = callbackUnsafe;
56 CFRunLoopPerformBlock(CFRunLoopGetCurrent(),
58 callbackSetter(press, callback);
59 });
60 }));
61 return mock;
62}
static CFStringRef kMessageLoopCFRunLoopMode
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
void(^ FlutterAsyncKeyCallback)(BOOL handled)
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530

◆ mockSecondaryResponder:

- (id< FlutterKeySecondaryResponder >) mockSecondaryResponder: (BoolGetter)  resultGetter
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

64 :(BoolGetter)resultGetter {
65 id<FlutterKeySecondaryResponder> mock =
66 OCMStrictProtocolMock(@protocol(FlutterKeySecondaryResponder));
67 OCMStub([mock handlePress:[OCMArg any]]).andDo((^(NSInvocation* invocation) {
68 BOOL result = resultGetter();
69 [invocation setReturnValue:&result];
70 }));
71 return mock;
72}
GAsyncResult * result
int BOOL
Definition: windows_types.h:37

◆ testDoublePrimaryResponder

- (void) testDoublePrimaryResponder
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

126 {
128
129 __block BOOL callback1Response = FALSE;
130 __block int callback1Count = 0;
131 [manager addPrimaryResponder:[self mockPrimaryResponder:^(FlutterUIPressProxy* press,
132 FlutterAsyncKeyCallback callback) {
133 callback1Count++;
134 callback(callback1Response);
135 }]];
136
137 __block BOOL callback2Response = FALSE;
138 __block int callback2Count = 0;
139 [manager addPrimaryResponder:[self mockPrimaryResponder:^(FlutterUIPressProxy* press,
140 FlutterAsyncKeyCallback callback) {
141 callback2Count++;
142 callback(callback2Response);
143 }]];
144
145 // Case: Both responders report TRUE.
146 __block bool somethingWasHandled = true;
147 constexpr UIKeyboardHIDUsage keyId = (UIKeyboardHIDUsage)0x50;
148 callback1Response = TRUE;
149 callback2Response = TRUE;
150 [manager handlePress:keyUpEvent(keyId)
151 nextAction:^() {
152 somethingWasHandled = false;
153 }];
154 XCTAssertEqual(callback1Count, 1);
155 XCTAssertEqual(callback2Count, 1);
156 XCTAssertTrue(somethingWasHandled);
157
158 somethingWasHandled = true;
159 callback1Count = 0;
160 callback2Count = 0;
161
162 // Case: One responder reports TRUE.
163 callback1Response = TRUE;
164 callback2Response = FALSE;
165 [manager handlePress:keyUpEvent(keyId)
166 nextAction:^() {
167 somethingWasHandled = false;
168 }];
169 XCTAssertEqual(callback1Count, 1);
170 XCTAssertEqual(callback2Count, 1);
171 XCTAssertTrue(somethingWasHandled);
172
173 somethingWasHandled = true;
174 callback1Count = 0;
175 callback2Count = 0;
176
177 // Case: Both responders report FALSE.
178 callback1Response = FALSE;
179 callback2Response = FALSE;
180 [manager handlePress:keyDownEvent(keyId)
181 nextAction:^() {
182 somethingWasHandled = false;
183 }];
184 XCTAssertEqual(callback1Count, 1);
185 XCTAssertEqual(callback2Count, 1);
186 XCTAssertFalse(somethingWasHandled);
187}
void addPrimaryResponder:(nonnull id< FlutterKeyPrimaryResponder > responder)
void handlePress:nextAction:(nonnull FlutterUIPressProxy *press,[nextAction] ios(13.4) API_AVAILABLE)
return FALSE
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
Definition: switches.h:218

◆ testEventsProcessedSequentially

- (void) testEventsProcessedSequentially
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

244 {
245 constexpr UIKeyboardHIDUsage keyId1 = (UIKeyboardHIDUsage)0x50;
246 constexpr UIKeyboardHIDUsage keyId2 = (UIKeyboardHIDUsage)0x51;
247 FlutterUIPressProxy* event1 = keyDownEvent(keyId1);
248 FlutterUIPressProxy* event2 = keyDownEvent(keyId2);
249 __block FlutterAsyncKeyCallback key1Callback;
250 __block FlutterAsyncKeyCallback key2Callback;
251 __block bool key1Handled = true;
252 __block bool key2Handled = true;
253
255 [manager addPrimaryResponder:[self mockPrimaryResponder:^(FlutterUIPressProxy* press,
256 FlutterAsyncKeyCallback callback) {
257 if (press == event1) {
258 key1Callback = callback;
259 } else if (press == event2) {
260 key2Callback = callback;
261 }
262 }]];
263
264 // Add both presses into the main CFRunLoop queue
265 CFRunLoopTimerRef timer0 = CFRunLoopTimerCreateWithHandler(
266 kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, ^(CFRunLoopTimerRef timerRef) {
267 [manager handlePress:event1
268 nextAction:^() {
269 key1Handled = false;
270 }];
271 });
272 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer0, kCFRunLoopCommonModes);
273 CFRunLoopTimerRef timer1 = CFRunLoopTimerCreateWithHandler(
274 kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + 1, 0, 0, 0, ^(CFRunLoopTimerRef timerRef) {
275 // key1 should be completely finished by now
276 XCTAssertFalse(key1Handled);
277 [manager handlePress:event2
278 nextAction:^() {
279 key2Handled = false;
280 }];
281 // End the nested CFRunLoop
282 CFRunLoopStop(CFRunLoopGetCurrent());
283 });
284 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer1, kCFRunLoopCommonModes);
285
286 // Add the callbacks to the CFRunLoop with mode kMessageLoopCFRunLoopMode
287 // This allows them to interrupt the loop started within handlePress
288 CFRunLoopTimerRef timer2 = CFRunLoopTimerCreateWithHandler(
289 kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + 2, 0, 0, 0, ^(CFRunLoopTimerRef timerRef) {
290 // No processing should be done on key2 yet
291 XCTAssertTrue(key1Callback != nil);
292 XCTAssertTrue(key2Callback == nil);
293 key1Callback(false);
294 });
295 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer2,
297 CFRunLoopTimerRef timer3 = CFRunLoopTimerCreateWithHandler(
298 kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + 3, 0, 0, 0, ^(CFRunLoopTimerRef timerRef) {
299 // Both keys should be processed by now
300 XCTAssertTrue(key1Callback != nil);
301 XCTAssertTrue(key2Callback != nil);
302 key2Callback(false);
303 });
304 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer3,
306
307 // Start a nested CFRunLoop so we can wait for both presses to complete before exiting the test
308 CFRunLoopRun();
309 XCTAssertFalse(key2Handled);
310 XCTAssertFalse(key1Handled);
311}
FlutterUIPressProxy * keyDownEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))

◆ testNextResponderShouldThrowOnPressesEnded

- (void) testNextResponderShouldThrowOnPressesEnded
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

74 {
75 // The nextResponder is a strict mock and hasn't stubbed pressesEnded.
76 // An error will be thrown on pressesEnded.
77 UIResponder* nextResponder = OCMStrictClassMock([UIResponder class]);
78 OCMStub([nextResponder pressesBegan:OCMOCK_ANY withEvent:OCMOCK_ANY]);
79
80 id mockEngine = OCMClassMock([FlutterEngine class]);
81 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
82 nibName:nil
83 bundle:nil];
84 FlutterViewController* owner = OCMPartialMock(viewController);
85 OCMStub([owner nextResponder]).andReturn(nextResponder);
86
87 XCTAssertThrowsSpecificNamed([owner.nextResponder pressesEnded:[[NSSet alloc] init]
88 withEvent:[[UIPressesEvent alloc] init]],
89 NSException, NSInternalInconsistencyException);
90
91 [mockEngine stopMocking];
92}
FlutterViewController * viewController
static bool init()

◆ testSinglePrimaryResponder

- (void) testSinglePrimaryResponder
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

94 {
96 __block BOOL primaryResponse = FALSE;
97 __block int callbackCount = 0;
98 [manager addPrimaryResponder:[self mockPrimaryResponder:^(FlutterUIPressProxy* press,
99 FlutterAsyncKeyCallback callback) {
100 callbackCount++;
101 callback(primaryResponse);
102 }]];
103 constexpr UIKeyboardHIDUsage keyId = (UIKeyboardHIDUsage)0x50;
104 // Case: The responder reports TRUE
105 __block bool completeHandled = true;
106 primaryResponse = TRUE;
107 [manager handlePress:keyDownEvent(keyId)
108 nextAction:^() {
109 completeHandled = false;
110 }];
111 XCTAssertEqual(callbackCount, 1);
112 XCTAssertTrue(completeHandled);
113 completeHandled = true;
114 callbackCount = 0;
115
116 // Case: The responder reports FALSE
117 primaryResponse = FALSE;
118 [manager handlePress:keyUpEvent(keyId)
119 nextAction:^() {
120 completeHandled = false;
121 }];
122 XCTAssertEqual(callbackCount, 1);
123 XCTAssertFalse(completeHandled);
124}

◆ testSingleSecondaryResponder

- (void) testSingleSecondaryResponder
implementation

Definition at line 30 of file FlutterKeyboardManagerTest.mm.

189 {
191
192 __block BOOL primaryResponse = FALSE;
193 __block int callbackCount = 0;
194 [manager addPrimaryResponder:[self mockPrimaryResponder:^(FlutterUIPressProxy* press,
195 FlutterAsyncKeyCallback callback) {
196 callbackCount++;
197 callback(primaryResponse);
198 }]];
199
200 __block BOOL secondaryResponse;
201 [manager addSecondaryResponder:[self mockSecondaryResponder:^() {
202 return secondaryResponse;
203 }]];
204
205 // Case: Primary responder responds TRUE. The event shouldn't be handled by
206 // the secondary responder.
207 constexpr UIKeyboardHIDUsage keyId = (UIKeyboardHIDUsage)0x50;
208 secondaryResponse = FALSE;
209 primaryResponse = TRUE;
210 __block bool completeHandled = true;
211 [manager handlePress:keyUpEvent(keyId)
212 nextAction:^() {
213 completeHandled = false;
214 }];
215 XCTAssertEqual(callbackCount, 1);
216 XCTAssertTrue(completeHandled);
217 completeHandled = true;
218 callbackCount = 0;
219
220 // Case: Primary responder responds FALSE. The secondary responder returns
221 // TRUE.
222 secondaryResponse = TRUE;
223 primaryResponse = FALSE;
224 [manager handlePress:keyUpEvent(keyId)
225 nextAction:^() {
226 completeHandled = false;
227 }];
228 XCTAssertEqual(callbackCount, 1);
229 XCTAssertTrue(completeHandled);
230 completeHandled = true;
231 callbackCount = 0;
232
233 // Case: Primary responder responds FALSE. The secondary responder returns FALSE.
234 secondaryResponse = FALSE;
235 primaryResponse = FALSE;
236 [manager handlePress:keyDownEvent(keyId)
237 nextAction:^() {
238 completeHandled = false;
239 }];
240 XCTAssertEqual(callbackCount, 1);
241 XCTAssertFalse(completeHandled);
242}
void addSecondaryResponder:(nonnull id< FlutterKeySecondaryResponder > responder)

The documentation for this class was generated from the following file: