20#import "flutter/shell/platform/darwin/common/test_utils_swift/test_utils_swift.h"
21#import "flutter/shell/platform/darwin/macos/InternalFlutterSwift/InternalFlutterSwift.h"
33#include "gtest/gtest.h"
38@interface FlutterEngine (Test)
53 arguments:(nullable
id)
args {
54 return viewIdentifier == 42 ? [[NSView alloc] init] : nil;
63- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication* _Nonnull)sender {
65 return NSTerminateCancel;
73@property(nonatomic, strong, readonly) NSPointerArray* registeredDelegates;
76- (
BOOL)hasDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate;
92- (void)addApplicationLifecycleDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
93 _delegates.push_back((__bridge
void*)delegate);
96- (void)removeApplicationLifecycleDelegate:
97 (nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
100 @"Attempting to unregister a delegate that was not registered.");
104- (
BOOL)hasDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
117+ (void)registerWithRegistrar:(id<FlutterPluginRegistrar>)registrar {
127- (NSArray<NSScreen*>*)screens {
128 id mockScreen = OCMClassMock([NSScreen
class]);
129 OCMStub([mockScreen backingScaleFactor]).andReturn(2.0);
130 OCMStub([mockScreen deviceDescription]).andReturn(@{
131 @"NSScreenNumber" : [NSNumber numberWithInt:10]
133 OCMStub([mockScreen frame]).andReturn(NSMakeRect(10, 20, 30, 40));
134 return [NSArray arrayWithObject:mockScreen];
144 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
145 ASSERT_TRUE(
engine.running);
150 std::string executable_name = [[engine executableName] UTF8String];
151 ASSERT_FALSE(executable_name.empty());
157 Dart_GetNativeArgument(
args, 0));
158 EXPECT_EQ(executable_name, dart_string);
163 EXPECT_TRUE([
engine runWithEntrypoint:
@"executableNameNotNull"]);
166 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
170#ifndef FLUTTER_RELEASE
172 setenv(
"FLUTTER_ENGINE_SWITCHES",
"2", 1);
173 setenv(
"FLUTTER_ENGINE_SWITCH_1",
"abc", 1);
174 setenv(
"FLUTTER_ENGINE_SWITCH_2",
"foo=\"bar, baz\"", 1);
177 std::vector<std::string> switches =
engine.switches;
178 ASSERT_EQ(switches.size(), 2UL);
179 EXPECT_EQ(switches[0],
"--abc");
180 EXPECT_EQ(switches[1],
"--foo=\"bar, baz\"");
182 unsetenv(
"FLUTTER_ENGINE_SWITCHES");
183 unsetenv(
"FLUTTER_ENGINE_SWITCH_1");
184 unsetenv(
"FLUTTER_ENGINE_SWITCH_2");
190 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
192 NSData* test_message = [@"a message" dataUsingEncoding:NSUTF8StringEncoding];
196 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
198 EXPECT_STREQ(
message->channel,
"test");
199 EXPECT_EQ(memcmp(
message->message, test_message.bytes,
message->message_size), 0);
203 [engine.binaryMessenger sendOnChannel:@"test" message:test_message];
210 AddNativeCallback(
"SignalNativeTest",
214 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
215 writer.expectedOutput =
@"Hello logging";
216 FlutterLogger.outputWriter = writer;
220 EXPECT_TRUE([
engine runWithEntrypoint:
@"canLogToStdout"]);
221 ASSERT_TRUE(
engine.running);
224 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
228 EXPECT_TRUE(writer.gotExpectedOutput);
238 EXPECT_TRUE(rootLayer.backgroundColor != nil);
239 if (rootLayer.backgroundColor != nil) {
240 NSColor* actualBackgroundColor =
241 [NSColor colorWithCGColor:rootLayer.backgroundColor];
242 EXPECT_EQ(actualBackgroundColor, [NSColor blackColor]);
248 EXPECT_TRUE([
engine runWithEntrypoint:
@"backgroundTest"]);
249 ASSERT_TRUE(
engine.running);
254 [viewController loadView];
258 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
269 EXPECT_TRUE(rootLayer.backgroundColor != nil);
270 if (rootLayer.backgroundColor != nil) {
271 NSColor* actualBackgroundColor =
272 [NSColor colorWithCGColor:rootLayer.backgroundColor];
273 EXPECT_EQ(actualBackgroundColor, [NSColor whiteColor]);
279 EXPECT_TRUE([
engine runWithEntrypoint:
@"backgroundTest"]);
280 ASSERT_TRUE(
engine.running);
285 [viewController loadView];
290 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
300 Initialize, ([&update_semantics_callback, &original_init](
303 update_semantics_callback =
args->update_semantics_callback2;
304 return original_init(version, config,
args,
user_data, engine_out);
306 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
311 [viewController loadView];
313 bool enabled_called =
false;
316 enabled_called = enabled;
319 engine.semanticsEnabled = YES;
320 EXPECT_TRUE(enabled_called);
338 int32_t children[] = {1};
345 child1.
flags2 = &child_flags;
350 child1.
label =
"child 1";
363 update.
nodes = nodes;
365 update_semantics_callback(&update, (__bridge
void*)
engine);
369 NSAccessibilityElement* native_root =
engine.
viewController.flutterView.accessibilityChildren[0];
370 std::string root_label = [native_root.accessibilityLabel UTF8String];
371 EXPECT_TRUE(root_label ==
"root");
372 EXPECT_EQ(native_root.accessibilityRole, NSAccessibilityGroupRole);
373 EXPECT_EQ([native_root.accessibilityChildren count], 1u);
374 NSAccessibilityElement* native_child1 = native_root.accessibilityChildren[0];
375 std::string child1_value = [native_child1.accessibilityValue UTF8String];
376 EXPECT_TRUE(child1_value ==
"child 1");
377 EXPECT_EQ(native_child1.accessibilityRole, NSAccessibilityStaticTextRole);
378 EXPECT_EQ([native_child1.accessibilityChildren count], 0u);
380 bool semanticsEnabled =
true;
383 semanticsEnabled = enabled;
386 engine.semanticsEnabled = NO;
387 EXPECT_FALSE(semanticsEnabled);
391 [engine setViewController:nil];
400 Initialize, ([&update_semantics_callback, &original_init](
403 update_semantics_callback =
args->update_semantics_callback2;
404 return original_init(version, config,
args,
user_data, engine_out);
406 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
409 bool enabled_called =
false;
412 enabled_called = enabled;
415 engine.semanticsEnabled = YES;
416 EXPECT_TRUE(enabled_called);
434 int32_t children[] = {1};
440 child1.
flags2 = &child_flags;
445 child1.
label =
"child 1";
457 update.
nodes = nodes;
461 update_semantics_callback(&update, (__bridge
void*)
engine);
467 bool semanticsEnabled =
true;
470 semanticsEnabled = enabled;
473 engine.semanticsEnabled = NO;
474 EXPECT_FALSE(semanticsEnabled);
481 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
484 bool enabled_called =
false;
487 enabled_called = enabled;
490 engine.semanticsEnabled = YES;
491 EXPECT_TRUE(enabled_called);
505 BOOL latch_called = NO;
506 AddNativeCallback(
"SignalNativeTest",
510 EXPECT_TRUE([
engine runWithEntrypoint:
@"nativeCallback"]);
511 ASSERT_TRUE(
engine.running);
513 while (!latch_called) {
514 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
516 ASSERT_TRUE(latch_called);
522 initWithAssetsPath:fixtures
523 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
529 [viewController loadView];
530 [viewController viewDidLoad];
533 EXPECT_TRUE([
engine runWithEntrypoint:
@"canCompositePlatformViews"]);
536 withId:@"factory_id"];
537 [engine.platformViewController
541 @"viewType" : @"factory_id",
547 CFAbsoluteTime
start = CFAbsoluteTimeGetCurrent();
549 while (rootLayer.sublayers.count == 0) {
550 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
551 if (CFAbsoluteTimeGetCurrent() -
start > 1) {
557 EXPECT_EQ(rootLayer.sublayers.count, 2u);
562 [engine shutDownEngine];
570 Initialize, ([&compositor, &original_init](
573 compositor = *
args->compositor;
574 return original_init(version, config,
args,
user_data, engine_out);
580 [viewController loadView];
582 EXPECT_TRUE([
engine runWithEntrypoint:
@"empty"]);
595 .backing_store = &backing_store,
597 std::vector<FlutterLayer*>
layers = {&layer};
611 [engine shutDownEngine];
617 initWithAssetsPath:fixtures
618 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
620 project.dartEntrypointArguments = @[ @"arg1", @"arg2" ];
630 EXPECT_EQ(
args->dart_entrypoint_argc, 2);
631 NSString* arg1 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[0]
632 encoding:NSUTF8StringEncoding];
633 NSString* arg2 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[1]
634 encoding:NSUTF8StringEncoding];
636 EXPECT_TRUE([arg1 isEqualToString:
@"arg1"]);
637 EXPECT_TRUE([arg2 isEqualToString:
@"arg2"]);
639 return original_init(version, config,
args,
user_data, engine_out);
642 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
644 [engine shutDownEngine];
655 id<FlutterBinaryMessenger> binaryMessenger = nil;
660 initWithAssetsPath:fixtures
661 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
664 allowHeadlessExecution:YES];
671 EXPECT_NE(binaryMessenger, nil);
672 EXPECT_EQ(weakEngine, nil);
679 id<FlutterTextureRegistry> textureRegistry;
684 initWithAssetsPath:fixtures
685 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
688 allowHeadlessExecution:YES];
689 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
690 textureRegistry = registrar.textures;
695 EXPECT_NE(textureRegistry, nil);
696 EXPECT_EQ(weakEngine, nil);
702 initWithAssetsPath:fixtures
703 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
706 allowHeadlessExecution:YES];
708 EXPECT_EQ([
engine valuePublishedByPlugin:
@"NoSuchPlugin"], nil);
714 initWithAssetsPath:fixtures
715 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
718 allowHeadlessExecution:YES];
719 NSString* pluginName =
@"MyPlugin";
721 [engine registrarForPlugin:pluginName];
725 EXPECT_EQ([
engine valuePublishedByPlugin:pluginName], [NSNull null]);
731 initWithAssetsPath:fixtures
732 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
735 allowHeadlessExecution:YES];
736 NSString* pluginName =
@"MyPlugin";
737 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:pluginName];
739 NSString* firstValue =
@"A published value";
740 NSArray* secondValue = @[ @"A different published value" ];
742 [registrar publish:firstValue];
743 EXPECT_EQ([
engine valuePublishedByPlugin:pluginName], firstValue);
745 [registrar publish:secondValue];
746 EXPECT_EQ([
engine valuePublishedByPlugin:pluginName], secondValue);
752 initWithAssetsPath:fixtures
753 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
759 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
772 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
775 NSData* channel_data = [channel dataUsingEncoding:NSUTF8StringEncoding];
781 SendPlatformMessage, ([](
auto engine_,
auto message_) {
782 if (strcmp(message_->channel,
"test/send_message") == 0) {
784 std::string message = R
"|({"method": "a"})|";
785 std::string channel(reinterpret_cast<const char*>(message_->message),
786 message_->message_size);
787 reinterpret_cast<EmbedderEngine*>(engine_)
790 ->HandlePlatformMessage(std::make_unique<PlatformMessage>(
791 channel.c_str(), fml::MallocMapping::Copy(message.c_str(), message.length()),
792 fml::RefPtr<PlatformMessageResponse>()));
797 __block
int record = 0;
807 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
808 EXPECT_EQ(record, 1);
818 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
819 EXPECT_EQ(record, 11);
823 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
824 EXPECT_EQ(record, 21);
831 __block
bool calledAfterClear =
false;
832 __block
bool valueAfterClear;
834 calledAfterClear =
true;
835 NSNumber* valueNumber = [result valueForKey:@"value"];
836 valueAfterClear = [valueNumber boolValue];
840 [engineMock handleMethodCall:methodCallAfterClear result:resultAfterClear];
841 EXPECT_TRUE(calledAfterClear);
842 EXPECT_FALSE(valueAfterClear);
849 __block
bool called =
false;
853 NSNumber* valueNumber = [result valueForKey:@"value"];
854 value = [valueNumber boolValue];
858 [engineMock handleMethodCall:methodCall result:result];
867 binaryMessenger:engine.binaryMessenger
869 __block
BOOL didCallCallback = NO;
873 didCallCallback = YES;
875 EXPECT_TRUE([
engine runWithEntrypoint:
@"sendFooMessage"]);
878 while (!didCallCallback) {
879 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
887 binaryMessenger:engine.binaryMessenger
889 __block
BOOL didCallCallback = NO;
891 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
893 dispatch_async(dispatch_get_main_queue(), ^{
894 didCallCallback = YES;
898 EXPECT_TRUE([
engine runWithEntrypoint:
@"sendFooMessage"]);
900 while (!didCallCallback) {
901 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
909 std::optional<int64_t> engineId;
911 const auto argument = Dart_GetNativeArgument(
args, 0);
912 if (!Dart_IsNull(argument)) {
919 EXPECT_TRUE([
engine runWithEntrypoint:
@"testEngineId"]);
921 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
924 EXPECT_TRUE(engineId.has_value());
925 if (!engineId.has_value()) {
933 FlutterResizeSynchronizer* threadSynchronizer = [[FlutterResizeSynchronizer alloc] init];
934 [threadSynchronizer shutDown];
936 std::thread rasterThread([&threadSynchronizer] {
937 [threadSynchronizer performCommitForSize:CGSizeMake(100, 100)
949 initWithAssetsPath:fixtures
950 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
958 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
975 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
984 allowHeadlessExecution:NO];
989 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
997 EXPECT_EQ(viewController2.viewIdentifier, 0ll);
1006 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
1012 initWithAssetsPath:fixtures
1013 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
1019 [viewController loadView];
1020 [viewController viewDidLoad];
1023 EXPECT_TRUE([
engine runWithEntrypoint:
@"drawIntoAllViews"]);
1025 CFTimeInterval
start = CACurrentMediaTime();
1027 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
1028 if (CACurrentMediaTime() -
start > 1) {
1038 [engine shutDownEngine];
1044 __block NSString* nextResponse =
@"exit";
1045 __block
BOOL triedToTerminate = NO;
1048 terminator:^(id sender) {
1049 triedToTerminate = TRUE;
1052 OCMStub([engineMock terminationHandler]).andReturn(terminationHandler);
1053 id binaryMessengerMock = OCMProtocolMock(
@protocol(FlutterBinaryMessenger));
1055 [engineMock binaryMessenger])
1056 .andReturn(binaryMessengerMock);
1057 OCMStub([engineMock sendOnChannel:
@"flutter/platform"
1059 binaryReply:[OCMArg any]])
1060 .andDo((^(NSInvocation* invocation) {
1061 [invocation retainArguments];
1063 NSData* returnedMessage;
1064 [invocation getArgument:&callback atIndex:4];
1065 if ([nextResponse isEqualToString:
@"error"]) {
1072 NSDictionary* responseDict = @{
@"response" : nextResponse};
1078 __block NSString* calledAfterTerminate =
@"";
1080 NSDictionary* resultDict = result;
1081 calledAfterTerminate = resultDict[@"response"];
1088 triedToTerminate = NO;
1089 calledAfterTerminate =
@"";
1090 nextResponse =
@"cancel";
1091 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1092 EXPECT_STREQ([calledAfterTerminate UTF8String],
"");
1093 EXPECT_TRUE(triedToTerminate);
1097 triedToTerminate = NO;
1098 calledAfterTerminate =
@"";
1099 nextResponse =
@"exit";
1100 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1101 EXPECT_STREQ([calledAfterTerminate UTF8String],
"exit");
1102 EXPECT_TRUE(triedToTerminate);
1104 triedToTerminate = NO;
1105 calledAfterTerminate =
@"";
1106 nextResponse =
@"cancel";
1107 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1108 EXPECT_STREQ([calledAfterTerminate UTF8String],
"cancel");
1109 EXPECT_FALSE(triedToTerminate);
1112 triedToTerminate = NO;
1113 calledAfterTerminate =
@"";
1114 nextResponse =
@"error";
1115 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1116 EXPECT_STREQ([calledAfterTerminate UTF8String],
"");
1117 EXPECT_TRUE(triedToTerminate);
1121 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1123 [NSApplication sharedApplication].delegate = plainDelegate;
1130 EXPECT_EQ([[[NSApplication sharedApplication] delegate] applicationShouldTerminate:NSApp],
1133 [NSApplication sharedApplication].delegate = previousDelegate;
1137 __block
BOOL announced = NO;
1140 OCMStub([engineMock announceAccessibilityMessage:[OCMArg any]
1141 withPriority:NSAccessibilityPriorityMedium])
1142 .andDo((^(NSInvocation* invocation) {
1144 [invocation retainArguments];
1146 [invocation getArgument:&message atIndex:2];
1147 EXPECT_EQ(
message,
@"error message");
1150 NSDictionary<NSString*, id>* annotatedEvent =
1151 @{
@"type" :
@"announce",
1152 @"data" : @{
@"message" :
@"error message"}};
1154 [engineMock handleAccessibilityEvent:annotatedEvent];
1156 EXPECT_TRUE(announced);
1166 .andDo((^(NSInvocation* invocation) {
1170 .andDo((^(NSInvocation* invocation) {
1174 .andDo((^(NSInvocation* invocation) {
1178 .andDo((^(NSInvocation* invocation) {
1182 .andDo((^(NSInvocation* invocation) {
1186 __block NSApplicationOcclusionState visibility = NSApplicationOcclusionStateVisible;
1187 id mockApplication = OCMPartialMock([NSApplication sharedApplication]);
1188 OCMStub((NSApplicationOcclusionState)[mockApplication occlusionState])
1189 .andDo(^(NSInvocation* invocation) {
1190 [invocation setReturnValue:&visibility];
1193 NSNotification* willBecomeActive =
1194 [[NSNotification alloc] initWithName:NSApplicationWillBecomeActiveNotification
1197 NSNotification* willResignActive =
1198 [[NSNotification alloc] initWithName:NSApplicationWillResignActiveNotification
1202 NSNotification* didChangeOcclusionState;
1203 didChangeOcclusionState =
1204 [[NSNotification alloc] initWithName:NSApplicationDidChangeOcclusionStateNotification
1208 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1211 [engineMock handleWillBecomeActive:willBecomeActive];
1214 [engineMock handleWillResignActive:willResignActive];
1218 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1221 [engineMock handleWillBecomeActive:willBecomeActive];
1224 [engineMock handleWillResignActive:willResignActive];
1227 [mockApplication stopMocking];
1231 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1233 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1238 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1240 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1242 [NSApplication sharedApplication].delegate = previousDelegate;
1246 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1248 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1255 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1256 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1261 EXPECT_FALSE([fakeAppDelegate hasDelegate:plugin]);
1263 [NSApplication sharedApplication].delegate = previousDelegate;
1271 NotifyDisplayUpdate, ([&updated, &original_update_displays](
1272 auto engine,
auto update_type,
auto*
displays,
auto display_count) {
1274 return original_update_displays(
engine, update_type,
displays, display_count);
1277 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
1278 EXPECT_TRUE(updated);
1281 [[NSNotificationCenter defaultCenter]
1282 postNotificationName:NSApplicationDidChangeScreenParametersNotification
1284 EXPECT_TRUE(updated);
1292 SendWindowMetricsEvent,
1293 ([&updated, &original_set_viewport_metrics](
auto engine,
auto* window_metrics) {
1295 return original_set_viewport_metrics(
engine, window_metrics);
1298 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
1301 [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidChangeScreenNotification
1304 EXPECT_FALSE(updated);
1309 [viewController loadView];
1312 [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidChangeScreenNotification
1314 EXPECT_TRUE(updated);
1318 NSString* fixtures = @(testing::GetFixturesPath());
1320 initWithAssetsPath:fixtures
1321 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
1325 allowHeadlessExecution:true];
1329 NotifyDisplayUpdate, ([&updated, &original_update_displays](
1330 auto engine,
auto update_type,
auto*
displays,
auto display_count) {
1331 EXPECT_EQ(display_count, 1UL);
1332 EXPECT_EQ(
displays->display_id, 10UL);
1335 EXPECT_EQ(
displays->device_pixel_ratio, 2UL);
1337 return original_update_displays(
engine, update_type,
displays, display_count);
1339 EXPECT_TRUE([
engine runWithEntrypoint:
@"main"]);
1340 EXPECT_TRUE(updated);
1346 __block
BOOL expectedValue;
1350 OCMStub([channelMock messageChannelWithName:
@"flutter/settings"
1351 binaryMessenger:[OCMArg any]
1352 codec:[OCMArg any]])
1353 .andReturn(channelMock);
1354 OCMStub([channelMock sendMessage:[OCMArg any]]).andDo((^(NSInvocation* invocation) {
1356 [invocation getArgument:&message atIndex:2];
1357 EXPECT_EQ(
message[
@"alwaysUse24HourFormat"], @(expectedValue));
1361 OCMStub([mockHourFormat isAlwaysUse24HourFormat]).andDo((^(NSInvocation* invocation) {
1362 [invocation setReturnValue:&expectedValue];
1368 expectedValue = YES;
1369 EXPECT_TRUE([engineMock runWithEntrypoint:
@"main"]);
1370 [engineMock shutDownEngine];
1374 EXPECT_TRUE([engineMock runWithEntrypoint:
@"main"]);
1375 [engineMock shutDownEngine];
1378 [mockHourFormat stopMocking];
1379 [engineMock stopMocking];
1380 [channelMock stopMocking];
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
void(^ FlutterResult)(id _Nullable result)
TEST_F(FlutterDisplayLinkTest, ViewAddedToWindowFirst)
NSPointerArray * _delegates
flutter::FlutterCompositor * macOSCompositor
FlutterEngine * engine() const
#define FLUTTER_API_SYMBOL(symbol)
@ kFlutterLayerContentTypeBackingStore
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
void setMessageHandler:(FlutterMessageHandler _Nullable handler)
void(* rootIsolateCreateCallback)(void *_Nullable)
NSObject< FlutterBinaryMessenger > * binaryMessenger
flutter::FlutterCompositor * macOSCompositor
FlutterViewController * viewController
FlutterEngineProcTable & embedderAPI
instancetype errorWithCode:message:details:(NSString *code,[message] NSString *_Nullable message,[details] id _Nullable details)
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
void setMethodCallHandler:(FlutterMethodCallHandler _Nullable handler)
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
NSColor * backgroundColor
UITextSmartQuotesType smartQuotesType API_AVAILABLE(ios(11.0))
FlutterViewController * viewController
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
id CreateMockFlutterEngine(NSString *pasteboardString)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
#define MOCK_ENGINE_PROC(proc, mock_impl)
instancetype sharedInstance()
FlutterBackingStoreCreateCallback create_backing_store_callback
FlutterPresentViewCallback present_view_callback
FlutterBackingStoreCollectCallback collect_backing_store_callback
FlutterEngineSendWindowMetricsEventFnPtr SendWindowMetricsEvent
FlutterEngineInitializeFnPtr Initialize
FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate
FlutterEngineSendPlatformMessageFnPtr SendPlatformMessage
FlutterEngineUpdateSemanticsEnabledFnPtr UpdateSemanticsEnabled
FlutterLayerContentType type
const char * increased_value
const char * tooltip
A textual tooltip attached to the node.
size_t custom_accessibility_actions_count
The number of custom accessibility action associated with this node.
const int32_t * children_in_traversal_order
Array of child node IDs in traversal order. Has length child_count.
int32_t text_selection_extent
The position at which the text selection terminates.
FlutterSemanticsAction actions
The set of semantics actions applicable to this node.
int32_t id
The unique identifier for this node.
size_t child_count
The number of children this node has.
const char * decreased_value
const char * label
A textual description of the node.
int32_t text_selection_base
The position at which the text selection originates.
const char * hint
A brief description of the result of performing an action on the node.
FlutterSemanticsFlags * flags2
const char * value
A textual description of the current value of the node.
A batch of updates to semantics nodes and custom actions.
size_t node_count
The number of semantics node updates.
size_t custom_action_count
The number of semantics custom action updates.
FlutterSemanticsNode2 ** nodes
A structure to represent the width and height.
#define CREATE_NATIVE_ENTRY(native_entry)