userver: /home/antonyzhilin/arcadia/taxi/uservices/userver/libraries/proto-structs/tests/oneof_test.cpp Source File
Loading...
Searching...
No Matches
oneof_test.cpp
1#include <gtest/gtest.h>
2
3#include <optional>
4#include <unordered_map>
5#include <vector>
6
7#include <userver/proto-structs/oneof.hpp>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace proto_structs::tests {
12
13enum TestEnum { kValue0 = 0, kValue1 = 1, kValue2 = 2 };
14
15struct TestStruct {
16 std::string f1;
17};
18
19using TestOneof = proto_structs::Oneof<int32_t, int32_t, std::string, TestEnum, TestStruct>;
20
21void CheckAlternativeSet(const TestOneof& oneof, std::size_t set_index) {
22 ASSERT_EQ(oneof.GetIndex(), set_index);
23
24 bool found = false;
25
26 for (std::size_t i = 0; i < TestOneof::kSize; ++i) {
27 if (i != set_index) {
28 ASSERT_FALSE(oneof.Contains(i));
29 } else {
30 ASSERT_TRUE(oneof.Contains(i));
31 found = true;
32 }
33 }
34
35 ASSERT_EQ(oneof.ContainsAny(), found);
36
37 if (found) {
38 ASSERT_TRUE(oneof);
39 } else {
40 ASSERT_FALSE(oneof);
41 }
42}
43
44TEST(OneofTest, Traits) {
45 static_assert(traits::Oneof<TestOneof>);
46 static_assert(traits::Oneof<const volatile TestOneof>);
47 static_assert(TestOneof::kSize == 5);
48
49 static_assert(!traits::Oneof<TestOneof&>);
50 static_assert(!traits::Oneof<int32_t>);
51 static_assert(!traits::Oneof<std::pair<int32_t, int32_t>>);
52
53 static_assert(std::is_same_v<int32_t, OneofAlternativeType<0, TestOneof>>);
54 static_assert(std::is_same_v<int32_t, OneofAlternativeType<1, TestOneof>>);
55 static_assert(std::is_same_v<std::string, OneofAlternativeType<2, TestOneof>>);
56
57 static_assert(traits::OneofField<int32_t>);
58 static_assert(traits::OneofField<const volatile int32_t>);
59 static_assert(traits::OneofField<uint32_t>);
60 static_assert(traits::OneofField<int64_t>);
61 static_assert(traits::OneofField<uint64_t>);
62 static_assert(traits::OneofField<bool>);
63 static_assert(traits::OneofField<float>);
64 static_assert(traits::OneofField<double>);
65 static_assert(traits::OneofField<std::string>);
66 static_assert(traits::OneofField<const volatile TestEnum>);
67 static_assert(traits::OneofField<TestStruct>);
68
69 static_assert(!traits::OneofField<std::vector<int32_t>>);
70 static_assert(!traits::OneofField<std::optional<int32_t>>);
71 static_assert(!traits::OneofField<std::map<std::string, std::string>>);
72 static_assert(!traits::OneofField<std::unordered_map<int32_t, int32_t>>);
73}
74
75TEST(OneofTest, Ctor) {
76 TestOneof default_oneof;
77
78 CheckAlternativeSet(default_oneof, kOneofNpos);
79
80 TestOneof oneof(std::in_place_index<2>, "hello world");
81
82 CheckAlternativeSet(oneof, 2);
83 EXPECT_EQ(oneof.Get<2>(), "hello world");
84
85 TestOneof oneof_copy(oneof);
86
87 CheckAlternativeSet(oneof_copy, 2);
88 EXPECT_EQ(oneof_copy.Get<2>(), "hello world");
89
90 oneof.Get<2>() = "test1";
91 oneof_copy = oneof;
92
93 CheckAlternativeSet(oneof_copy, 2);
94 EXPECT_EQ(oneof_copy.Get<2>(), "test1");
95
96 oneof.Get<2>() = "test2";
97 TestOneof oneof_move(std::move(oneof));
98
99 CheckAlternativeSet(oneof_move, 2);
100 EXPECT_EQ(oneof_move.Get<2>(), "test2");
101
102 oneof_copy = std::move(oneof_move);
103
104 CheckAlternativeSet(oneof_copy, 2);
105 EXPECT_EQ(oneof_copy.Get<2>(), "test2");
106}
107
108TEST(OneofTest, GetSetEmplace) {
109 TestOneof oneof;
110
111 oneof.Set<0>(0);
112
113 CheckAlternativeSet(oneof, 0);
114 EXPECT_EQ(oneof.Get<0>(), 0);
115
116 oneof.Set<0>(42);
117
118 CheckAlternativeSet(oneof, 0);
119 EXPECT_EQ(oneof.Get<0>(), 42);
120
121 EXPECT_EQ(oneof.Emplace<1>(1001), 1001);
122 CheckAlternativeSet(oneof, 1);
123 EXPECT_EQ(oneof.Get<1>(), 1001);
124
125 ++oneof.Get<1>();
126
127 CheckAlternativeSet(oneof, 1);
128 EXPECT_EQ(oneof.Get<1>(), 1002);
129
130 oneof.Set<2>("hello world");
131
132 CheckAlternativeSet(oneof, 2);
133 EXPECT_EQ(oneof.Get<2>(), "hello world");
134
135 std::string str = "some string";
136
137 EXPECT_EQ(oneof.Emplace<2>(str.begin() + 5, str.end()), "string");
138 CheckAlternativeSet(oneof, 2);
139
140 str += "!";
141 oneof.Set<2>(std::move(str));
142
143 CheckAlternativeSet(oneof, 2);
144 EXPECT_EQ(oneof.Get<2>(), "some string!");
145
146 oneof.Set<3>(kValue1);
147
148 CheckAlternativeSet(oneof, 3);
149 EXPECT_EQ(oneof.Get<3>(), kValue1);
150
151 oneof.Set<4>({.f1 = "test"});
152
153 CheckAlternativeSet(oneof, 4);
154 EXPECT_EQ(std::move(oneof).Get<4>().f1, "test");
155}
156
157TEST(OneofTest, Clear) {
158 TestOneof oneof;
159
160 EXPECT_NO_THROW(oneof.ClearOneof());
161 CheckAlternativeSet(oneof, kOneofNpos);
162
163 oneof.Set<0>(1);
164
165 EXPECT_NO_THROW(oneof.Clear(1));
166 CheckAlternativeSet(oneof, 0);
167 EXPECT_EQ(oneof.Get<0>(), 1);
168
169 EXPECT_NO_THROW(oneof.Clear(0));
170 CheckAlternativeSet(oneof, kOneofNpos);
171
172 oneof.Set<1>(2);
173
174 EXPECT_NO_THROW(oneof.ClearOneof());
175 CheckAlternativeSet(oneof, kOneofNpos);
176}
177
178} // namespace proto_structs::tests
179
180USERVER_NAMESPACE_END