Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1497)

Unified Diff: ios/web/webui/mojo_facade_unittest.mm

Issue 1956113002: [ios Mojo] iOS facade class for Mojo API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated the comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/web/webui/mojo_facade.mm ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/web/webui/mojo_facade_unittest.mm
diff --git a/ios/web/webui/mojo_facade_unittest.mm b/ios/web/webui/mojo_facade_unittest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..3522afd7f2331496465b85c3031fb1d982c6e415
--- /dev/null
+++ b/ios/web/webui/mojo_facade_unittest.mm
@@ -0,0 +1,273 @@
+// Copyright 2016 The Chromium 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 "ios/web/webui/mojo_facade.h"
+
+#include <memory>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/test/ios/wait_util.h"
+#include "ios/web/test/mojo_test.mojom.h"
+#include "ios/web/test/web_test.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/shell/public/cpp/interface_factory.h"
+#include "services/shell/public/cpp/interface_registry.h"
+#import "testing/gtest_mac.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+
+namespace web {
+
+namespace {
+
+// Serializes the given |object| to JSON string.
+std::string GetJson(id object) {
+ NSData* json_as_data =
+ [NSJSONSerialization dataWithJSONObject:object options:0 error:nil];
+ base::scoped_nsobject<NSString> json_as_string([[NSString alloc]
+ initWithData:json_as_data
+ encoding:NSUTF8StringEncoding]);
+ return base::SysNSStringToUTF8(json_as_string);
+}
+
+// Deserializes the given |json| to an object.
+id GetObject(const std::string& json) {
+ NSData* json_as_data =
+ [base::SysUTF8ToNSString(json) dataUsingEncoding:NSUTF8StringEncoding];
+ return [NSJSONSerialization JSONObjectWithData:json_as_data
+ options:0
+ error:nil];
+}
+
+// Test mojo handler factory.
+class TestUIHandlerFactory : public shell::InterfaceFactory<TestUIHandlerMojo> {
+ public:
+ ~TestUIHandlerFactory() override {}
+
+ private:
+ // shell::InterfaceFactory overrides.
+ void Create(shell::Connection* connection,
+ mojo::InterfaceRequest<TestUIHandlerMojo> request) override {}
+};
+
+} // namespace
+
+// A test fixture to test MojoFacade class.
+class MojoFacadeTest : public WebTest {
+ protected:
+ MojoFacadeTest() {
+ interface_registry_.reset(new shell::InterfaceRegistry(nullptr));
+ interface_registry_->AddInterface(&ui_handler_factory_);
+ evaluator_.reset([[OCMockObject
+ mockForProtocol:@protocol(CRWJSInjectionEvaluator)] retain]);
+ facade_.reset(new MojoFacade(
+ interface_registry_.get(),
+ static_cast<id<CRWJSInjectionEvaluator>>(evaluator_.get())));
+ }
+
+ OCMockObject* evaluator() { return evaluator_.get(); }
+ MojoFacade* facade() { return facade_.get(); }
+
+ private:
+ TestUIHandlerFactory ui_handler_factory_;
+ std::unique_ptr<shell::InterfaceRegistry> interface_registry_;
+ base::scoped_nsobject<OCMockObject> evaluator_;
+ std::unique_ptr<MojoFacade> facade_;
+};
+
+// Tests connecting to existing service and closing the handle.
+TEST_F(MojoFacadeTest, ConnectToServiceAndCloseHandle) {
+ // Connect to the service.
+ NSDictionary* connect = @{
+ @"name" : @"service_provider.connectToService",
+ @"args" : @{
+ @"serviceName" : @"::TestUIHandlerMojo",
+ },
+ };
+
+ std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect));
+ EXPECT_FALSE(handle_as_string.empty());
+ int handle = 0;
+ EXPECT_TRUE(base::StringToInt(handle_as_string, &handle));
+
+ // Close the handle.
+ NSDictionary* close = @{
+ @"name" : @"core.close",
+ @"args" : @{
+ @"handle" : @(handle),
+ },
+ };
+ std::string result_as_string = facade()->HandleMojoMessage(GetJson(close));
+ EXPECT_FALSE(result_as_string.empty());
+ int result = 0;
+ EXPECT_TRUE(base::StringToInt(result_as_string, &result));
+ EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
+}
+
+// Tests creating a message pipe without options.
+TEST_F(MojoFacadeTest, CreateMessagePipeWithoutOptions) {
+ // Create a message pipe.
+ NSDictionary* create = @{
+ @"name" : @"core.createMessagePipe",
+ @"args" : @{
+ @"optionsDict" : [NSNull null],
+ },
+ };
+ std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
+
+ // Verify handles.
+ EXPECT_FALSE(response_as_string.empty());
+ NSDictionary* response_as_dict = GetObject(response_as_string);
+ EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
+ id handle0 = response_as_dict[@"handle0"];
+ EXPECT_TRUE(handle0);
+ id handle1 = response_as_dict[@"handle1"];
+ EXPECT_TRUE(handle1);
+
+ // Close handle0.
+ NSDictionary* close0 = @{
+ @"name" : @"core.close",
+ @"args" : @{
+ @"handle" : handle0,
+ },
+ };
+ std::string result0_as_string = facade()->HandleMojoMessage(GetJson(close0));
+ EXPECT_FALSE(result0_as_string.empty());
+ int result0 = 0;
+ EXPECT_TRUE(base::StringToInt(result0_as_string, &result0));
+ EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result0));
+
+ // Close handle1.
+ NSDictionary* close1 = @{
+ @"name" : @"core.close",
+ @"args" : @{
+ @"handle" : handle1,
+ },
+ };
+ std::string result1_as_string = facade()->HandleMojoMessage(GetJson(close1));
+ EXPECT_FALSE(result1_as_string.empty());
+ int result1 = 0;
+ EXPECT_TRUE(base::StringToInt(result1_as_string, &result1));
+ EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result1));
+}
+
+// Tests watching the pipe.
+TEST_F(MojoFacadeTest, Watch) {
+ // Create a message pipe.
+ NSDictionary* create = @{
+ @"name" : @"core.createMessagePipe",
+ @"args" : @{
+ @"optionsDict" : [NSNull null],
+ },
+ };
+ std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
+
+ // Verify handles.
+ EXPECT_FALSE(response_as_string.empty());
+ NSDictionary* response_as_dict = GetObject(response_as_string);
+ EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
+ id handle0 = response_as_dict[@"handle0"];
+ EXPECT_TRUE(handle0);
+ id handle1 = response_as_dict[@"handle1"];
+ EXPECT_TRUE(handle1);
+
+ // Start watching one end of the pipe.
+ int callback_id = 99;
+ NSDictionary* watch = @{
+ @"name" : @"support.watch",
+ @"args" : @{
+ @"handle" : handle0,
+ @"signals" : @(MOJO_HANDLE_SIGNAL_READABLE),
+ @"callbackId" : @(callback_id),
+ },
+ };
+ std::string watch_id_as_string = facade()->HandleMojoMessage(GetJson(watch));
+ EXPECT_FALSE(watch_id_as_string.empty());
+ int watch_id = 0;
+ EXPECT_TRUE(base::StringToInt(watch_id_as_string, &watch_id));
+
+ // Start waiting for the watch callback.
+ __block bool callback_received = false;
+ NSString* expected_script =
+ [NSString stringWithFormat:@"__crWeb.mojo.signalWatch(%d, %d)",
+ callback_id, MOJO_RESULT_OK];
+ [[[evaluator() expect] andDo:^(NSInvocation*) {
+ callback_received = true;
+ }] executeJavaScript:expected_script completionHandler:nil];
+
+ // Write to the other end of the pipe.
+ NSDictionary* write = @{
+ @"name" : @"core.writeMessage",
+ @"args" : @{
+ @"handle" : handle1,
+ @"handles" : @[],
+ @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE),
+ @"buffer" : @{@"0" : @0}
+ },
+ };
+ std::string result_as_string = facade()->HandleMojoMessage(GetJson(write));
+ EXPECT_FALSE(result_as_string.empty());
+ int result = 0;
+ EXPECT_TRUE(base::StringToInt(result_as_string, &result));
+ EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
+
+ base::test::ios::WaitUntilCondition(^{
+ return callback_received;
+ }, base::MessageLoop::current(), base::TimeDelta());
+}
+
+// Tests reading the message from the pipe.
+TEST_F(MojoFacadeTest, ReadWrite) {
+ // Create a message pipe.
+ NSDictionary* create = @{
+ @"name" : @"core.createMessagePipe",
+ @"args" : @{
+ @"optionsDict" : [NSNull null],
+ },
+ };
+ std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
+
+ // Verify handles.
+ EXPECT_FALSE(response_as_string.empty());
+ NSDictionary* response_as_dict = GetObject(response_as_string);
+ EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
+ id handle0 = response_as_dict[@"handle0"];
+ EXPECT_TRUE(handle0);
+ id handle1 = response_as_dict[@"handle1"];
+ EXPECT_TRUE(handle1);
+
+ // Write to the other end of the pipe.
+ NSDictionary* write = @{
+ @"name" : @"core.writeMessage",
+ @"args" : @{
+ @"handle" : handle1,
+ @"handles" : @[],
+ @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE),
+ @"buffer" : @{@"0" : @9, @"1" : @2, @"2" : @2008}
+ },
+ };
+ std::string result_as_string = facade()->HandleMojoMessage(GetJson(write));
+ EXPECT_FALSE(result_as_string.empty());
+ int result = 0;
+ EXPECT_TRUE(base::StringToInt(result_as_string, &result));
+ EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
+
+ // Read the message from the pipe.
+ NSDictionary* read = @{
+ @"name" : @"core.readMessage",
+ @"args" : @{
+ @"handle" : handle0,
+ @"flags" : @(MOJO_READ_MESSAGE_FLAG_NONE),
+ },
+ };
+ NSDictionary* message = GetObject(facade()->HandleMojoMessage(GetJson(read)));
+ EXPECT_TRUE([message isKindOfClass:[NSDictionary class]]);
+ EXPECT_TRUE(message);
+ NSArray* expected_message = @[ @9, @2, @216 ]; // 2008 does not fit 8-bit.
+ EXPECT_NSEQ(expected_message, message[@"buffer"]);
+ EXPECT_FALSE([message[@"handles"] count]);
+ EXPECT_EQ(MOJO_RESULT_OK, [message[@"result"] unsignedIntValue]);
+}
+
+} // namespace web
« no previous file with comments | « ios/web/webui/mojo_facade.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698