mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[macOS] Fix tests failing on Sonoma (flutter/engine#46461)
1. Using arbitrary struct passed as const reference to `OCMStub` now fails in OCMock. Down the line this will result with `object_getClass` being called in [`OCMArg.m`](https://github.com/erikdoe/ocmock/blob/master/Source/OCMock/OCMArg.m#L129-L133) with the address of the reference, which is not a valid class instance. This seems to have worked pre-sonoma, but it seems like a weird thing to rely on. 2. `NSResponder` mock can not be set to view controller anymore. The controller will try to access an ivar of the `NSResponder`, but mocked responder does not have the ivar of original objects which will result on invalid selector being called on a `NSMutableArray` one of the ivar of mock objects. Solution for this is to inherit from `NSResponder` and forward calls to mocked object. 3. Adding `flutter::kModifierFlagShiftLeft` to a modifier flag containing `kCGEventFlagMaskShift`. The assertion was introduced in https://github.com/flutter/engine/pull/46230 but i missed the test failure because of the problems above. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
0aa1f4977e
commit
6054dbd0cb
@ -276,7 +276,9 @@ void clearEvents(std::vector<FlutterKeyEvent>& events) {
|
||||
OCMStub([viewDelegateMock onTextInputKeyEvent:[OCMArg any]])
|
||||
.andCall(self, @selector(handleTextInputKeyEvent:));
|
||||
OCMStub([viewDelegateMock getBinaryMessenger]).andReturn(_messengerMock);
|
||||
OCMStub([viewDelegateMock sendKeyEvent:FlutterKeyEvent {} callback:nil userData:nil])
|
||||
OCMStub([viewDelegateMock sendKeyEvent:*(const FlutterKeyEvent*)[OCMArg anyPointer]
|
||||
callback:nil
|
||||
userData:nil])
|
||||
.ignoringNonObjectArgs()
|
||||
.andCall(self, @selector(handleEmbedderEvent:callback:userData:));
|
||||
OCMStub([viewDelegateMock subscribeToKeyboardLayoutChange:[OCMArg any]])
|
||||
|
||||
@ -38,6 +38,42 @@
|
||||
}
|
||||
@end
|
||||
|
||||
/// Responder wrapper that forwards key events to another responder. This is a necessary middle step
|
||||
/// for mocking responder because when setting the responder to controller AppKit will access ivars
|
||||
/// of the objects, which means it must extend NSResponder instead of just implementing the
|
||||
/// selectors.
|
||||
@interface FlutterResponderWrapper : NSResponder {
|
||||
NSResponder* _responder;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FlutterResponderWrapper
|
||||
|
||||
- (instancetype)initWithResponder:(NSResponder*)responder {
|
||||
if (self = [super init]) {
|
||||
_responder = responder;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent*)event {
|
||||
[_responder keyDown:event];
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent*)event {
|
||||
[_responder keyUp:event];
|
||||
}
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
||||
return [_responder performKeyEquivalent:event];
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent*)event {
|
||||
[_responder flagsChanged:event];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// A FlutterViewController subclass for testing that mouseDown/mouseUp get called when
|
||||
// mouse events are sent to the associated view.
|
||||
@interface MouseEventFlutterViewController : FlutterViewController
|
||||
@ -417,7 +453,8 @@ TEST(FlutterViewControllerTest, testViewControllerIsReleased) {
|
||||
nibName:@""
|
||||
bundle:nil];
|
||||
id responderMock = flutter::testing::mockResponder();
|
||||
viewController.nextResponder = responderMock;
|
||||
id responderWrapper = [[FlutterResponderWrapper alloc] initWithResponder:responderMock];
|
||||
viewController.nextResponder = responderWrapper;
|
||||
NSDictionary* expectedEvent = @{
|
||||
@"keymap" : @"macos",
|
||||
@"type" : @"keydown",
|
||||
@ -493,7 +530,8 @@ TEST(FlutterViewControllerTest, testViewControllerIsReleased) {
|
||||
nibName:@""
|
||||
bundle:nil];
|
||||
id responderMock = flutter::testing::mockResponder();
|
||||
viewController.nextResponder = responderMock;
|
||||
id responderWrapper = [[FlutterResponderWrapper alloc] initWithResponder:responderMock];
|
||||
viewController.nextResponder = responderWrapper;
|
||||
NSDictionary* expectedEvent = @{
|
||||
@"keymap" : @"macos",
|
||||
@"type" : @"keydown",
|
||||
@ -546,7 +584,8 @@ TEST(FlutterViewControllerTest, testViewControllerIsReleased) {
|
||||
nibName:@""
|
||||
bundle:nil];
|
||||
id responderMock = flutter::testing::mockResponder();
|
||||
viewController.nextResponder = responderMock;
|
||||
id responderWrapper = [[FlutterResponderWrapper alloc] initWithResponder:responderMock];
|
||||
viewController.nextResponder = responderWrapper;
|
||||
NSDictionary* expectedEvent = @{
|
||||
@"keymap" : @"macos",
|
||||
@"type" : @"keydown",
|
||||
@ -825,7 +864,7 @@ TEST(FlutterViewControllerTest, testViewControllerIsReleased) {
|
||||
CGEventRef cgEventDiscreteShift =
|
||||
CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, 0);
|
||||
CGEventSetType(cgEventDiscreteShift, kCGEventScrollWheel);
|
||||
CGEventSetFlags(cgEventDiscreteShift, kCGEventFlagMaskShift);
|
||||
CGEventSetFlags(cgEventDiscreteShift, kCGEventFlagMaskShift | flutter::kModifierFlagShiftLeft);
|
||||
CGEventSetIntegerValueField(cgEventDiscreteShift, kCGScrollWheelEventIsContinuous, 0);
|
||||
CGEventSetIntegerValueField(cgEventDiscreteShift, kCGScrollWheelEventDeltaAxis2,
|
||||
0); // scroll_delta_x
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user