1#include <gtest/gtest.h>
8#include <google/protobuf/dynamic_message.h>
10#include <userver/formats/json/serialize.hpp>
11#include <userver/protobuf/datetime.hpp>
12#include <userver/protobuf/json/convert.hpp>
13#include <userver/utest/assert_macros.hpp>
17USERVER_NAMESPACE_BEGIN
19namespace protobuf::json::tests {
21struct DurationFromJsonSuccessTestParam {
22 std::string input = {};
24 ParseOptions options = {};
27struct DurationFromJsonFailureTestParam {
28 std::string input = {};
29 ParseErrorCode expected_errc = {};
30 std::string expected_path = {};
31 ParseOptions options = {};
36 bool skip_native_check =
false;
39void PrintTo(
const DurationFromJsonSuccessTestParam& param, std::ostream* os) {
40 *os << fmt::format(
"{{ input = '{}' }}", param.input);
43void PrintTo(
const DurationFromJsonFailureTestParam& param, std::ostream* os) {
44 *os << fmt::format(
"{{ input = '{}' }}", param.input);
47class DurationFromJsonSuccessTest :
public ::testing::TestWithParam<DurationFromJsonSuccessTestParam> {};
48class DurationFromJsonFailureTest :
public ::testing::TestWithParam<DurationFromJsonFailureTestParam> {};
50INSTANTIATE_TEST_SUITE_P(
52 DurationFromJsonSuccessTest,
54 DurationFromJsonSuccessTestParam{R"({})", DurationMessageData{0, 0,
true}},
55 DurationFromJsonSuccessTestParam{R"({"field1":null})", DurationMessageData{0, 0,
true}},
56 DurationFromJsonSuccessTestParam{R"({"field1":"0s"})", DurationMessageData{0, 0}},
57 DurationFromJsonSuccessTestParam{R"({"field1":"0.0s"})", DurationMessageData{0, 0}},
58 DurationFromJsonSuccessTestParam{R"({"field1":"-0.0s"})", DurationMessageData{0, 0}},
59 DurationFromJsonSuccessTestParam{
60 R"({"field1":"315576000000.999999999s"})",
61 DurationMessageData{kMaxDurationSeconds, kMaxDurationNanos}
63 DurationFromJsonSuccessTestParam{
64 R"({"field1":"-315576000000.999999999s"})",
65 DurationMessageData{kMinDurationSeconds, kMinDurationNanos}
67 DurationFromJsonSuccessTestParam{R"({"field1":"123.987654321s"})", DurationMessageData{123, 987654321}},
68 DurationFromJsonSuccessTestParam{R"({"field1":"-123.98765432s"})", DurationMessageData{-123, -987654320}},
69 DurationFromJsonSuccessTestParam{R"({"field1":"123.9876543s"})", DurationMessageData{123, 987654300}},
70 DurationFromJsonSuccessTestParam{R"({"field1":"-123.987654s"})", DurationMessageData{-123, -987654000}},
71 DurationFromJsonSuccessTestParam{R"({"field1":"123.987654000s"})", DurationMessageData{123, 987654000}},
72 DurationFromJsonSuccessTestParam{R"({"field1":"-123.9s"})", DurationMessageData{-123, -900000000}},
73 DurationFromJsonSuccessTestParam{R"({"field1":"123.000000009s"})", DurationMessageData{123, 9}}
77INSTANTIATE_TEST_SUITE_P(
79 DurationFromJsonFailureTest,
81 DurationFromJsonFailureTestParam{R"({"field1":[]})", ParseErrorCode::kInvalidType,
"field1"},
82 DurationFromJsonFailureTestParam{R"({"field1":{}})", ParseErrorCode::kInvalidType,
"field1", {},
true},
83 DurationFromJsonFailureTestParam{R"({"field1":true})", ParseErrorCode::kInvalidType,
"field1"},
84 DurationFromJsonFailureTestParam{R"({"field1":1})", ParseErrorCode::kInvalidType,
"field1"},
85 DurationFromJsonFailureTestParam{R"({"field1":""})", ParseErrorCode::kInvalidValue,
"field1"},
86 DurationFromJsonFailureTestParam{R"({"field1":"abc"})", ParseErrorCode::kInvalidValue,
"field1"},
87 DurationFromJsonFailureTestParam{R"({"field1":"0"})", ParseErrorCode::kInvalidValue,
"field1"},
88 DurationFromJsonFailureTestParam{R"({"field1":"0.-0s"})", ParseErrorCode::kInvalidValue,
"field1"},
89 DurationFromJsonFailureTestParam{R"({"field1":"0ss"})", ParseErrorCode::kInvalidValue,
"field1"},
90 DurationFromJsonFailureTestParam{R"({"field1":"123-s"})", ParseErrorCode::kInvalidValue,
"field1"},
91 DurationFromJsonFailureTestParam{R"({"field1":"-123.-1s"})", ParseErrorCode::kInvalidValue,
"field1"},
92 DurationFromJsonFailureTestParam{R"({"field1":"315576000001.0s"})", ParseErrorCode::kInvalidValue,
"field1"},
93 DurationFromJsonFailureTestParam{R"({"field1":"-315576000001.0s"})", ParseErrorCode::kInvalidValue,
"field1"},
94 DurationFromJsonFailureTestParam{R"({"field1":"0.1000000000s"})", ParseErrorCode::kInvalidValue,
"field1"},
95 DurationFromJsonFailureTestParam{R"({"field1":"-0.1000000000s"})", ParseErrorCode::kInvalidValue,
"field1"},
96 DurationFromJsonFailureTestParam{R"({"field1":"1..1s"})", ParseErrorCode::kInvalidValue,
"field1"},
97 DurationFromJsonFailureTestParam{R"({"field1":".1s"})", ParseErrorCode::kInvalidValue,
"field1"},
98 DurationFromJsonFailureTestParam{R"({"field1":"1.1.s"})", ParseErrorCode::kInvalidValue,
"field1"}
102TEST_P(DurationFromJsonSuccessTest, Test) {
103 const auto& param = GetParam();
105 proto_json::messages::DurationMessage message;
106 proto_json::messages::DurationMessage expected_message;
107 proto_json::messages::DurationMessage sample_message;
108 formats::json::
Value input = PrepareJsonTestData(param.input);
109 expected_message = PrepareTestData(param.expected_message);
111 message.mutable_field1()->set_seconds(100001);
113 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::DurationMessage>(input, param.options)));
114 UASSERT_NO_THROW(InitSampleMessage(param.input, sample_message, param.options));
116 CheckMessageEqual(message, sample_message);
117 CheckMessageEqual(message, expected_message);
120TEST_P(DurationFromJsonFailureTest, Test) {
121 const auto& param = GetParam();
123 proto_json::messages::DurationMessage sample_message;
124 formats::json::
Value input = PrepareJsonTestData(param.input);
127 (
void)JsonToMessage<proto_json::messages::DurationMessage>(input, param.options),
132 if (!param.skip_native_check) {
133 UEXPECT_THROW(InitSampleMessage(param.input, sample_message, param.options), SampleError);
137TEST(DurationFromJsonAdditionalTest, InlinedNonNull) {
138 using Message = ::google::protobuf::Duration;
140 const char* json_str =
"\"123.987654321s\"";
145 message.set_seconds(100001);
147 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
148 UASSERT_NO_THROW(InitSampleMessage(json_str, sample));
150 EXPECT_EQ(message.seconds(), 123);
151 EXPECT_EQ(message.nanos(), 987654321);
152 CheckMessageEqual(message, sample);
155TEST(DurationFromJsonAdditionalTest, InlinedNull) {
156 using Message = ::google::protobuf::Duration;
162 message.set_seconds(100001);
164 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
165 UASSERT_NO_THROW(InitSampleMessage(
"null", sample));
167 EXPECT_EQ(message.seconds(), 0);
168 EXPECT_EQ(message.nanos(), 0);
169 CheckMessageEqual(message, sample);
172TEST(DurationFromJsonAdditionalTest, DynamicMessage) {
173 using Message = ::google::protobuf::Duration;
175 const char* json_str =
"\"123.000000987s\"";
177 ::google::protobuf::DynamicMessageFactory factory;
180 std::unique_ptr<::google::protobuf::Message> message(factory.GetPrototype(Message::descriptor())->New());
182 UASSERT_NO_THROW(JsonToMessage(json, *message));
184 const auto reflection = message->GetReflection();
185 const auto seconds_desc = message->GetDescriptor()->FindFieldByName(
"seconds");
186 const auto nanos_desc = message->GetDescriptor()->FindFieldByName(
"nanos");
188 EXPECT_EQ(reflection->GetInt64(*message, seconds_desc), 123);
189 EXPECT_EQ(reflection->GetInt32(*message, nanos_desc), 987);