| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import <XCTest/XCTest.h> |
| |
| #import "flutter/shell/platform/darwin/ios/platform_message_handler_ios.h" |
| |
| #import "flutter/common/task_runners.h" |
| #import "flutter/fml/message_loop.h" |
| #import "flutter/fml/thread.h" |
| #import "flutter/shell/common/thread_host.h" |
| #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" |
| |
| FLUTTER_ASSERT_NOT_ARC |
| |
| namespace { |
| using namespace flutter; |
| fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { |
| auto thread = std::make_unique<fml::Thread>(name); |
| auto runner = thread->GetTaskRunner(); |
| return runner; |
| } |
| |
| fml::RefPtr<fml::TaskRunner> GetCurrentTaskRunner() { |
| fml::MessageLoop::EnsureInitializedForCurrentThread(); |
| return fml::MessageLoop::GetCurrent().GetTaskRunner(); |
| } |
| |
| class MockPlatformMessageResponse : public PlatformMessageResponse { |
| public: |
| static fml::RefPtr<MockPlatformMessageResponse> Create() { |
| return fml::AdoptRef(new MockPlatformMessageResponse()); |
| } |
| void Complete(std::unique_ptr<fml::Mapping> data) override { is_complete_ = true; } |
| void CompleteEmpty() override { is_complete_ = true; } |
| }; |
| } // namespace |
| |
| @interface PlatformMessageHandlerIosTest : XCTestCase |
| @end |
| |
| @implementation PlatformMessageHandlerIosTest |
| - (void)testCreate { |
| flutter::TaskRunners task_runners("test", GetCurrentTaskRunner(), CreateNewThread("raster"), |
| CreateNewThread("ui"), CreateNewThread("io")); |
| auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners); |
| XCTAssertTrue(handler); |
| } |
| |
| - (void)testSetAndCallHandler { |
| ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), |
| ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); |
| TaskRunners task_runners( |
| "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), |
| thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); |
| |
| auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners); |
| std::string channel = "foo"; |
| XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"]; |
| handler->SetMessageHandler( |
| channel, |
| ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { |
| reply(nil); |
| [didCallReply fulfill]; |
| }, |
| nil); |
| auto response = MockPlatformMessageResponse::Create(); |
| task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] { |
| auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response); |
| handler->HandlePlatformMessage(std::move(platform_message)); |
| }); |
| [self waitForExpectationsWithTimeout:1.0 handler:nil]; |
| XCTAssertTrue(response->is_complete()); |
| } |
| |
| - (void)testSetClearAndCallHandler { |
| ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), |
| ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); |
| TaskRunners task_runners( |
| "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), |
| thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); |
| |
| auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners); |
| std::string channel = "foo"; |
| XCTestExpectation* didCallMessage = [self expectationWithDescription:@"didCallMessage"]; |
| handler->SetMessageHandler( |
| channel, |
| ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { |
| XCTFail(@"This shouldn't be called"); |
| reply(nil); |
| }, |
| nil); |
| handler->SetMessageHandler(channel, nil, nil); |
| auto response = MockPlatformMessageResponse::Create(); |
| task_runners.GetUITaskRunner()->PostTask([channel, response, &handler, &didCallMessage] { |
| auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response); |
| handler->HandlePlatformMessage(std::move(platform_message)); |
| [didCallMessage fulfill]; |
| }); |
| [self waitForExpectationsWithTimeout:1.0 handler:nil]; |
| XCTAssertTrue(response->is_complete()); |
| } |
| |
| - (void)testSetAndCallHandlerTaskQueue { |
| ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), |
| ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); |
| TaskRunners task_runners( |
| "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), |
| thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); |
| |
| auto handler = std::make_unique<PlatformMessageHandlerIos>(task_runners); |
| std::string channel = "foo"; |
| XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"]; |
| NSObject<FlutterTaskQueue>* taskQueue = PlatformMessageHandlerIos::MakeBackgroundTaskQueue(); |
| handler->SetMessageHandler( |
| channel, |
| ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { |
| XCTAssertFalse([NSThread isMainThread]); |
| reply(nil); |
| [didCallReply fulfill]; |
| }, |
| taskQueue); |
| auto response = MockPlatformMessageResponse::Create(); |
| task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] { |
| auto platform_message = std::make_unique<flutter::PlatformMessage>(channel, response); |
| handler->HandlePlatformMessage(std::move(platform_message)); |
| }); |
| [self waitForExpectationsWithTimeout:1.0 handler:nil]; |
| XCTAssertTrue(response->is_complete()); |
| } |
| @end |