blob: 376162ead5980cae1a6205898b8cfa4561289bd2 [file] [log] [blame]
// 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