|
5 | 5 | #import <XCTest/XCTest.h> |
6 | 6 |
|
7 | 7 | #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" |
| 8 | +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" |
| 9 | +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" |
8 | 10 | #import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h" |
9 | 11 | #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" |
10 | 12 | #import "third_party/ocmock/Source/OCMock/OCMock.h" |
11 | 13 |
|
12 | 14 | FLUTTER_ASSERT_NOT_ARC |
| 15 | +@class MockPlatformView; |
| 16 | +static MockPlatformView* gMockPlatformView = nil; |
| 17 | + |
| 18 | +@interface MockPlatformView : UIView |
| 19 | +@end |
| 20 | +@implementation MockPlatformView |
| 21 | + |
| 22 | +- (instancetype)init { |
| 23 | + self = [super init]; |
| 24 | + if (self) { |
| 25 | + gMockPlatformView = self; |
| 26 | + } |
| 27 | + return self; |
| 28 | +} |
| 29 | + |
| 30 | +- (void)dealloc { |
| 31 | + gMockPlatformView = nil; |
| 32 | + [super dealloc]; |
| 33 | +} |
| 34 | + |
| 35 | +@end |
| 36 | + |
| 37 | +@interface MockFlutterPlatformView : NSObject <FlutterPlatformView> |
| 38 | +@property(nonatomic, strong) UIView* view; |
| 39 | +@end |
| 40 | + |
| 41 | +@implementation MockFlutterPlatformView |
| 42 | + |
| 43 | +- (instancetype)init { |
| 44 | + if (self = [super init]) { |
| 45 | + _view = [[MockPlatformView alloc] init]; |
| 46 | + } |
| 47 | + return self; |
| 48 | +} |
| 49 | + |
| 50 | +- (void)dealloc { |
| 51 | + [_view release]; |
| 52 | + _view = nil; |
| 53 | + [super dealloc]; |
| 54 | +} |
| 55 | + |
| 56 | +@end |
| 57 | + |
| 58 | +@interface MockFlutterPlatformFactory : NSObject <FlutterPlatformViewFactory> |
| 59 | +@end |
| 60 | + |
| 61 | +@implementation MockFlutterPlatformFactory |
| 62 | +- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame |
| 63 | + viewIdentifier:(int64_t)viewId |
| 64 | + arguments:(id _Nullable)args { |
| 65 | + return [[[MockFlutterPlatformView alloc] init] autorelease]; |
| 66 | +} |
| 67 | + |
| 68 | +@end |
13 | 69 |
|
14 | 70 | namespace flutter { |
15 | 71 | namespace { |
@@ -131,4 +187,55 @@ - (void)testUpdateSemanticsOneNode { |
131 | 187 | OCMVerifyAll(mockFlutterView); |
132 | 188 | } |
133 | 189 |
|
| 190 | +- (void)testSemanticsDeallocated { |
| 191 | + @autoreleasepool { |
| 192 | + flutter::MockDelegate mock_delegate; |
| 193 | + auto thread_task_runner = CreateNewThread("AccessibilityBridgeTest"); |
| 194 | + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, |
| 195 | + /*platform=*/thread_task_runner, |
| 196 | + /*raster=*/thread_task_runner, |
| 197 | + /*ui=*/thread_task_runner, |
| 198 | + /*io=*/thread_task_runner); |
| 199 | + auto platform_view = std::make_unique<flutter::PlatformViewIOS>( |
| 200 | + /*delegate=*/mock_delegate, |
| 201 | + /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, |
| 202 | + /*task_runners=*/runners); |
| 203 | + id mockFlutterView = OCMClassMock([FlutterView class]); |
| 204 | + std::string label = "some label"; |
| 205 | + |
| 206 | + auto flutterPlatformViewsController = |
| 207 | + std::make_unique<flutter::FlutterPlatformViewsController>(); |
| 208 | + flutterPlatformViewsController->SetFlutterView(mockFlutterView); |
| 209 | + |
| 210 | + MockFlutterPlatformFactory* factory = [[MockFlutterPlatformFactory new] autorelease]; |
| 211 | + flutterPlatformViewsController->RegisterViewFactory( |
| 212 | + factory, @"MockFlutterPlatformView", |
| 213 | + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); |
| 214 | + FlutterResult result = ^(id result) { |
| 215 | + }; |
| 216 | + flutterPlatformViewsController->OnMethodCall( |
| 217 | + [FlutterMethodCall |
| 218 | + methodCallWithMethodName:@"create" |
| 219 | + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], |
| 220 | + result); |
| 221 | + |
| 222 | + auto bridge = std::make_unique<flutter::AccessibilityBridge>( |
| 223 | + /*view=*/mockFlutterView, |
| 224 | + /*platform_view=*/platform_view.get(), |
| 225 | + /*platform_views_controller=*/flutterPlatformViewsController.get()); |
| 226 | + |
| 227 | + flutter::SemanticsNodeUpdates nodes; |
| 228 | + flutter::SemanticsNode semantics_node; |
| 229 | + semantics_node.id = 2; |
| 230 | + semantics_node.platformViewId = 2; |
| 231 | + semantics_node.label = label; |
| 232 | + nodes[kRootNodeId] = semantics_node; |
| 233 | + flutter::CustomAccessibilityActionUpdates actions; |
| 234 | + bridge->UpdateSemantics(/*nodes=*/nodes, /*actions=*/actions); |
| 235 | + XCTAssertNotNil(gMockPlatformView); |
| 236 | + flutterPlatformViewsController->Reset(); |
| 237 | + } |
| 238 | + XCTAssertNil(gMockPlatformView); |
| 239 | +} |
| 240 | + |
134 | 241 | @end |
0 commit comments