1#include <gtest/gtest.h>
5#include <google/protobuf/util/time_util.h>
7#include <userver/proto-structs/any.hpp>
8#include <userver/proto-structs/io/std/chrono/duration_conv.hpp>
9#include <userver/utest/assert_macros.hpp>
11#include "messages.pb.h"
14USERVER_NAMESPACE_BEGIN
16namespace proto_structs::tests {
20 google::protobuf::Any pbuf_any;
22 messages::Simple original;
23 original.set_f1(1001);
25 ASSERT_TRUE(pbuf_any.PackFrom(original));
26 EXPECT_TRUE(any_default.GetProtobufAny().type_url().empty());
27 EXPECT_TRUE(std::move(any_default).GetProtobufAny().value().empty());
29 Any any = Any{pbuf_any};
32 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
33 EXPECT_EQ(msg.f1(), original.f1());
39 ASSERT_TRUE(std::move(any_copy).GetProtobufAny().UnpackTo(&msg));
40 EXPECT_EQ(msg.f1(), original.f1());
45 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
46 EXPECT_EQ(msg.f1(), original.f1());
48 Any any_move(std::move(any_copy));
50 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
51 EXPECT_EQ(msg.f1(), original.f1());
54 any_copy = std::move(any_move);
56 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
57 EXPECT_EQ(msg.f1(), original.f1());
61 structs::
Simple obj{.f1 = 1001};
64 EXPECT_TRUE(any.Is<structs::
Simple>());
65 EXPECT_TRUE(any.Is<messages::Simple>());
69 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
70 EXPECT_EQ(obj.f1, msg.f1());
76 EXPECT_FALSE(any.Is<structs::
Simple>());
77 EXPECT_FALSE(any.Is<messages::Simple>());
78 UASSERT_NO_THROW(any = obj);
79 EXPECT_TRUE(any.Is<structs::
Simple>());
80 EXPECT_TRUE(any.Is<messages::Simple>());
81 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
82 EXPECT_EQ(obj.f1, msg.f1());
88 EXPECT_FALSE(any.Is<structs::
Simple>());
89 EXPECT_FALSE(any.Is<messages::Simple>());
90 UASSERT_NO_THROW(any.Pack(structs::
Simple{obj}));
91 EXPECT_TRUE(any.Is<structs::
Simple>());
92 EXPECT_TRUE(any.Is<messages::Simple>());
93 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
94 EXPECT_EQ(obj.f1, msg.f1());
100 EXPECT_FALSE(any.Is<structs::
Simple>());
101 EXPECT_FALSE(any.Is<messages::Simple>());
102 UASSERT_NO_THROW(any.Pack(msg));
103 EXPECT_TRUE(any.Is<structs::
Simple>());
104 EXPECT_TRUE(any.Is<messages::Simple>());
108 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
109 EXPECT_EQ(obj.f1, msg.f1());
111 UASSERT_NO_THROW(any.Pack(std::chrono::nanoseconds(-123'456'789'987'654'321LL)));
112 EXPECT_TRUE(any.Is<std::chrono::milliseconds>());
113 EXPECT_TRUE(any.Is<::google::protobuf::Duration>());
115 ::google::protobuf::Duration duration;
117 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&duration));
118 EXPECT_EQ(::google::protobuf::util::TimeUtil::DurationToNanoseconds(duration), -123'456'789'987'654'321LL);
121TEST(AnyTest, Unpack) {
122 structs::
Simple obj{.f1 = 1001};
125 UASSERT_NO_THROW(any.Pack(obj));
126 ASSERT_TRUE(any.Is<structs::
Simple>());
127 EXPECT_EQ(any.Unpack<structs::
Simple>().f1, obj.f1);
128 ASSERT_TRUE(any.Is<messages::Simple>());
129 EXPECT_EQ(any.Unpack<messages::Simple>().f1(), obj.f1);
131 UEXPECT_THROW_MSG(
static_cast<
void>(any.Unpack<structs::Empty>()), AnyUnpackError,
"'messages.Empty'");
134 messages::Simple msg;
137 EXPECT_FALSE(any.Is<structs::
Simple>());
138 EXPECT_FALSE(any.Is<messages::Simple>());
139 UASSERT_NO_THROW(any.Pack(msg));
140 ASSERT_TRUE(any.Is<structs::
Simple>());
141 EXPECT_EQ(any.Unpack<structs::
Simple>().f1, msg.f1());
142 ASSERT_TRUE(any.Is<messages::Simple>());
143 EXPECT_EQ(any.Unpack<messages::Simple>().f1(), msg.f1());
145 auto duration = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(123'456'789'987'654'321LL);
147 UASSERT_NO_THROW(any.Pack(std::chrono::nanoseconds(123'456'789'987'654'321LL)));
148 ASSERT_TRUE(any.Is<std::chrono::seconds>());
149 EXPECT_EQ(any.Unpack<std::chrono::nanoseconds>(), std::chrono::nanoseconds(123'456'789'987'654'321LL));
150 ASSERT_TRUE(any.Is<::google::protobuf::Duration>());
151 EXPECT_EQ(any.Unpack<::google::protobuf::Duration>(), duration);