1#include <gtest/gtest.h>
7#include <google/protobuf/dynamic_message.h>
9#include <userver/crypto/base64.hpp>
10#include <userver/protobuf/json/convert.hpp>
11#include <userver/utest/assert_macros.hpp>
12#include <userver/utils/from_string.hpp>
16USERVER_NAMESPACE_BEGIN
18namespace protobuf::json::tests {
21void SetWrappedValue(::google::protobuf::Message& msg, T value) {
22 const auto reflection = msg.GetReflection();
23 const auto value_desc = msg.GetDescriptor()->FindFieldByName(
"value");
26 throw std::runtime_error(
"Field 'value' is not found in wrapper message");
29 if constexpr (std::is_same_v<T,
double>) {
30 return reflection->SetDouble(&msg, value_desc, value);
31 }
else if constexpr (std::is_same_v<T,
float>) {
32 return reflection->SetFloat(&msg, value_desc, value);
33 }
else if constexpr (std::is_same_v<T, std::int64_t>) {
34 return reflection->SetInt64(&msg, value_desc, value);
35 }
else if constexpr (std::is_same_v<T, std::uint64_t>) {
36 return reflection->SetUInt64(&msg, value_desc, value);
37 }
else if constexpr (std::is_same_v<T, std::int32_t>) {
38 return reflection->SetInt32(&msg, value_desc, value);
39 }
else if constexpr (std::is_same_v<T, std::uint32_t>) {
40 return reflection->SetUInt32(&msg, value_desc, value);
41 }
else if constexpr (std::is_same_v<T,
bool>) {
42 return reflection->SetBool(&msg, value_desc, value);
43 }
else if constexpr (std::is_same_v<T, std::string_view>) {
44 return reflection->SetString(&msg, value_desc, {value.begin(), value.end()});
46 static_assert(
sizeof(T) &&
false,
"unexpected type");
50template <
typename TParam>
52 using Type = WrappedType<TParam>;
54 if constexpr (std::is_same_v<Type,
double>) {
55 return json.As<
double>();
56 }
else if constexpr (std::is_same_v<Type,
float>) {
57 return json.As<
float>();
58 }
else if constexpr (std::is_same_v<Type, std::int64_t> || std::is_same_v<Type, std::uint64_t>) {
59 return utils::FromString<Type>(json.As<std::string>());
60 }
else if constexpr (std::is_same_v<Type, std::int32_t>) {
61 return json.As<std::int32_t>();
62 }
else if constexpr (std::is_same_v<Type, std::uint32_t>) {
63 return json.As<std::uint32_t>();
64 }
else if constexpr (std::is_same_v<Type,
bool>) {
65 return json.As<
bool>();
66 }
else if constexpr (std::is_same_v<Type, std::string>) {
67 if constexpr (!std::is_same_v<TParam,
BytesValue>) {
68 return json.As<std::string>();
73 static_assert(
sizeof(TParam) &&
false,
"unexpected type");
77struct WrapperToJsonSuccessTestParam {
79 std::string expected_json = {};
80 PrintOptions options = {};
83class WrapperToJsonSuccessTest :
public ::testing::TestWithParam<WrapperToJsonSuccessTestParam> {};
85INSTANTIATE_TEST_SUITE_P(
87 WrapperToJsonSuccessTest,
89 WrapperToJsonSuccessTestParam{WrapperMessageData{}, R"({})"},
90 WrapperToJsonSuccessTestParam{
91 WrapperMessageData{0, 0, 0, 0, 0, 0,
false,
"",
""},
93 "field1":0,
94 "field2":0,
95 "field3":"0",
96 "field4":"0",
97 "field5":0,
98 "field6":0,
99 "field7":false,
100 "field8":"",
101 "field9":""
102 })"
104 WrapperToJsonSuccessTestParam{
106 WrapperMessageData{1.5, 1.5, -123, 123, -321, 321,
true,
"hello",
"world"},
108 "field1":1.5,
109 "field2":1.5,
110 "field3":"-123",
111 "field4":"123",
112 "field5":-321,
113 "field6":321,
114 "field7":true,
115 "field8":"hello",
116 "field9":"d29ybGQ="
117 })"
119 WrapperToJsonSuccessTestParam{
132 "field3":"-123",
133 "field5":-321,
134 "field7":true,
135 "field9":"d29ybGQ="
136 })"
141TEST_P(WrapperToJsonSuccessTest, Test) {
142 const auto& param = GetParam();
144 auto input = PrepareTestData(param.input);
147 UASSERT_NO_THROW((json = MessageToJson(input, param.options)));
148 UASSERT_NO_THROW((expected_json = PrepareJsonTestData(param.expected_json)));
149 UASSERT_NO_THROW((sample_json = CreateSampleJson(input, param.options)));
151 EXPECT_EQ(json, expected_json);
152 EXPECT_EQ(expected_json, sample_json);
156class WrapperToJsonAdditionalTest :
public ::testing::Test {
161using WrapperTypes = ::testing::Types<
172TYPED_TEST_SUITE(WrapperToJsonAdditionalTest, WrapperTypes);
174TYPED_TEST(WrapperToJsonAdditionalTest, InlinedNonNull) {
175 using Param =
typename TestFixture::Param;
176 using Message =
typename Param::Message;
180 SetWrappedValue(message, Param::kValue);
182 UASSERT_NO_THROW((json = MessageToJson(message, {})));
183 UASSERT_NO_THROW((sample = CreateSampleJson(message)));
184 EXPECT_EQ(json, sample);
185 EXPECT_EQ(GetJsonValue<Param>(json), Param::kValue);
188TYPED_TEST(WrapperToJsonAdditionalTest, InlinedNull) {
189 using Param =
typename TestFixture::Param;
190 using Message =
typename Param::Message;
195 UASSERT_NO_THROW((json = MessageToJson(message, {})));
196 UASSERT_NO_THROW((sample = CreateSampleJson(message)));
197 EXPECT_EQ(json, sample);
200TYPED_TEST(WrapperToJsonAdditionalTest, DynamicMessage) {
201 using Param =
typename TestFixture::Param;
202 using Message =
typename Param::Message;
204 ::google::protobuf::DynamicMessageFactory factory;
207 std::unique_ptr<::google::protobuf::Message> message(factory.GetPrototype(Message::descriptor())->New());
208 SetWrappedValue(*message, Param::kValue);
212 UASSERT_NO_THROW((json = MessageToJson(*message, {})));
213 EXPECT_EQ(GetJsonValue<Param>(json), Param::kValue);