Flutter macOS Embedder
method_channel_unittests.cc
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 
6 
7 #include <memory>
8 #include <string>
9 
13 #include "gtest/gtest.h"
14 
15 namespace flutter {
16 
17 namespace {
18 
19 class TestBinaryMessenger : public BinaryMessenger {
20  public:
21  void Send(const std::string& channel,
22  const uint8_t* message,
23  size_t message_size,
24  BinaryReply reply) const override {
25  send_called_ = true;
26  last_reply_handler_ = reply;
27  int length = static_cast<int>(message_size);
28  last_message_ =
29  std::vector<uint8_t>(message, message + length * sizeof(uint8_t));
30  }
31 
32  void SetMessageHandler(const std::string& channel,
33  BinaryMessageHandler handler) override {
34  last_message_handler_channel_ = channel;
35  last_message_handler_ = handler;
36  }
37 
38  bool send_called() { return send_called_; }
39 
40  BinaryReply last_reply_handler() { return last_reply_handler_; }
41 
42  std::string last_message_handler_channel() {
43  return last_message_handler_channel_;
44  }
45 
46  BinaryMessageHandler last_message_handler() { return last_message_handler_; }
47 
48  std::vector<uint8_t> last_message() { return last_message_; }
49 
50  private:
51  mutable bool send_called_ = false;
52  mutable BinaryReply last_reply_handler_;
53  std::string last_message_handler_channel_;
54  BinaryMessageHandler last_message_handler_;
55  mutable std::vector<uint8_t> last_message_;
56 };
57 
58 } // namespace
59 
60 // Tests that SetMethodCallHandler sets a handler that correctly interacts with
61 // the binary messenger.
62 TEST(MethodChannelTest, Registration) {
63  TestBinaryMessenger messenger;
64  const std::string channel_name("some_channel");
66  MethodChannel channel(&messenger, channel_name, &codec);
67 
68  bool callback_called = false;
69  const std::string method_name("hello");
70  channel.SetMethodCallHandler(
71  [&callback_called, method_name](const auto& call, auto result) {
72  callback_called = true;
73  // Ensure that the wrapper received a correctly decoded call and a
74  // result.
75  EXPECT_EQ(call.method_name(), method_name);
76  EXPECT_NE(result, nullptr);
77  result->Success();
78  });
79  EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
80  EXPECT_NE(messenger.last_message_handler(), nullptr);
81  // Send a test message to trigger the handler test assertions.
82  MethodCall<> call(method_name, nullptr);
83  auto message = codec.EncodeMethodCall(call);
84 
85  messenger.last_message_handler()(
86  message->data(), message->size(),
87  [](const uint8_t* reply, size_t reply_size) {});
88  EXPECT_TRUE(callback_called);
89 }
90 
91 // Tests that SetMethodCallHandler with a null handler unregisters the handler.
92 TEST(MethodChannelTest, Unregistration) {
93  TestBinaryMessenger messenger;
94  const std::string channel_name("some_channel");
95  MethodChannel channel(&messenger, channel_name,
97 
98  channel.SetMethodCallHandler([](const auto& call, auto result) {});
99  EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
100  EXPECT_NE(messenger.last_message_handler(), nullptr);
101 
102  channel.SetMethodCallHandler(nullptr);
103  EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
104  EXPECT_EQ(messenger.last_message_handler(), nullptr);
105 }
106 
107 TEST(MethodChannelTest, InvokeWithoutResponse) {
108  TestBinaryMessenger messenger;
109  const std::string channel_name("some_channel");
110  MethodChannel channel(&messenger, channel_name,
112 
113  channel.InvokeMethod("foo", nullptr);
114  EXPECT_TRUE(messenger.send_called());
115  EXPECT_EQ(messenger.last_reply_handler(), nullptr);
116 }
117 
118 TEST(MethodChannelTest, InvokeWithResponse) {
119  TestBinaryMessenger messenger;
120  const std::string channel_name("some_channel");
121  MethodChannel channel(&messenger, channel_name,
123 
124  bool received_reply = false;
125  const std::string reply = "bar";
126  auto result_handler = std::make_unique<MethodResultFunctions<>>(
127  [&received_reply, reply](const EncodableValue* success_value) {
128  received_reply = true;
129  EXPECT_EQ(std::get<std::string>(*success_value), reply);
130  },
131  nullptr, nullptr);
132 
133  channel.InvokeMethod("foo", nullptr, std::move(result_handler));
134  EXPECT_TRUE(messenger.send_called());
135  ASSERT_NE(messenger.last_reply_handler(), nullptr);
136 
137  // Call the underlying reply handler to ensure it's processed correctly.
138  EncodableValue reply_value(reply);
139  std::unique_ptr<std::vector<uint8_t>> encoded_reply =
141  messenger.last_reply_handler()(encoded_reply->data(), encoded_reply->size());
142  EXPECT_TRUE(received_reply);
143 }
144 
145 TEST(MethodChannelTest, InvokeNotImplemented) {
146  TestBinaryMessenger messenger;
147  const std::string channel_name("some_channel");
148  MethodChannel channel(&messenger, channel_name,
150 
151  bool received_not_implemented = false;
152  auto result_handler = std::make_unique<MethodResultFunctions<>>(
153  nullptr, nullptr,
154  [&received_not_implemented]() { received_not_implemented = true; });
155 
156  channel.InvokeMethod("foo", nullptr, std::move(result_handler));
157  EXPECT_EQ(messenger.send_called(), true);
158  ASSERT_NE(messenger.last_reply_handler(), nullptr);
159 
160  // Call the underlying reply handler to ensure it's reported as unimplemented.
161  messenger.last_reply_handler()(nullptr, 0);
162  EXPECT_TRUE(received_not_implemented);
163 }
164 
165 // Tests that calling Resize generates the binary message expected by the Dart
166 // implementation.
167 TEST(MethodChannelTest, Resize) {
168  TestBinaryMessenger messenger;
169  const std::string channel_name("flutter/test");
170  MethodChannel channel(&messenger, channel_name,
172 
173  channel.Resize(3);
174 
175  // Because the Dart implementation for the control channel implements its own
176  // custom deserialization logic, this test compares the generated bytes array
177  // to the expected one (for instance, the deserialization logic expects the
178  // size parameter of the resize method call to be an uint32).
179  //
180  // The expected content was created from the following Dart code:
181  // MethodCall call = MethodCall('resize', ['flutter/test',3]);
182  // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
183  const int expected_message_size = 29;
184 
185  EXPECT_EQ(messenger.send_called(), true);
186  EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
187  expected_message_size);
188 
189  int expected[expected_message_size] = {
190  7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117,
191  116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0};
192  for (int i = 0; i < expected_message_size; i++) {
193  EXPECT_EQ(messenger.last_message()[i], expected[i]);
194  }
195 }
196 
197 // Tests that calling SetWarnsOnOverflow generates the binary message expected
198 // by the Dart implementation.
199 TEST(MethodChannelTest, SetWarnsOnOverflow) {
200  TestBinaryMessenger messenger;
201 
202  const std::string channel_name("flutter/test");
203  MethodChannel channel(&messenger, channel_name,
205 
206  channel.SetWarnsOnOverflow(false);
207 
208  // The expected content was created from the following Dart code:
209  // MethodCall call = MethodCall('overflow',['flutter/test', true]);
210  // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
211  const int expected_message_size = 27;
212 
213  EXPECT_EQ(messenger.send_called(), true);
214  EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
215  expected_message_size);
216 
217  int expected[expected_message_size] = {
218  7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
219  102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
220  for (int i = 0; i < expected_message_size; i++) {
221  EXPECT_EQ(messenger.last_message()[i], expected[i]);
222  }
223 }
224 
225 } // namespace flutter
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58
flutter::MethodChannel
Definition: method_channel.h:34
method_result_functions.h
flutter::StandardMethodCodec
Definition: standard_method_codec.h:18
flutter::MethodChannel::InvokeMethod
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T >> result=nullptr)
Definition: method_channel.h:53
standard_method_codec.h
binary_messenger.h
flutter::MethodChannel::SetMethodCallHandler
void SetMethodCallHandler(MethodCallHandler< T > handler) const
Definition: method_channel.h:99
flutter::MethodCall
Definition: method_call.h:18
SetMessageHandler
static FlutterBinaryMessengerConnection SetMessageHandler(NSObject< FlutterBinaryMessenger > *messenger, NSString *name, FlutterBinaryMessageHandler handler, NSObject< FlutterTaskQueue > *taskQueue)
Definition: FlutterChannels.mm:50
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:17
flutter::MethodCodec::EncodeSuccessEnvelope
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
Definition: method_codec.h:55
flutter::MethodCodec::EncodeMethodCall
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
Definition: method_codec.h:48
flutter
Definition: AccessibilityBridgeMac.h:16
flutter::MethodChannel::SetWarnsOnOverflow
void SetWarnsOnOverflow(bool warns)
Definition: method_channel.h:139
flutter::MethodChannel::Resize
void Resize(int new_size)
Definition: method_channel.h:130
flutter::EncodableValue
Definition: encodable_value.h:165
SetWarnsOnOverflow
static void SetWarnsOnOverflow(NSObject< FlutterBinaryMessenger > *binaryMessenger, NSString *channel, BOOL warns)
Definition: FlutterChannels.mm:39
method_channel.h
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:24
flutter::StandardMethodCodec::GetInstance
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:340