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