| Flutter iOS Embedder |

platform_message_handler_ios_test.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 <XCTest/XCTest.h>
6
7 #import "flutter/shell/platform/darwin/ios/platform_message_handler_ios.h"
8
9 #import "flutter/common/task_runners.h"
10 #import "flutter/fml/message_loop.h"
11 #import "flutter/fml/thread.h"
12 #import "flutter/lib/ui/window/platform_message.h"
13 #import "flutter/lib/ui/window/platform_message_response.h"
14 #import "flutter/shell/common/thread_host.h"
15 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
16
17 FLUTTER_ASSERT_ARC
18
19 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
20 namespace {
21 using namespace flutter;
22 fml::RefPtr<fml::TaskRunner> CreateNewThread(const std::string& name) {
23 auto thread = std::make_unique<fml::Thread>(name);
24 auto runner = thread->GetTaskRunner();
25 return runner;
26 }
27
28 fml::RefPtr<fml::TaskRunner> GetCurrentTaskRunner() {
29 fml::MessageLoop::EnsureInitializedForCurrentThread();
30 return fml::MessageLoop::GetCurrent().GetTaskRunner();
31 }
32
33 class MockPlatformMessageResponse : public PlatformMessageResponse {
34 public:
35 static fml::RefPtr<MockPlatformMessageResponse> Create() {
36 return fml::AdoptRef(new MockPlatformMessageResponse());
37 }
38 void Complete(std::unique_ptr<fml::Mapping> data) override { is_complete_ = true; }
39 void CompleteEmpty() override { is_complete_ = true; }
40 };
41 } // namespace
42
43 @interface PlatformMessageHandlerIosTest : XCTestCase
44 @end
45
46 @implementation PlatformMessageHandlerIosTest
47 - (void)testCreate {
48 TaskRunners task_runners("test", GetCurrentTaskRunner(), CreateNewThread("raster"),
49 CreateNewThread("ui"), CreateNewThread("io"));
50 auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners.GetPlatformTaskRunner());
51 XCTAssertTrue(handler);
52 }
53
54 - (void)testSetAndCallHandler {
55 ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String),
56 ThreadHost::Type::kRaster | ThreadHost::Type::kIo | ThreadHost::Type::kUi);
57 TaskRunners task_runners(
58 "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(),
59 thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner());
60
61 auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners.GetPlatformTaskRunner());
62 std::string channel = "foo";
63 XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"];
64 handler->SetMessageHandler(
65 channel,
66 ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) {
67 reply(nil);
68 [didCallReply fulfill];
69 },
70 nil);
71 auto response = MockPlatformMessageResponse::Create();
72 task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] {
73 auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response);
74 handler->HandlePlatformMessage(std::move(platform_message));
75 });
76 [self waitForExpectationsWithTimeout:1.0 handler:nil];
77 XCTAssertTrue(response->is_complete());
78 }
79
80 - (void)testSetClearAndCallHandler {
81 ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String),
82 ThreadHost::Type::kRaster | ThreadHost::Type::kIo | ThreadHost::Type::kUi);
83 TaskRunners task_runners(
84 "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(),
85 thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner());
86
87 auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners.GetPlatformTaskRunner());
88 std::string channel = "foo";
89 XCTestExpectation* didCallMessage = [self expectationWithDescription:@"didCallMessage"];
90 handler->SetMessageHandler(
91 channel,
92 ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) {
93 XCTFail(@"This shouldn't be called");
94 reply(nil);
95 },
96 nil);
97 handler->SetMessageHandler(channel, nil, nil);
98 auto response = MockPlatformMessageResponse::Create();
99 task_runners.GetUITaskRunner()->PostTask([channel, response, &handler, &didCallMessage] {
100 auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response);
101 handler->HandlePlatformMessage(std::move(platform_message));
102 [didCallMessage fulfill];
103 });
104 [self waitForExpectationsWithTimeout:1.0 handler:nil];
105 XCTAssertTrue(response->is_complete());
106 }
107
108 - (void)testSetAndCallHandlerTaskQueue {
109 ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String),
110 ThreadHost::Type::kRaster | ThreadHost::Type::kIo | ThreadHost::Type::kUi);
111 TaskRunners task_runners(
112 "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(),
113 thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner());
114
115 auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners.GetPlatformTaskRunner());
116 std::string channel = "foo";
117 XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"];
118 NSObject<FlutterTaskQueue>* taskQueue = PlatformMessageHandlerIos::MakeBackgroundTaskQueue();
119 handler->SetMessageHandler(
120 channel,
121 ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) {
122 XCTAssertFalse([NSThread isMainThread]);
123 reply(nil);
124 [didCallReply fulfill];
125 },
126 taskQueue);
127 auto response = MockPlatformMessageResponse::Create();
128 task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] {
129 auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response);
130 handler->HandlePlatformMessage(std::move(platform_message));
131 });
132 [self waitForExpectationsWithTimeout:1.0 handler:nil];
133 XCTAssertTrue(response->is_complete());
134 }
135 @end
136 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
FlutterBinaryReply
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
FlutterMacros.h
FLUTTER_ASSERT_ARC::MockPlatformMessageResponse
Definition: platform_message_handler_ios_test.mm:33
FLUTTER_ASSERT_ARC::MockPlatformMessageResponse::Complete
void Complete(std::unique_ptr< fml::Mapping > data) override
Definition: platform_message_handler_ios_test.mm:38
FLUTTER_ASSERT_ARC::MockPlatformMessageResponse::Create
static fml::RefPtr< MockPlatformMessageResponse > Create()
Definition: platform_message_handler_ios_test.mm:35
FLUTTER_ASSERT_ARC::MockPlatformMessageResponse::CompleteEmpty
void CompleteEmpty() override
Definition: platform_message_handler_ios_test.mm:39
PlatformMessageHandlerIosTest
Definition: platform_message_handler_ios_test.mm:44
FLUTTER_ASSERT_ARC
Definition: FlutterChannelKeyResponder.mm:13
FLUTTER_ASSERT_ARC::CreateNewThread
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
Definition: VsyncWaiterIosTest.mm:16
FLUTTER_ASSERT_ARC::GetCurrentTaskRunner
fml::RefPtr< fml::TaskRunner > GetCurrentTaskRunner()
Definition: platform_message_handler_ios_test.mm:28
flutter
Definition: accessibility_bridge.h:26
platform_message_handler_ios.h