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
21struct DurationFromJsonSuccessTestParam {
22 std::string input = {};
24 ReadOptions options = {};
27struct DurationFromJsonFailureTestParam {
28 std::string input = {};
29 ReadErrorCode expected_errc = {};
30 std::string expected_path = {};
31 ReadOptions 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":[]})", ReadErrorCode::kInvalidType,
"field1"},
82 DurationFromJsonFailureTestParam{R"({"field1":{}})", ReadErrorCode::kInvalidType,
"field1", {},
true},
83 DurationFromJsonFailureTestParam{R"({"field1":true})", ReadErrorCode::kInvalidType,
"field1"},
84 DurationFromJsonFailureTestParam{R"({"field1":1})", ReadErrorCode::kInvalidType,
"field1"},
85 DurationFromJsonFailureTestParam{R"({"field1":""})", ReadErrorCode::kInvalidValue,
"field1"},
86 DurationFromJsonFailureTestParam{R"({"field1":"abc"})", ReadErrorCode::kInvalidValue,
"field1"},
87 DurationFromJsonFailureTestParam{R"({"field1":"0"})", ReadErrorCode::kInvalidValue,
"field1"},
88 DurationFromJsonFailureTestParam{R"({"field1":"0.-0s"})", ReadErrorCode::kInvalidValue,
"field1"},
89 DurationFromJsonFailureTestParam{R"({"field1":"0ss"})", ReadErrorCode::kInvalidValue,
"field1"},
90 DurationFromJsonFailureTestParam{R"({"field1":"123-s"})", ReadErrorCode::kInvalidValue,
"field1"},
91 DurationFromJsonFailureTestParam{R"({"field1":"-123.-1s"})", ReadErrorCode::kInvalidValue,
"field1"},
92 DurationFromJsonFailureTestParam{R"({"field1":"315576000001.0s"})", ReadErrorCode::kInvalidValue,
"field1"},
93 DurationFromJsonFailureTestParam{R"({"field1":"-315576000001.0s"})", ReadErrorCode::kInvalidValue,
"field1"},
94 DurationFromJsonFailureTestParam{R"({"field1":"0.1000000000s"})", ReadErrorCode::kInvalidValue,
"field1"},
95 DurationFromJsonFailureTestParam{R"({"field1":"-0.1000000000s"})", ReadErrorCode::kInvalidValue,
"field1"},
96 DurationFromJsonFailureTestParam{R"({"field1":"1..1s"})", ReadErrorCode::kInvalidValue,
"field1"},
97 DurationFromJsonFailureTestParam{R"({"field1":".1s"})", ReadErrorCode::kInvalidValue,
"field1"},
98 DurationFromJsonFailureTestParam{R"({"field1":"1.1.s"})", ReadErrorCode::kInvalidValue,
"field1"}
102TEST_P(DurationFromJsonSuccessTest, Test) {
103 const auto& param = GetParam();
105 proto_json::messages::DurationMessage message, expected_message, sample_message;
106 formats::json::Value input = PrepareJsonTestData(param.input);
107 expected_message = PrepareTestData(param.expected_message);
109 message.mutable_field1()->set_seconds(100001);
111 UASSERT_NO_THROW((message = JsonToMessage<proto_json::messages::DurationMessage>(input, param.options)));
112 UASSERT_NO_THROW(InitSampleMessage(param.input, param.options, sample_message));
114 CheckMessageEqual(message, sample_message);
115 CheckMessageEqual(message, expected_message);
118TEST_P(DurationFromJsonFailureTest, Test) {
119 const auto& param = GetParam();
121 proto_json::messages::DurationMessage sample_message;
122 formats::json::Value input = PrepareJsonTestData(param.input);
125 (
void)JsonToMessage<proto_json::messages::DurationMessage>(input, param.options),
130 if (!param.skip_native_check) {
131 UEXPECT_THROW(InitSampleMessage(param.input, param.options, sample_message), SampleError);
135TEST(DurationFromJsonAdditionalTest, InlinedNonNull) {
136 using Message = ::google::protobuf::Duration;
138 const char* json_str =
"\"123.987654321s\"";
139 const auto json = formats::json::FromString(json_str);
140 Message message, sample;
142 message.set_seconds(100001);
144 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
145 UASSERT_NO_THROW(InitSampleMessage(json_str, {}, sample));
147 EXPECT_EQ(message.seconds(), 123);
148 EXPECT_EQ(message.nanos(), 987654321);
149 CheckMessageEqual(message, sample);
152TEST(DurationFromJsonAdditionalTest, InlinedNull) {
153 using Message = ::google::protobuf::Duration;
155 const auto json = formats::json::FromString(
"null");
156 Message message, sample;
158 message.set_seconds(100001);
160 UASSERT_NO_THROW((message = JsonToMessage<Message>(json)));
161 UASSERT_NO_THROW(InitSampleMessage(
"null", {}, sample));
163 EXPECT_EQ(message.seconds(), 0);
164 EXPECT_EQ(message.nanos(), 0);
165 CheckMessageEqual(message, sample);
168TEST(DurationFromJsonAdditionalTest, DynamicMessage) {
169 using Message = ::google::protobuf::Duration;
171 const char* json_str =
"\"123.000000987s\"";
172 const auto json = formats::json::FromString(json_str);
173 ::google::protobuf::DynamicMessageFactory factory;
176 std::unique_ptr<::google::protobuf::Message> message(factory.GetPrototype(Message::descriptor())->New());
178 UASSERT_NO_THROW(JsonToMessage(json, {}, *message));
180 const auto reflection = message->GetReflection();
181 const auto seconds_desc = message->GetDescriptor()->FindFieldByName(
"seconds");
182 const auto nanos_desc = message->GetDescriptor()->FindFieldByName(
"nanos");
184 EXPECT_EQ(reflection->GetInt64(*message, seconds_desc), 123);
185 EXPECT_EQ(reflection->GetInt32(*message, nanos_desc), 987);