| Flutter iOS Embedder |

FlutterChannelKeyResponderTest.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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.
4
5 #import <Foundation/Foundation.h>
6 #import <OCMock/OCMock.h>
7 #import <XCTest/XCTest.h>
8
9 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
10 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterChannelKeyResponder.h"
11 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFakeKeyEvents.h"
12
13 FLUTTER_ASSERT_ARC;
14
15 #define XCTAssertStrEqual(value, expected) \
16 XCTAssertTrue([value isEqualToString:expected], \
17 @"String \"%@\" not equal to the expected value of \"%@\"", value, expected)
18
19 using namespace flutter::testing;
20
21 API_AVAILABLE(ios(13.4))
22 @interface FlutterChannelKeyResponderTest : XCTestCase
23 @property(copy, nonatomic) FlutterUIPressProxy* testKeyDownEvent API_AVAILABLE(ios(13.4));
24 @property(copy, nonatomic) FlutterUIPressProxy* testKeyUpEvent API_AVAILABLE(ios(13.4));
25 @end
26
27 @implementation FlutterChannelKeyResponderTest
28
29 - (void)setUp {
30 // All of these tests were designed to run on iOS 13.4 or later.
31 if (@available(iOS 13.4, *)) {
32 } else {
33 XCTSkip(@"Required API not present for test.");
34 }
35 _testKeyDownEvent = keyDownEvent(UIKeyboardHIDUsageKeyboardA, 0x0, 0.0f, "a", "a");
36 _testKeyUpEvent = keyUpEvent(UIKeyboardHIDUsageKeyboardA, 0x0, 0.0f);
37 }
38
39 - (void)tearDown API_AVAILABLE(ios(13.4)) {
40 _testKeyDownEvent = nil;
41 _testKeyUpEvent = nil;
42 }
43
44 - (void)testBasicKeyEvent API_AVAILABLE(ios(13.4)) {
45 __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
46 __block BOOL next_response = TRUE;
47 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
48
49 id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
50 OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
51 .andDo((^(NSInvocation* invocation) {
52 [invocation retainArguments];
53 NSDictionary* message;
54 [invocation getArgument:&message atIndex:2];
55 [messages addObject:message];
56
57 FlutterReply callback;
58 [invocation getArgument:&callback atIndex:3];
59 NSDictionary* keyMessage = @{
60 @"handled" : @(next_response),
61 };
62 callback(keyMessage);
63 }));
64
65 // Key down
66 FlutterChannelKeyResponder* responder =
67 [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
68 [responder handlePress:_testKeyDownEvent
69 callback:^(BOOL handled) {
70 [responses addObject:@(handled)];
71 }];
72
73 XCTAssertEqual([messages count], 1u);
74 XCTAssertStrEqual([messages lastObject][@"keymap"], @"ios");
75 XCTAssertStrEqual([messages lastObject][@"type"], @"keydown");
76 XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], UIKeyboardHIDUsageKeyboardA);
77 XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);
78 XCTAssertStrEqual([messages lastObject][@"characters"], @"a");
79 XCTAssertStrEqual([messages lastObject][@"charactersIgnoringModifiers"], @"a");
80
81 XCTAssertEqual([responses count], 1u);
82 XCTAssertEqual([[responses lastObject] boolValue], TRUE);
83
84 [messages removeAllObjects];
85 [responses removeAllObjects];
86
87 // Key up
88 next_response = FALSE;
89 [responder handlePress:_testKeyUpEvent
90 callback:^(BOOL handled) {
91 [responses addObject:@(handled)];
92 }];
93
94 XCTAssertEqual([messages count], 1u);
95 XCTAssertStrEqual([messages lastObject][@"keymap"], @"ios");
96 XCTAssertStrEqual([messages lastObject][@"type"], @"keyup");
97 XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], UIKeyboardHIDUsageKeyboardA);
98 XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);
99
100 XCTAssertEqual([responses count], 1u);
101 XCTAssertEqual([[responses lastObject] boolValue], FALSE);
102
103 [messages removeAllObjects];
104 [responses removeAllObjects];
105 }
106
107 - (void)testEmptyResponseIsTakenAsHandled API_AVAILABLE(ios(13.4)) {
108 __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
109 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
110
111 id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
112 OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
113 .andDo((^(NSInvocation* invocation) {
114 [invocation retainArguments];
115 NSDictionary* message;
116 [invocation getArgument:&message atIndex:2];
117 [messages addObject:message];
118
119 FlutterReply callback;
120 [invocation getArgument:&callback atIndex:3];
121 callback(nullptr);
122 }));
123
124 FlutterChannelKeyResponder* responder =
125 [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
126 [responder handlePress:_testKeyDownEvent
127 callback:^(BOOL handled) {
128 [responses addObject:@(handled)];
129 }];
130
131 XCTAssertEqual([messages count], 1u);
132 XCTAssertStrEqual([messages lastObject][@"keymap"], @"ios");
133 XCTAssertStrEqual([messages lastObject][@"type"], @"keydown");
134 XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], UIKeyboardHIDUsageKeyboardA);
135 XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);
136 XCTAssertStrEqual([messages lastObject][@"characters"], @"a");
137 XCTAssertStrEqual([messages lastObject][@"charactersIgnoringModifiers"], @"a");
138
139 XCTAssertEqual([responses count], 1u);
140 XCTAssertEqual([[responses lastObject] boolValue], TRUE);
141 }
142
143 @end
FlutterBasicMessageChannel
Definition: FlutterChannels.h:37
flutter::testing::keyDownEvent
FlutterUIPressProxy * keyDownEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
Definition: FlutterFakeKeyEvents.mm:90
API_AVAILABLE
UITextSmartQuotesType smartQuotesType API_AVAILABLE(ios(11.0))
XCTAssertStrEqual
#define XCTAssertStrEqual(value, expected)
Definition: FlutterChannelKeyResponderTest.mm:15
flutter::testing
Definition: FlutterFakeKeyEvents.h:51
FlutterChannelKeyResponder.h
-[FlutterKeyPrimaryResponder-p handlePress:callback:]
void handlePress:callback:(nonnull FlutterUIPressProxy *press,[callback] ios(13.4) API_AVAILABLE)
FlutterMacros.h
FlutterFakeKeyEvents.h
FlutterChannelKeyResponder
Definition: FlutterChannelKeyResponder.h:20
FlutterReply
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterReply)(id _Nullable reply)
FLUTTER_ASSERT_ARC
FLUTTER_ASSERT_ARC
Definition: FlutterChannelKeyResponderTest.mm:13
FlutterUIPressProxy
Definition: FlutterUIPressProxy.h:17
FlutterChannelKeyResponderTest
Definition: FlutterChannelKeyResponderTest.mm:22
flutter::testing::keyUpEvent
FlutterUIPressProxy * keyUpEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
Definition: FlutterFakeKeyEvents.mm:100