1#include <gtest/gtest.h>
9#include <google/protobuf/dynamic_message.h>
11#include <userver/formats/json/serialize.hpp>
12#include <userver/protobuf/json/convert.hpp>
13#include <userver/utest/assert_macros.hpp>
17USERVER_NAMESPACE_BEGIN
22T GetWrappedValue(
const ::google::protobuf::Message& msg) {
23 const auto reflection = msg.GetReflection();
24 const auto value_desc = msg.GetDescriptor()->FindFieldByName(
"value");
27 throw std::runtime_error(
"Field 'value' is not found in wrapper message");
30 if constexpr (std::is_same_v<T,
double>) {
31 return reflection->GetDouble(msg, value_desc);
32 }
else if constexpr (std::is_same_v<T,
float>) {
33 return reflection->GetFloat(msg, value_desc);
34 }
else if constexpr (std::is_same_v<T, std::int64_t>) {
35 return reflection->GetInt64(msg, value_desc);
36 }
else if constexpr (std::is_same_v<T, std::uint64_t>) {
37 return reflection->GetUInt64(msg, value_desc);
38 }
else if constexpr (std::is_same_v<T, std::int32_t>) {
39 return reflection->GetInt32(msg, value_desc);
40 }
else if constexpr (std::is_same_v<T, std::uint32_t>) {
41 return reflection->GetUInt32(msg, value_desc);
42 }
else if constexpr (std::is_same_v<T,
bool>) {
43 return reflection->GetBool(msg, value_desc);
44 }
else if constexpr (std::is_same_v<T, std::string>) {
45 return reflection->GetString(msg, value_desc);
47 static_assert(
sizeof(T) &&
false,
"unexpected type");
51struct WrapperFromJsonSuccessTestParam {
52 std::string input = {};
54 ReadOptions options = {};
57struct WrapperFromJsonFailureTestParam {
58 std::string input = {};
59 ReadErrorCode expected_errc = {};
60 std::string expected_path = {};
61 ReadOptions options = {};
67 bool skip_native_check =
false;
70void PrintTo(
const WrapperFromJsonFailureTestParam& param, std::ostream* os) {
71 *os << fmt::format(
"{{ input = '{}' }}", param.input);
74class WrapperFromJsonSuccessTest :
public ::testing::TestWithParam<WrapperFromJsonSuccessTestParam> {};
75class WrapperFromJsonFailureTest :
public ::testing::TestWithParam<WrapperFromJsonFailureTestParam> {};
77INSTANTIATE_TEST_SUITE_P(
79 WrapperFromJsonSuccessTest,
81 WrapperFromJsonSuccessTestParam{R"({})", WrapperMessageData{}},
82 WrapperFromJsonSuccessTestParam{
84 "field1":null,
85 "field2":null,
86 "field3":null,
87 "field4":null,
88 "field5":null,
89 "field6":null,
90 "field7":null,
91 "field8":null,
92 "field9":null
93 })",
96 WrapperFromJsonSuccessTestParam{
98 "field1":0,
99 "field2":0,
100 "field3":"0",
101 "field4":"0",
102 "field5":0,
103 "field6":0,
104 "field7":false,
105 "field8":"",
106 "field9":""
107 })",
108 WrapperMessageData{0, 0, 0, 0, 0, 0,
false,
"",
""},
110 WrapperFromJsonSuccessTestParam{
113 "field1":1.5,
114 "field2":1.5,
115 "field3":"-123",
116 "field4":"123",
117 "field5":-321,
118 "field6":321,
119 "field7":true,
120 "field8":"hello",
121 "field9":"d29ybGQ="
122 })",
123 WrapperMessageData{1.5, 1.5, -123, 123, -321, 321,
true,
"hello",
"world"},
125 WrapperFromJsonSuccessTestParam{
128 "field3":"-123",
129 "field5":-321,
130 "field7":true,
131 "field9":"d29ybGQ="
132 })",
148INSTANTIATE_TEST_SUITE_P(
150 WrapperFromJsonFailureTest,
152 WrapperFromJsonFailureTestParam{R"({"field1":[]})", ReadErrorCode::kInvalidType,
"field1"},
153 WrapperFromJsonFailureTestParam{R"({"field2":{}})", ReadErrorCode::kInvalidType,
"field2", {},
true},
154 WrapperFromJsonFailureTestParam{R"({"field3":true})", ReadErrorCode::kInvalidType,
"field3"},
155 WrapperFromJsonFailureTestParam{R"({"field4":"hello"})", ReadErrorCode::kInvalidValue,
"field4"},
156 WrapperFromJsonFailureTestParam{R"({"field5":1.5})", ReadErrorCode::kInvalidValue,
"field5"}
160TEST_P(WrapperFromJsonSuccessTest, Test) {
161 const auto& param = GetParam();
163 proto_json::messages::WrapperMessage message, expected_message, sample_message;
164 formats::json::Value input = PrepareJsonTestData(param.input);
165 expected_message = PrepareTestData(param.expected_message);
167 message.mutable_field1()->set_value(100001);
168 message.mutable_field2()->set_value(200002);
169 message.mutable_field3()->set_value(300003);
170 message.mutable_field4()->set_value(400004);
171 message.mutable_field5()->set_value(500005);
172 message.mutable_field6()->set_value(600006);
173 message.mutable_field7()->set_value(
true);
174 message.mutable_field8()->set_value(
"dump1");
175 message.mutable_field9()->set_value(
"dump2");
177 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::WrapperMessage>(input, param.options)));
178 UASSERT_NO_THROW(InitSampleMessage(param.input, param.options, sample_message));
180 CheckMessageEqual(message, sample_message);
181 CheckMessageEqual(message, expected_message);
184TEST_P(WrapperFromJsonFailureTest, Test) {
185 const auto& param = GetParam();
187 proto_json::messages::WrapperMessage sample_message;
188 formats::json::Value input = PrepareJsonTestData(param.input);
191 (
void)JsonToMessage<proto_json::messages::WrapperMessage>(input, param.options),
196 if (!param.skip_native_check) {
197 UEXPECT_THROW(InitSampleMessage(param.input, param.options, sample_message), SampleError);
202class WrapperFromJsonAdditionalTest :
public ::testing::Test {
207using WrapperTypes = ::testing::Types<
218TYPED_TEST_SUITE(WrapperFromJsonAdditionalTest, WrapperTypes);
220TYPED_TEST(WrapperFromJsonAdditionalTest, InlinedNonNull) {
221 using Param =
typename TestFixture::Param;
222 using Message =
typename Param::Message;
224 const auto json = formats::json::FromString(Param::kJson);
225 Message message, sample;
227 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
228 UASSERT_NO_THROW(InitSampleMessage(Param::kJson, {}, sample));
229 EXPECT_EQ(message.value(), sample.value());
230 EXPECT_EQ(message.value(), Param::kValue);
233TYPED_TEST(WrapperFromJsonAdditionalTest, InlinedNull) {
234 using Param =
typename TestFixture::Param;
235 using Message =
typename Param::Message;
236 using Value = std::remove_const_t<
decltype(Param::kValue)>;
238 const auto json = formats::json::FromString(
"null");
239 Message message, sample;
241 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
242 UASSERT_NO_THROW(InitSampleMessage(
"null", {}, sample));
243 EXPECT_EQ(message.value(), sample.value());
244 EXPECT_EQ(message.value(), Value{});
247TYPED_TEST(WrapperFromJsonAdditionalTest, DynamicMessage) {
248 using Param =
typename TestFixture::Param;
249 using Message =
typename Param::Message;
251 const auto json = formats::json::FromString(Param::kJson);
252 ::google::protobuf::DynamicMessageFactory factory;
255 std::unique_ptr<::google::protobuf::Message> message(factory.GetPrototype(Message::descriptor())->New());
257 UASSERT_NO_THROW(JsonToMessage(json, {}, *message));
258 EXPECT_EQ(GetWrappedValue<WrappedType<Param>>(*message), Param::kValue);