userver: /data/code/userver/libraries/proto-structs/codegen-tests/src/simple/simple_test.cpp Source File
Loading...
Searching...
No Matches
simple_test.cpp
1#include <type_traits>
2
3#include <gtest/gtest.h>
4
5#include <userver/proto-structs/convert.hpp>
6#include <userver/proto-structs/type_mapping.hpp>
7
8#include <simple/base.pb.h>
9#include <simple/base.structs.usrv.pb.hpp>
10
11#include <google/protobuf/any.h>
12
13namespace ss = simple::structs;
14
15USERVER_NAMESPACE_BEGIN
16
17TEST(SingleFile, SimpleStruct) {
18 static_assert(std::is_aggregate_v<ss::SimpleStruct>);
19 [[maybe_unused]] ss::SimpleStruct message;
20 message.some_integer = 5;
21 message.some_text = std::optional<std::string>("foo");
22 message.is_condition = true;
23 message.some_bytes = {"foo", "bar"};
24 message.something.set_bar("bar_val");
25 message.inner_enum = ss::SimpleStruct::InnerEnum2::kFooVal;
26 message.nested.swag = "foo";
27 message.optional_nested = std::optional<ss::SimpleStruct::NestedStruct>{{.swag = "foo"}};
28
29 auto vanilla = ::proto_structs::StructToMessage(std::move(message));
30
31 EXPECT_EQ(vanilla.some_integer(), 5);
32 EXPECT_EQ(vanilla.some_text(), "foo");
33 EXPECT_EQ(vanilla.is_condition(), true);
34 EXPECT_EQ(vanilla.some_bytes().Get(0), "foo");
35 EXPECT_EQ(vanilla.some_bytes().Get(1), "bar");
36 EXPECT_EQ(vanilla.bar(), "bar_val");
37 EXPECT_EQ(vanilla.inner_enum(), ss::SimpleStruct::ProtobufMessage::FOO_VAL);
38 EXPECT_EQ(vanilla.nested().swag(), "foo");
39 EXPECT_EQ(vanilla.optional_nested().swag(), "foo");
40
41 ss::SimpleStruct to;
42 ::proto_structs::MessageToStruct(vanilla, to);
43
44 ASSERT_EQ(to.some_integer, 5);
45 ASSERT_EQ(to.some_text, std::optional<std::string>("foo"));
46 ASSERT_TRUE(to.is_condition);
47 std::vector<std::string> exp = {"foo", "bar"};
48 ASSERT_EQ(to.some_bytes, exp);
49 ASSERT_EQ(to.something.bar(), "bar_val");
50 ASSERT_THROW([[maybe_unused]] auto foo = to.something.foo(), proto_structs::OneofAccessError);
51}
52
53TEST(SingleFile, NestedStruct) {
54 static_assert(std::is_aggregate_v<ss::SimpleStruct::NestedStruct>);
55 [[maybe_unused]] ss::SimpleStruct::NestedStruct nested;
56 nested.swag = "foo";
57
58 static_assert(std::is_aggregate_v<ss::SimpleStruct::NestedStruct::NestedStruct2>);
59 [[maybe_unused]] ss::SimpleStruct::NestedStruct::NestedStruct2 nested2;
60 nested2.swag2 = "bar";
61}
62
63TEST(SingleFile, InnerEnum1) {
64 static_assert(std::is_enum_v<ss::SimpleStruct::NestedStruct::NestedStruct2::InnerEnum1>);
65 [[maybe_unused]] const auto inner_enum1 = ss::SimpleStruct::NestedStruct::NestedStruct2::InnerEnum1::kBarVal;
66}
67
68TEST(SingleFile, InnerEnum2) {
69 static_assert(std::is_enum_v<ss::SimpleStruct::InnerEnum2>);
70 [[maybe_unused]] const auto inner_enum2 = ss::SimpleStruct::InnerEnum2::kFooVal;
71}
72
73TEST(SingleFile, SecondStruct) {
74 static_assert(std::is_aggregate_v<ss::SecondStruct>);
75 [[maybe_unused]] ss::SecondStruct message;
76}
77
78TEST(SingleFile, GlobalEnum) {
79 static_assert(std::is_enum_v<ss::GlobalEnum>);
80 [[maybe_unused]] ss::GlobalEnum message{};
81}
82
83TEST(Oneof, Empty) {
84 const ss::SimpleStruct::Something none;
85 EXPECT_FALSE(none);
86 EXPECT_FALSE(none.has_foo());
87 EXPECT_FALSE(none.has_bar());
88 EXPECT_THROW([[maybe_unused]] const auto& not_found1 = none.foo(), proto_structs::OneofAccessError);
89 EXPECT_THROW([[maybe_unused]] const auto& not_found2 = none.bar(), proto_structs::OneofAccessError);
90}
91
92TEST(Oneof, MakeFoo) {
93 ss::SimpleStruct::Something foo;
94 foo.set_foo(42);
95 EXPECT_TRUE(foo);
96 EXPECT_TRUE(foo.has_foo());
97 EXPECT_NO_THROW(EXPECT_EQ(foo.foo(), 42));
98 EXPECT_FALSE(foo.has_bar());
99 EXPECT_THROW([[maybe_unused]] const auto& not_found = foo.bar(), proto_structs::OneofAccessError);
100}
101
102TEST(Oneof, MakeBar) {
103 ss::SimpleStruct::Something bar;
104 bar.set_bar("bar");
105 EXPECT_TRUE(bar);
106 EXPECT_FALSE(bar.has_foo());
107 EXPECT_THROW([[maybe_unused]] const auto& not_found = bar.foo(), proto_structs::OneofAccessError);
108 EXPECT_TRUE(bar.has_bar());
109 EXPECT_NO_THROW(EXPECT_EQ(bar.bar(), "bar"));
110}
111
112TEST(Oneof, OneofInStruct) {
113 [[maybe_unused]] ss::SimpleStruct message;
114 message.something.set_bar("bar");
115 EXPECT_EQ(message.something.bar(), "bar");
116}
117
118TEST(Oneof, WellKnownTypes) {
119 const std::chrono::seconds kSeconds{1};
120 const std::chrono::nanoseconds kNanoseconds{1};
121 const std::chrono::year kYear{2025};
122 const std::chrono::month kMonth{10};
123 const std::chrono::day kDay{30};
124 const std::chrono::hours kHours{20};
125 const std::chrono::minutes kMinutes{10};
126 const std::string kString{"swag"};
127
128 ss::WellKnownUsrv message;
129
130 message.f1 = proto_structs::Timestamp(kSeconds, kNanoseconds);
131 message.f2 = proto_structs::Duration(kSeconds, kNanoseconds);
132 message.f3 = proto_structs::Date(kYear, kMonth, kDay);
133 message.f4 = proto_structs::TimeOfDay(kHours, kMinutes, kSeconds);
134
135 google::protobuf::Any pbuf_any;
136 proto_structs::traits::CompatibleMessageType<ss::ForAny> for_any;
137 for_any.set_f1(kString);
138
139 EXPECT_TRUE(pbuf_any.PackFrom(for_any));
140
141 message.f5 = proto_structs::Any{pbuf_any};
142
143 const auto vanilla = proto_structs::StructToMessage(std::move(message));
144
145 ss::WellKnownUsrv parsed;
146 proto_structs::MessageToStruct(vanilla, parsed);
147
148 ASSERT_EQ(parsed.f1.Seconds(), kSeconds);
149 ASSERT_EQ(parsed.f1.Nanos(), kNanoseconds);
150
151 ASSERT_EQ(parsed.f2.Seconds(), kSeconds);
152 ASSERT_EQ(parsed.f2.Nanos(), kNanoseconds);
153
154 ASSERT_TRUE(parsed.f3.Year().has_value());
155 ASSERT_TRUE(parsed.f3.Month().has_value());
156 ASSERT_TRUE(parsed.f3.Day().has_value());
157
158 ASSERT_EQ(parsed.f3.Year(), kYear);
159 ASSERT_EQ(parsed.f3.Month(), kMonth);
160 ASSERT_EQ(parsed.f3.Day(), kDay);
161
162 ASSERT_EQ(parsed.f4.Hours(), kHours);
163 ASSERT_EQ(parsed.f4.Minutes(), kMinutes);
164 ASSERT_EQ(parsed.f4.Seconds(), kSeconds);
165 ASSERT_EQ(parsed.f4.Nanos(), std::chrono::nanoseconds{0});
166
167 ASSERT_TRUE(parsed.f5.Is<proto_structs::traits::CompatibleMessageType<ss::ForAny>>());
168
169 const auto parsed_any = parsed.f5.Unpack<ss::ForAny>();
170 ASSERT_EQ(parsed_any.f1, kString);
171}
172
173USERVER_NAMESPACE_END