userver: /data/code/userver/libraries/proto-structs/tests/any_test.cpp Source File
Loading...
Searching...
No Matches
any_test.cpp
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <chrono>
5
6#include <google/protobuf/util/time_util.h>
7
8#include <userver/proto-structs/any.hpp>
9#include <userver/proto-structs/io/std/chrono/duration_conv.hpp>
10
11#include "messages.pb.h"
13
14USERVER_NAMESPACE_BEGIN
15
16namespace proto_structs::tests {
17
18TEST(AnyTest, Ctor) {
19 Any any_default;
20 google::protobuf::Any pbuf_any;
21
22 messages::Simple original;
23 original.set_f1(1001);
24
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());
28
29 Any any = Any{pbuf_any};
30 messages::Simple msg;
31
32 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
33 EXPECT_EQ(msg.f1(), original.f1());
34
35 msg.clear_f1();
36
37 Any any_copy(any);
38
39 ASSERT_TRUE(std::move(any_copy).GetProtobufAny().UnpackTo(&msg));
40 EXPECT_EQ(msg.f1(), original.f1());
41
42 any_copy = Any{};
43 any_copy = any;
44
45 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
46 EXPECT_EQ(msg.f1(), original.f1());
47
48 Any any_move(std::move(any_copy));
49
50 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
51 EXPECT_EQ(msg.f1(), original.f1());
52
53 any_copy = Any{};
54 any_copy = std::move(any_move);
55
56 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
57 EXPECT_EQ(msg.f1(), original.f1());
58}
59
60TEST(AnyTest, Pack) {
61 structs::Simple obj{.f1 = 1001};
62 Any any(obj);
63
64 EXPECT_TRUE(any.Is<structs::Simple>());
65 EXPECT_TRUE(any.Is<messages::Simple>());
66
67 messages::Simple msg;
68
69 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
70 EXPECT_EQ(obj.f1, msg.f1());
71
72 any = {};
73 obj.f1 = 1002;
74 msg.clear_f1();
75
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());
83
84 any = {};
85 obj.f1 = 1003;
86 msg.clear_f1();
87
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());
95
96 any = {};
97 obj.f1 = 1004;
98 msg.set_f1(obj.f1);
99
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>());
105
106 msg.clear_f1();
107
108 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&msg));
109 EXPECT_EQ(obj.f1, msg.f1());
110
111 ASSERT_NO_THROW(any.Pack(std::chrono::nanoseconds(-123'456'789'987'654'321LL)));
112 EXPECT_TRUE(any.Is<std::chrono::milliseconds>()); // any duration suits
113 EXPECT_TRUE(any.Is<::google::protobuf::Duration>());
114
115 ::google::protobuf::Duration duration;
116
117 ASSERT_TRUE(any.GetProtobufAny().UnpackTo(&duration));
118 EXPECT_EQ(::google::protobuf::util::TimeUtil::DurationToNanoseconds(duration), -123'456'789'987'654'321LL);
119}
120
121TEST(AnyTest, Unpack) {
122 structs::Simple obj{.f1 = 1001};
123 Any any;
124
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);
130 EXPECT_THAT(
131 [&any]() { static_cast<void>(any.Unpack<structs::Empty>()); },
132 ::testing::ThrowsMessage<AnyUnpackError>(::testing::HasSubstr("'messages.Empty'"))
133 );
134
135 any = {};
136 messages::Simple msg;
137 msg.set_f1(1002);
138
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());
146
147 auto duration = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(123'456'789'987'654'321LL);
148
149 ASSERT_NO_THROW(any.Pack(std::chrono::nanoseconds(123'456'789'987'654'321LL)));
150 ASSERT_TRUE(any.Is<std::chrono::seconds>()); // any duration suits
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);
154}
155
156} // namespace proto_structs::tests
157
158USERVER_NAMESPACE_END