Flutter iOS Embedder
json_method_codec_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 
8 #include "gtest/gtest.h"
9 
10 namespace flutter {
11 
12 namespace {
13 
14 // Returns true if the given method calls have the same method name, and their
15 // arguments have equivalent values.
16 bool MethodCallsAreEqual(const MethodCall<rapidjson::Document>& a,
17  const MethodCall<rapidjson::Document>& b) {
18  if (a.method_name() != b.method_name()) {
19  return false;
20  }
21  // Treat nullptr and Null as equivalent.
22  if ((!a.arguments() || a.arguments()->IsNull()) &&
23  (!b.arguments() || b.arguments()->IsNull())) {
24  return true;
25  }
26  return *a.arguments() == *b.arguments();
27 }
28 
29 } // namespace
30 
31 TEST(JsonMethodCodec, HandlesMethodCallsWithNullArguments) {
33  MethodCall<rapidjson::Document> call("hello", nullptr);
34  auto encoded = codec.EncodeMethodCall(call);
35  ASSERT_TRUE(encoded);
36  std::unique_ptr<MethodCall<rapidjson::Document>> decoded =
37  codec.DecodeMethodCall(*encoded);
38  ASSERT_TRUE(decoded);
39  EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
40 }
41 
42 TEST(JsonMethodCodec, HandlesMethodCallsWithArgument) {
44 
45  auto arguments = std::make_unique<rapidjson::Document>(rapidjson::kArrayType);
46  auto& allocator = arguments->GetAllocator();
47  arguments->PushBack(42, allocator);
48  arguments->PushBack("world", allocator);
49  MethodCall<rapidjson::Document> call("hello", std::move(arguments));
50  auto encoded = codec.EncodeMethodCall(call);
51  ASSERT_TRUE(encoded);
52  std::unique_ptr<MethodCall<rapidjson::Document>> decoded =
53  codec.DecodeMethodCall(*encoded);
54  ASSERT_TRUE(decoded);
55  EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
56 }
57 
58 TEST(JsonMethodCodec, HandlesSuccessEnvelopesWithNullResult) {
60  auto encoded = codec.EncodeSuccessEnvelope();
61  ASSERT_TRUE(encoded);
62  std::vector<uint8_t> bytes = {'[', 'n', 'u', 'l', 'l', ']'};
63  EXPECT_EQ(*encoded, bytes);
64 
65  bool decoded_successfully = false;
67  [&decoded_successfully](const rapidjson::Document* result) {
68  decoded_successfully = true;
69  EXPECT_EQ(result, nullptr);
70  },
71  nullptr, nullptr);
72  codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
73  &result_handler);
74  EXPECT_TRUE(decoded_successfully);
75 }
76 
77 TEST(JsonMethodCodec, HandlesSuccessEnvelopesWithResult) {
79  rapidjson::Document result;
80  result.SetInt(42);
81  auto encoded = codec.EncodeSuccessEnvelope(&result);
82  ASSERT_TRUE(encoded);
83  std::vector<uint8_t> bytes = {'[', '4', '2', ']'};
84  EXPECT_EQ(*encoded, bytes);
85 
86  bool decoded_successfully = false;
88  [&decoded_successfully](const rapidjson::Document* result) {
89  decoded_successfully = true;
90  EXPECT_EQ(result->GetInt(), 42);
91  },
92  nullptr, nullptr);
93  codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
94  &result_handler);
95  EXPECT_TRUE(decoded_successfully);
96 }
97 
98 TEST(JsonMethodCodec, HandlesErrorEnvelopesWithNulls) {
100  auto encoded = codec.EncodeErrorEnvelope("errorCode");
101  ASSERT_TRUE(encoded);
102  std::vector<uint8_t> bytes = {
103  '[', '"', 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e',
104  '"', ',', '"', '"', ',', 'n', 'u', 'l', 'l', ']',
105  };
106  EXPECT_EQ(*encoded, bytes);
107 
108  bool decoded_successfully = false;
110  nullptr,
111  [&decoded_successfully](const std::string& code,
112  const std::string& message,
113  const rapidjson::Document* details) {
114  decoded_successfully = true;
115  EXPECT_EQ(code, "errorCode");
116  EXPECT_EQ(message, "");
117  EXPECT_EQ(details, nullptr);
118  },
119  nullptr);
120  codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
121  &result_handler);
122  EXPECT_TRUE(decoded_successfully);
123 }
124 
125 TEST(JsonMethodCodec, HandlesErrorEnvelopesWithDetails) {
127  // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
128  rapidjson::Document details(rapidjson::kArrayType);
129  auto& allocator = details.GetAllocator();
130  details.PushBack("a", allocator);
131  details.PushBack(42, allocator);
132  auto encoded =
133  codec.EncodeErrorEnvelope("errorCode", "something failed", &details);
134  ASSERT_NE(encoded.get(), nullptr);
135  std::vector<uint8_t> bytes = {
136  '[', '"', 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e', '"', ',', '"',
137  's', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', ' ', 'f', 'a', 'i', 'l',
138  'e', 'd', '"', ',', '[', '"', 'a', '"', ',', '4', '2', ']', ']',
139  };
140  EXPECT_EQ(*encoded, bytes);
141 
142  bool decoded_successfully = false;
144  nullptr,
145  [&decoded_successfully](const std::string& code,
146  const std::string& message,
147  const rapidjson::Document* details) {
148  decoded_successfully = true;
149  EXPECT_EQ(code, "errorCode");
150  EXPECT_EQ(message, "something failed");
151  EXPECT_TRUE(details->IsArray());
152  EXPECT_EQ(std::string((*details)[0].GetString()), "a");
153  EXPECT_EQ((*details)[1].GetInt(), 42);
154  },
155  nullptr);
156  codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
157  &result_handler);
158  EXPECT_TRUE(decoded_successfully);
159 }
160 
161 } // namespace flutter
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58
flutter::JsonMethodCodec
Definition: json_method_codec.h:16
method_result_functions.h
flutter::MethodCodec::EncodeErrorEnvelope
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelope(const std::string &error_code, const std::string &error_message="", const T *error_details=nullptr) const
Definition: method_codec.h:62
json_method_codec.h
flutter::JsonMethodCodec::GetInstance
static const JsonMethodCodec & GetInstance()
Definition: json_method_codec.cc:36
flutter::MethodCall
Definition: method_call.h:18
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: accessibility_bridge.h:28
flutter::MethodCodec::DecodeMethodCall
std::unique_ptr< MethodCall< T > > DecodeMethodCall(const uint8_t *message, size_t message_size) const
Definition: method_codec.h:32
flutter::MethodResultFunctions
Definition: method_result_functions.h:31
flutter::MethodCodec::DecodeAndProcessResponseEnvelope
bool DecodeAndProcessResponseEnvelope(const uint8_t *response, size_t response_size, MethodResult< T > *result) const
Definition: method_codec.h:75