| Flutter iOS Embedder |

FlutterPlatformPluginTest.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 <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
7
8 #import "flutter/fml/platform/darwin/weak_nsobject.h"
9 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
10 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
11 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
12 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
13 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h"
14 #import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
15
16 FLUTTER_ASSERT_ARC
17
18 @interface FlutterPlatformPluginTest : XCTestCase
19 @end
20
21 @interface FlutterPlatformPlugin ()
22 - (BOOL)isLiveTextInputAvailable;
23 - (void)searchWeb:(NSString*)searchTerm;
24 - (void)showLookUpViewController:(NSString*)term;
25 - (void)showShareViewController:(NSString*)content;
26 @end
27
28 @interface UIViewController ()
29 - (void)presentViewController:(UIViewController*)viewControllerToPresent
30 animated:(BOOL)flag
31 completion:(void (^)(void))completion;
32 @end
33
34 @implementation FlutterPlatformPluginTest
35 - (void)testSearchWebInvokedWithEscapedTerm {
36 id mockApplication = OCMClassMock([UIApplication class]);
37 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
38
39 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
40 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
41 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
42 [engine runWithEntrypoint:nil];
43
44 XCTestExpectation* invokeExpectation =
45 [self expectationWithDescription:@"Web search launched with escaped search term"];
46
47 FlutterPlatformPlugin* plugin =
48 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
49 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
50
51 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
52 arguments:@"Testing Word!"];
53
54 FlutterResult result = ^(id result) {
55 OCMVerify([mockPlugin searchWeb:@"Testing Word!"]);
56 #if not APPLICATION_EXTENSION_API_ONLY
57 OCMVerify([mockApplication openURL:[NSURL URLWithString:@"x-web-search://?Testing%20Word!"]
58 options:@{}
59 completionHandler:nil]);
60 #endif
61 [invokeExpectation fulfill];
62 };
63
64 [mockPlugin handleMethodCall:methodCall result:result];
65 [self waitForExpectationsWithTimeout:1 handler:nil];
66 [mockApplication stopMocking];
67 }
68
69 - (void)testSearchWebInvokedWithNonEscapedTerm {
70 id mockApplication = OCMClassMock([UIApplication class]);
71 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
72
73 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
74 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
75 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
76 [engine runWithEntrypoint:nil];
77
78 XCTestExpectation* invokeExpectation =
79 [self expectationWithDescription:@"Web search launched with non escaped search term"];
80
81 FlutterPlatformPlugin* plugin =
82 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
83 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
84
85 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
86 arguments:@"Test"];
87
88 FlutterResult result = ^(id result) {
89 OCMVerify([mockPlugin searchWeb:@"Test"]);
90 #if not APPLICATION_EXTENSION_API_ONLY
91 OCMVerify([mockApplication openURL:[NSURL URLWithString:@"x-web-search://?Test"]
92 options:@{}
93 completionHandler:nil]);
94 #endif
95 [invokeExpectation fulfill];
96 };
97
98 [mockPlugin handleMethodCall:methodCall result:result];
99 [self waitForExpectationsWithTimeout:1 handler:nil];
100 [mockApplication stopMocking];
101 }
102
103 - (void)testLookUpCallInitiated {
104 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
105 [engine runWithEntrypoint:nil];
106 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
107 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
108
109 XCTestExpectation* presentExpectation =
110 [self expectationWithDescription:@"Look Up view controller presented"];
111
112 FlutterViewController* engineViewController = [[FlutterViewController alloc] initWithEngine:engine
113 nibName:nil
114 bundle:nil];
115 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
116
117 FlutterPlatformPlugin* plugin =
118 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
119 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
120
121 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LookUp.invoke"
122 arguments:@"Test"];
123 FlutterResult result = ^(id result) {
124 OCMVerify([mockEngineViewController
125 presentViewController:[OCMArg isKindOfClass:[UIReferenceLibraryViewController class]]
126 animated:YES
127 completion:nil]);
128 [presentExpectation fulfill];
129 };
130 [mockPlugin handleMethodCall:methodCall result:result];
131 [self waitForExpectationsWithTimeout:2 handler:nil];
132 }
133
134 - (void)testShareScreenInvoked {
135 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
136 [engine runWithEntrypoint:nil];
137 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
138 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
139
140 XCTestExpectation* presentExpectation =
141 [self expectationWithDescription:@"Share view controller presented"];
142
143 FlutterViewController* engineViewController = [[FlutterViewController alloc] initWithEngine:engine
144 nibName:nil
145 bundle:nil];
146 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
147 OCMStub([mockEngineViewController
148 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
149 animated:YES
150 completion:nil]);
151
152 FlutterPlatformPlugin* plugin =
153 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
154 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
155
156 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
157 arguments:@"Test"];
158 FlutterResult result = ^(id result) {
159 OCMVerify([mockEngineViewController
160 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
161 animated:YES
162 completion:nil]);
163 [presentExpectation fulfill];
164 };
165 [mockPlugin handleMethodCall:methodCall result:result];
166 [self waitForExpectationsWithTimeout:1 handler:nil];
167 }
168
169 - (void)testShareScreenInvokedOnIPad {
170 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
171 [engine runWithEntrypoint:nil];
172 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
173 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
174
175 XCTestExpectation* presentExpectation =
176 [self expectationWithDescription:@"Share view controller presented on iPad"];
177
178 FlutterViewController* engineViewController = [[FlutterViewController alloc] initWithEngine:engine
179 nibName:nil
180 bundle:nil];
181 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
182 OCMStub([mockEngineViewController
183 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
184 animated:YES
185 completion:nil]);
186
187 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
188 OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad);
189
190 FlutterPlatformPlugin* plugin =
191 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
192 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
193
194 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
195 arguments:@"Test"];
196 FlutterResult result = ^(id result) {
197 OCMVerify([mockEngineViewController
198 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
199 animated:YES
200 completion:nil]);
201 [presentExpectation fulfill];
202 };
203 [mockPlugin handleMethodCall:methodCall result:result];
204 [self waitForExpectationsWithTimeout:1 handler:nil];
205 }
206
207 - (void)testClipboardHasCorrectStrings {
208 [UIPasteboard generalPasteboard].string = nil;
209 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
210 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
211 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
212 FlutterPlatformPlugin* plugin =
213 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
214
215 XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"];
216 FlutterResult resultSet = ^(id result) {
217 [setStringExpectation fulfill];
218 };
219 FlutterMethodCall* methodCallSet =
220 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData"
221 arguments:@{@"text" : @"some string"}];
222 [plugin handleMethodCall:methodCallSet result:resultSet];
223 [self waitForExpectationsWithTimeout:1 handler:nil];
224
225 XCTestExpectation* hasStringsExpectation = [self expectationWithDescription:@"hasStrings"];
226 FlutterResult result = ^(id result) {
227 XCTAssertTrue([result[@"value"] boolValue]);
228 [hasStringsExpectation fulfill];
229 };
230 FlutterMethodCall* methodCall =
231 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
232 [plugin handleMethodCall:methodCall result:result];
233 [self waitForExpectationsWithTimeout:1 handler:nil];
234
235 XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"];
236 FlutterResult getDataResult = ^(id result) {
237 XCTAssertEqualObjects(result[@"text"], @"some string");
238 [getDataExpectation fulfill];
239 };
240 FlutterMethodCall* methodCallGetData =
241 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" arguments:@"text/plain"];
242 [plugin handleMethodCall:methodCallGetData result:getDataResult];
243 [self waitForExpectationsWithTimeout:1 handler:nil];
244 }
245
246 - (void)testClipboardSetDataToNullDoNotCrash {
247 [UIPasteboard generalPasteboard].string = nil;
248 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
249 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
250 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
251 FlutterPlatformPlugin* plugin =
252 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
253
254 XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"];
255 FlutterResult resultSet = ^(id result) {
256 [setStringExpectation fulfill];
257 };
258 FlutterMethodCall* methodCallSet =
259 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData"
260 arguments:@{@"text" : [NSNull null]}];
261 [plugin handleMethodCall:methodCallSet result:resultSet];
262
263 XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"];
264 FlutterResult result = ^(id result) {
265 XCTAssertEqualObjects(result[@"text"], @"null");
266 [getDataExpectation fulfill];
267 };
268 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData"
269 arguments:@"text/plain"];
270 [plugin handleMethodCall:methodCall result:result];
271 [self waitForExpectationsWithTimeout:1 handler:nil];
272 }
273
274 - (void)testPopSystemNavigator {
275 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
276 [engine runWithEntrypoint:nil];
277 FlutterViewController* flutterViewController =
278 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
279 UINavigationController* navigationController =
280 [[UINavigationController alloc] initWithRootViewController:flutterViewController];
281 UITabBarController* tabBarController = [[UITabBarController alloc] init];
282 tabBarController.viewControllers = @[ navigationController ];
283 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
284 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
285 FlutterPlatformPlugin* plugin =
286 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
287
288 id navigationControllerMock = OCMPartialMock(navigationController);
289 OCMStub([navigationControllerMock popViewControllerAnimated:YES]);
290 // Set some string to the pasteboard.
291 XCTestExpectation* navigationPopCalled = [self expectationWithDescription:@"SystemNavigator.pop"];
292 FlutterResult resultSet = ^(id result) {
293 [navigationPopCalled fulfill];
294 };
295 FlutterMethodCall* methodCallSet =
296 [FlutterMethodCall methodCallWithMethodName:@"SystemNavigator.pop" arguments:@(YES)];
297 [plugin handleMethodCall:methodCallSet result:resultSet];
298 [self waitForExpectationsWithTimeout:1 handler:nil];
299 OCMVerify([navigationControllerMock popViewControllerAnimated:YES]);
300
301 [flutterViewController deregisterNotifications];
302 }
303
304 - (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly {
305 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
306 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
307 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
308 XCTestExpectation* invokeExpectation =
309 [self expectationWithDescription:@"isLiveTextInputAvailableInvoke"];
310 FlutterPlatformPlugin* plugin =
311 [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakNSObject()];
312 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
313 FlutterMethodCall* methodCall =
314 [FlutterMethodCall methodCallWithMethodName:@"LiveText.isLiveTextInputAvailable"
315 arguments:nil];
316 FlutterResult result = ^(id result) {
317 OCMVerify([mockPlugin isLiveTextInputAvailable]);
318 [invokeExpectation fulfill];
319 };
320 [mockPlugin handleMethodCall:methodCall result:result];
321 [self waitForExpectationsWithTimeout:1 handler:nil];
322 }
323
324 - (void)testViewControllerBasedStatusBarHiddenUpdate {
325 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
326 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
327 .andReturn(@YES);
328 {
329 // Enabling system UI overlays to update status bar.
330 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
331 [engine runWithEntrypoint:nil];
332 FlutterViewController* flutterViewController =
333 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
334 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
335 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
336 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
337
338 // Update to hidden.
339 FlutterPlatformPlugin* plugin = [engine platformPlugin];
340
341 XCTestExpectation* enableSystemUIOverlaysCalled =
342 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
343 FlutterResult resultSet = ^(id result) {
344 [enableSystemUIOverlaysCalled fulfill];
345 };
346 FlutterMethodCall* methodCallSet =
347 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
348 arguments:@[ @"SystemUiOverlay.bottom" ]];
349 [plugin handleMethodCall:methodCallSet result:resultSet];
350 [self waitForExpectationsWithTimeout:1 handler:nil];
351 XCTAssertTrue(flutterViewController.prefersStatusBarHidden);
352
353 // Update to shown.
354 XCTestExpectation* enableSystemUIOverlaysCalled2 =
355 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
356 FlutterResult resultSet2 = ^(id result) {
357 [enableSystemUIOverlaysCalled2 fulfill];
358 };
359 FlutterMethodCall* methodCallSet2 =
360 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
361 arguments:@[ @"SystemUiOverlay.top" ]];
362 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
363 [self waitForExpectationsWithTimeout:1 handler:nil];
364 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
365
366 [flutterViewController deregisterNotifications];
367 }
368 {
369 // Enable system UI mode to update status bar.
370 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
371 [engine runWithEntrypoint:nil];
372 FlutterViewController* flutterViewController =
373 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
374 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
375 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
376 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
377
378 // Update to hidden.
379 FlutterPlatformPlugin* plugin = [engine platformPlugin];
380
381 XCTestExpectation* enableSystemUIModeCalled =
382 [self expectationWithDescription:@"setEnabledSystemUIMode"];
383 FlutterResult resultSet = ^(id result) {
384 [enableSystemUIModeCalled fulfill];
385 };
386 FlutterMethodCall* methodCallSet =
387 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode"
388 arguments:@"SystemUiMode.immersive"];
389 [plugin handleMethodCall:methodCallSet result:resultSet];
390 [self waitForExpectationsWithTimeout:1 handler:nil];
391 XCTAssertTrue(flutterViewController.prefersStatusBarHidden);
392
393 // Update to shown.
394 XCTestExpectation* enableSystemUIModeCalled2 =
395 [self expectationWithDescription:@"setEnabledSystemUIMode"];
396 FlutterResult resultSet2 = ^(id result) {
397 [enableSystemUIModeCalled2 fulfill];
398 };
399 FlutterMethodCall* methodCallSet2 =
400 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode"
401 arguments:@"SystemUiMode.edgeToEdge"];
402 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
403 [self waitForExpectationsWithTimeout:1 handler:nil];
404 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
405
406 [flutterViewController deregisterNotifications];
407 }
408 [bundleMock stopMocking];
409 }
410
411 - (void)testStatusBarHiddenUpdate {
412 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
413 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
414 .andReturn(@NO);
415 id mockApplication = OCMClassMock([UIApplication class]);
416 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
417
418 // Enabling system UI overlays to update status bar.
419 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
420 [engine runWithEntrypoint:nil];
421 FlutterViewController* flutterViewController =
422 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
423 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
424 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
425
426 // Update to hidden.
427 FlutterPlatformPlugin* plugin = [engine platformPlugin];
428
429 XCTestExpectation* enableSystemUIOverlaysCalled =
430 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
431 FlutterResult resultSet = ^(id result) {
432 [enableSystemUIOverlaysCalled fulfill];
433 };
434 FlutterMethodCall* methodCallSet =
435 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
436 arguments:@[ @"SystemUiOverlay.bottom" ]];
437 [plugin handleMethodCall:methodCallSet result:resultSet];
438 [self waitForExpectationsWithTimeout:1 handler:nil];
439 #if not APPLICATION_EXTENSION_API_ONLY
440 OCMVerify([mockApplication setStatusBarHidden:YES]);
441 #endif
442
443 // Update to shown.
444 XCTestExpectation* enableSystemUIOverlaysCalled2 =
445 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
446 FlutterResult resultSet2 = ^(id result) {
447 [enableSystemUIOverlaysCalled2 fulfill];
448 };
449 FlutterMethodCall* methodCallSet2 =
450 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
451 arguments:@[ @"SystemUiOverlay.top" ]];
452 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
453 [self waitForExpectationsWithTimeout:1 handler:nil];
454 #if not APPLICATION_EXTENSION_API_ONLY
455 OCMVerify([mockApplication setStatusBarHidden:NO]);
456 #endif
457
458 [flutterViewController deregisterNotifications];
459 [mockApplication stopMocking];
460 [bundleMock stopMocking];
461 }
462
463 - (void)testStatusBarStyle {
464 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
465 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
466 .andReturn(@NO);
467 id mockApplication = OCMClassMock([UIApplication class]);
468 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
469
470 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
471 [engine runWithEntrypoint:nil];
472 FlutterViewController* flutterViewController =
473 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
474 std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
475 std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
476 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
477
478 FlutterPlatformPlugin* plugin = [engine platformPlugin];
479
480 XCTestExpectation* enableSystemUIModeCalled =
481 [self expectationWithDescription:@"setSystemUIOverlayStyle"];
482 FlutterResult resultSet = ^(id result) {
483 [enableSystemUIModeCalled fulfill];
484 };
485 FlutterMethodCall* methodCallSet =
486 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setSystemUIOverlayStyle"
487 arguments:@{@"statusBarBrightness" : @"Brightness.dark"}];
488 [plugin handleMethodCall:methodCallSet result:resultSet];
489 [self waitForExpectationsWithTimeout:1 handler:nil];
490
491 #if not APPLICATION_EXTENSION_API_ONLY
492 OCMVerify([mockApplication setStatusBarStyle:UIStatusBarStyleLightContent]);
493 #endif
494
495 [flutterViewController deregisterNotifications];
496 [mockApplication stopMocking];
497 [bundleMock stopMocking];
498 }
499
500 @end
_weakFactory
std::unique_ptr< fml::WeakNSObjectFactory< FlutterEngine > > _weakFactory
Definition: FlutterEngine.mm:121
FlutterEngine
Definition: FlutterEngine.h:61
+[FlutterMethodCall methodCallWithMethodName:arguments:]
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
FlutterViewController
Definition: FlutterViewController.h:57
FlutterPlatformPluginTest
Definition: FlutterPlatformPluginTest.mm:18
-[FlutterEngine runWithEntrypoint:]
BOOL runWithEntrypoint:(nullable NSString *entrypoint)
FlutterEngine_Internal.h
-[FlutterPlatformPlugin handleMethodCall:result:]
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)
Definition: FlutterPlatformPlugin.mm:106
FlutterMacros.h
FlutterMethodCall
Definition: FlutterCodecs.h:220
FlutterBinaryMessenger.h
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:194
FlutterPlatformPlugin.h
engine
id engine
Definition: FlutterTextInputPluginTest.mm:89
FlutterPlatformPlugin
Definition: FlutterPlatformPlugin.h:12
platform_view_ios.h
FLUTTER_ASSERT_ARC
Definition: FlutterChannelKeyResponder.mm:13
FlutterViewController.h