1#include <gtest/gtest.h>
9#include <google/protobuf/dynamic_message.h>
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 {
21using namespace std::chrono_literals;
23constexpr auto kTestSeconds = 1s + 1min + 1h + 24h + (31 * 24h) + (365 * 24h);
25struct TimestampToJsonSuccessTestParam {
27 std::string expected_json = {};
31struct TimestampToJsonFailureTestParam {
34 std::string expected_path = {};
38 bool skip_native_check =
false;
41void PrintTo(
const TimestampToJsonSuccessTestParam& param, std::ostream* os) {
42 *os << fmt::format(
"{{ input = {{.seconds={}, .nanos={}}} }}", param.input.seconds, param.input.nanos);
45void PrintTo(
const TimestampToJsonFailureTestParam& param, std::ostream* os) {
46 *os << fmt::format(
"{{ input = {{.seconds={}, .nanos={}}} }}", param.input.seconds, param.input.nanos);
49class TimestampToJsonSuccessTest :
public ::testing::TestWithParam<TimestampToJsonSuccessTestParam> {};
50class TimestampToJsonFailureTest :
public ::testing::TestWithParam<TimestampToJsonFailureTestParam> {};
52INSTANTIATE_TEST_SUITE_P(
54 TimestampToJsonSuccessTest,
57 TimestampToJsonSuccessTestParam{
TimestampMessageData{0, 0}, R"({"field1": "1970-01-01T00:00:00Z"})"},
58 TimestampToJsonSuccessTestParam{
60 R"({"field1": "1971-02-02T01:01:01.123456789Z"})"
62 TimestampToJsonSuccessTestParam{
64 R"({"field1": "1968-11-29T22:58:59.987654321Z"})"
66 TimestampToJsonSuccessTestParam{
68 R"({"field1": "9999-12-31T23:59:59.999999999Z"})"
70 TimestampToJsonSuccessTestParam{
72 R"({"field1": "0001-01-01T00:00:00Z"})"
74 TimestampToJsonSuccessTestParam{
76 R"({"field1": "1970-01-01T00:00:00.123456780Z"})"
78 TimestampToJsonSuccessTestParam{
80 R"({"field1": "1970-01-01T00:00:00.123456Z"})"
82 TimestampToJsonSuccessTestParam{
84 R"({"field1": "1970-01-01T00:00:00.123400Z"})"
86 TimestampToJsonSuccessTestParam{
88 R"({"field1": "1970-01-01T00:00:00.100Z"})"
90 TimestampToJsonSuccessTestParam{
92 R"({"field1": "2016-02-29T00:00:00.123450Z"})"
94 TimestampToJsonSuccessTestParam{
TimestampMessageData{0, 9}, R"({"field1": "1970-01-01T00:00:00.000000009Z"})"}
98#if GOOGLE_PROTOBUF_VERSION
>= 6033000
99constexpr bool kNanosSkipNativeCheck =
false;
101constexpr bool kNanosSkipNativeCheck =
true;
104INSTANTIATE_TEST_SUITE_P(
106 TimestampToJsonFailureTest,
108 TimestampToJsonFailureTestParam{
113 TimestampToJsonFailureTestParam{
118 TimestampToJsonFailureTestParam{
123 kNanosSkipNativeCheck
125 TimestampToJsonFailureTestParam{
130 kNanosSkipNativeCheck
135TEST_P(TimestampToJsonSuccessTest, Test) {
136 const auto& param = GetParam();
138 auto input = PrepareTestData(param.input);
144 UASSERT_NO_THROW((expected_json = PrepareJsonTestData(param.expected_json)));
147 EXPECT_EQ(json, expected_json);
148 EXPECT_EQ(expected_json, sample_json);
151TEST_P(TimestampToJsonFailureTest, Test) {
152 const auto& param = GetParam();
153 auto input = PrepareTestData(param.input);
155 EXPECT_PRINT_ERROR((
void)MessageToJson(input, param.options), param.expected_errc, param.expected_path);
157 if (!param.skip_native_check) {
162TEST(TimestampToJsonAdditionalTest, InlinedNonNull) {
164 auto message = PrepareTestData(data);
171 EXPECT_EQ(json, sample);
172 EXPECT_EQ(json.As<std::string>(),
"1970-01-01T00:02:03.000000321Z");
175TEST(TimestampToJsonAdditionalTest, InlinedNull) {
176 proto_json::messages::TimestampMessage message;
183 EXPECT_EQ(json, sample);
184 EXPECT_EQ(json.As<std::string>(),
"1970-01-01T00:00:00Z");
187TEST(TimestampToJsonAdditionalTest, DynamicMessage) {
188 using Message = ::google::protobuf::Timestamp;
189 ::google::protobuf::DynamicMessageFactory factory;
192 std::unique_ptr<::google::protobuf::Message> message(factory.GetPrototype(Message::descriptor())->New());
193 const auto reflection = message->GetReflection();
194 const auto seconds_desc = message->GetDescriptor()->FindFieldByName(
"seconds");
195 const auto nanos_desc = message->GetDescriptor()->FindFieldByName(
"nanos");
197 reflection->SetInt64(message.get(), seconds_desc, 1456704000);
198 reflection->SetInt32(message.get(), nanos_desc, 123450000);
204 EXPECT_EQ(json.As<std::string>(),
"2016-02-29T00:00:00.123450Z");