Flutter Engine
The Flutter Engine
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
14
15#define XCTAssertStrEqual(value, expected) \
16 XCTAssertTrue([value isEqualToString:expected], \
17 @"String \"%@\" not equal to the expected value of \"%@\"", value, expected)
18
19using namespace flutter::testing;
20
21API_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
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
58 [invocation getArgument:&callback atIndex:3];
59 NSDictionary* keyMessage = @{
60 @"handled" : @(next_response),
61 };
62 callback(keyMessage);
63 }));
64
65 // Key down
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
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
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterReply)(id _Nullable reply)
int count
Definition: FontMgrTest.cpp:50
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlutterUIPressProxy *testKeyUpEvent API_AVAILABLE(ios(13.4))
FlutterUIPressProxy *testKeyDownEvent API_AVAILABLE(ios(13.4))
void handlePress:callback:(nonnull FlutterUIPressProxy *press, [callback] ios(13.4) API_AVAILABLE)
#define XCTAssertStrEqual(value, expected)
Win32Message message
return FALSE
SK_API sk_sp< SkSurface > ios(9.0)
FlutterUIPressProxy * keyUpEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
FlutterUIPressProxy * keyDownEvent(UIKeyboardHIDUsage keyCode, UIKeyModifierFlags modifierFlags=0x0, NSTimeInterval timestamp=0.0f, const char *characters="", const char *charactersIgnoringModifiers="") API_AVAILABLE(ios(13.4))
API_AVAILABLE(ios(14.0), macos(11.0)) static NSString *MTLCommandEncoderErrorStateToString(MTLCommandEncoderErrorState state)
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530
int BOOL
Definition: windows_types.h:37