1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
6#include <google/protobuf/util/time_util.h>
8#include <userver/proto-structs/any.hpp>
9#include <userver/proto-structs/io/std/chrono/duration_conv.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 ASSERT_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 ASSERT_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 ASSERT_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 ASSERT_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 ASSERT_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 [&any]() {
static_cast<
void>(any.Unpack<structs::Empty>()); },
132 ::testing::ThrowsMessage<AnyUnpackError>(::testing::HasSubstr(
"'messages.Empty'"))
136 messages::Simple msg;
139 EXPECT_FALSE(any.Is<structs::
Simple>());
140 EXPECT_FALSE(any.Is<messages::Simple>());
141 ASSERT_NO_THROW(any.Pack(msg));
142 ASSERT_TRUE(any.Is<structs::
Simple>());
143 EXPECT_EQ(any.Unpack<structs::
Simple>().f1, msg.f1());
144 ASSERT_TRUE(any.Is<messages::Simple>());
145 EXPECT_EQ(any.Unpack<messages::Simple>().f1(), msg.f1());
147 auto duration = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(123'456'789'987'654'321LL);
149 ASSERT_NO_THROW(any.Pack(std::chrono::nanoseconds(123'456'789'987'654'321LL)));
150 ASSERT_TRUE(any.Is<std::chrono::seconds>());
151 EXPECT_EQ(any.Unpack<std::chrono::nanoseconds>(), std::chrono::nanoseconds(123'456'789'987'654'321LL));
152 ASSERT_TRUE(any.Is<::google::protobuf::Duration>());
153 EXPECT_EQ(any.Unpack<::google::protobuf::Duration>(), duration);