mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
161 lines
5.9 KiB
C++
161 lines
5.9 KiB
C++
// 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.
|
|
|
|
#include "flutter/shell/platform/common/json_method_codec.h"
|
|
|
|
#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_result_functions.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace flutter {
|
|
|
|
namespace {
|
|
|
|
// Returns true if the given method calls have the same method name, and their
|
|
// arguments have equivalent values.
|
|
bool MethodCallsAreEqual(const MethodCall<rapidjson::Document>& a,
|
|
const MethodCall<rapidjson::Document>& b) {
|
|
if (a.method_name() != b.method_name()) {
|
|
return false;
|
|
}
|
|
// Treat nullptr and Null as equivalent.
|
|
if ((!a.arguments() || a.arguments()->IsNull()) &&
|
|
(!b.arguments() || b.arguments()->IsNull())) {
|
|
return true;
|
|
}
|
|
return *a.arguments() == *b.arguments();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST(JsonMethodCodec, HandlesMethodCallsWithNullArguments) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
MethodCall<rapidjson::Document> call("hello", nullptr);
|
|
auto encoded = codec.EncodeMethodCall(call);
|
|
ASSERT_TRUE(encoded);
|
|
std::unique_ptr<MethodCall<rapidjson::Document>> decoded =
|
|
codec.DecodeMethodCall(*encoded);
|
|
ASSERT_TRUE(decoded);
|
|
EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
|
|
}
|
|
|
|
TEST(JsonMethodCodec, HandlesMethodCallsWithArgument) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
|
|
auto arguments = std::make_unique<rapidjson::Document>(rapidjson::kArrayType);
|
|
auto& allocator = arguments->GetAllocator();
|
|
arguments->PushBack(42, allocator);
|
|
arguments->PushBack("world", allocator);
|
|
MethodCall<rapidjson::Document> call("hello", std::move(arguments));
|
|
auto encoded = codec.EncodeMethodCall(call);
|
|
ASSERT_TRUE(encoded);
|
|
std::unique_ptr<MethodCall<rapidjson::Document>> decoded =
|
|
codec.DecodeMethodCall(*encoded);
|
|
ASSERT_TRUE(decoded);
|
|
EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
|
|
}
|
|
|
|
TEST(JsonMethodCodec, HandlesSuccessEnvelopesWithNullResult) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
auto encoded = codec.EncodeSuccessEnvelope();
|
|
ASSERT_TRUE(encoded);
|
|
std::vector<uint8_t> bytes = {'[', 'n', 'u', 'l', 'l', ']'};
|
|
EXPECT_EQ(*encoded, bytes);
|
|
|
|
bool decoded_successfully = false;
|
|
MethodResultFunctions<rapidjson::Document> result_handler(
|
|
[&decoded_successfully](const rapidjson::Document* result) {
|
|
decoded_successfully = true;
|
|
EXPECT_EQ(result, nullptr);
|
|
},
|
|
nullptr, nullptr);
|
|
codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
|
|
&result_handler);
|
|
EXPECT_TRUE(decoded_successfully);
|
|
}
|
|
|
|
TEST(JsonMethodCodec, HandlesSuccessEnvelopesWithResult) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
rapidjson::Document result;
|
|
result.SetInt(42);
|
|
auto encoded = codec.EncodeSuccessEnvelope(&result);
|
|
ASSERT_TRUE(encoded);
|
|
std::vector<uint8_t> bytes = {'[', '4', '2', ']'};
|
|
EXPECT_EQ(*encoded, bytes);
|
|
|
|
bool decoded_successfully = false;
|
|
MethodResultFunctions<rapidjson::Document> result_handler(
|
|
[&decoded_successfully](const rapidjson::Document* result) {
|
|
decoded_successfully = true;
|
|
EXPECT_EQ(result->GetInt(), 42);
|
|
},
|
|
nullptr, nullptr);
|
|
codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
|
|
&result_handler);
|
|
EXPECT_TRUE(decoded_successfully);
|
|
}
|
|
|
|
TEST(JsonMethodCodec, HandlesErrorEnvelopesWithNulls) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
auto encoded = codec.EncodeErrorEnvelope("errorCode");
|
|
ASSERT_TRUE(encoded);
|
|
std::vector<uint8_t> bytes = {
|
|
'[', '"', 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e',
|
|
'"', ',', '"', '"', ',', 'n', 'u', 'l', 'l', ']',
|
|
};
|
|
EXPECT_EQ(*encoded, bytes);
|
|
|
|
bool decoded_successfully = false;
|
|
MethodResultFunctions<rapidjson::Document> result_handler(
|
|
nullptr,
|
|
[&decoded_successfully](const std::string& code,
|
|
const std::string& message,
|
|
const rapidjson::Document* details) {
|
|
decoded_successfully = true;
|
|
EXPECT_EQ(code, "errorCode");
|
|
EXPECT_EQ(message, "");
|
|
EXPECT_EQ(details, nullptr);
|
|
},
|
|
nullptr);
|
|
codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
|
|
&result_handler);
|
|
EXPECT_TRUE(decoded_successfully);
|
|
}
|
|
|
|
TEST(JsonMethodCodec, HandlesErrorEnvelopesWithDetails) {
|
|
const JsonMethodCodec& codec = JsonMethodCodec::GetInstance();
|
|
rapidjson::Document details(rapidjson::kArrayType);
|
|
auto& allocator = details.GetAllocator();
|
|
details.PushBack("a", allocator);
|
|
details.PushBack(42, allocator);
|
|
auto encoded =
|
|
codec.EncodeErrorEnvelope("errorCode", "something failed", &details);
|
|
ASSERT_NE(encoded.get(), nullptr);
|
|
std::vector<uint8_t> bytes = {
|
|
'[', '"', 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e', '"', ',', '"',
|
|
's', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', ' ', 'f', 'a', 'i', 'l',
|
|
'e', 'd', '"', ',', '[', '"', 'a', '"', ',', '4', '2', ']', ']',
|
|
};
|
|
EXPECT_EQ(*encoded, bytes);
|
|
|
|
bool decoded_successfully = false;
|
|
MethodResultFunctions<rapidjson::Document> result_handler(
|
|
nullptr,
|
|
[&decoded_successfully](const std::string& code,
|
|
const std::string& message,
|
|
const rapidjson::Document* details) {
|
|
decoded_successfully = true;
|
|
EXPECT_EQ(code, "errorCode");
|
|
EXPECT_EQ(message, "something failed");
|
|
EXPECT_TRUE(details->IsArray());
|
|
EXPECT_EQ(std::string((*details)[0].GetString()), "a");
|
|
EXPECT_EQ((*details)[1].GetInt(), 42);
|
|
},
|
|
nullptr);
|
|
codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
|
|
&result_handler);
|
|
EXPECT_TRUE(decoded_successfully);
|
|
}
|
|
|
|
} // namespace flutter
|