1#include <gtest/gtest.h>
4#include <unordered_map>
7#include <userver/proto-structs/oneof.hpp>
11namespace proto_structs::tests {
13enum TestEnum { kValue0 = 0, kValue1 = 1, kValue2 = 2 };
19using TestOneof = proto_structs::Oneof<int32_t, int32_t, std::string, TestEnum, TestStruct>;
21void CheckAlternativeSet(
const TestOneof& oneof, std::size_t set_index) {
22 ASSERT_EQ(oneof.GetIndex(), set_index);
26 for (std::size_t i = 0; i < TestOneof::kSize; ++i) {
28 ASSERT_FALSE(oneof.Contains(i));
30 ASSERT_TRUE(oneof.Contains(i));
35 ASSERT_EQ(oneof.ContainsAny(), found);
44TEST(OneofTest, Traits) {
45 static_assert(traits::Oneof<TestOneof>);
46 static_assert(traits::Oneof<
const volatile TestOneof>);
47 static_assert(TestOneof::kSize == 5);
49 static_assert(!traits::Oneof<TestOneof&>);
50 static_assert(!traits::Oneof<int32_t>);
51 static_assert(!traits::Oneof<std::pair<int32_t, int32_t>>);
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>>);
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>);
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>>);
75TEST(OneofTest, Ctor) {
76 TestOneof default_oneof;
78 CheckAlternativeSet(default_oneof, kOneofNpos);
80 TestOneof oneof(std::in_place_index<2>,
"hello world");
82 CheckAlternativeSet(oneof, 2);
83 EXPECT_EQ(oneof.Get<2>(),
"hello world");
85 TestOneof oneof_copy(oneof);
87 CheckAlternativeSet(oneof_copy, 2);
88 EXPECT_EQ(oneof_copy.Get<2>(),
"hello world");
90 oneof.Get<2>() =
"test1";
93 CheckAlternativeSet(oneof_copy, 2);
94 EXPECT_EQ(oneof_copy.Get<2>(),
"test1");
96 oneof.Get<2>() =
"test2";
97 TestOneof oneof_move(std::move(oneof));
99 CheckAlternativeSet(oneof_move, 2);
100 EXPECT_EQ(oneof_move.Get<2>(),
"test2");
102 oneof_copy = std::move(oneof_move);
104 CheckAlternativeSet(oneof_copy, 2);
105 EXPECT_EQ(oneof_copy.Get<2>(),
"test2");
108TEST(OneofTest, GetSetEmplace) {
113 CheckAlternativeSet(oneof, 0);
114 EXPECT_EQ(oneof.Get<0>(), 0);
118 CheckAlternativeSet(oneof, 0);
119 EXPECT_EQ(oneof.Get<0>(), 42);
121 EXPECT_EQ(oneof.Emplace<1>(1001), 1001);
122 CheckAlternativeSet(oneof, 1);
123 EXPECT_EQ(oneof.Get<1>(), 1001);
127 CheckAlternativeSet(oneof, 1);
128 EXPECT_EQ(oneof.Get<1>(), 1002);
130 oneof.Set<2>(
"hello world");
132 CheckAlternativeSet(oneof, 2);
133 EXPECT_EQ(oneof.Get<2>(),
"hello world");
135 std::string str =
"some string";
137 EXPECT_EQ(oneof.Emplace<2>(str.begin() + 5, str.end()),
"string");
138 CheckAlternativeSet(oneof, 2);
141 oneof.Set<2>(std::move(str));
143 CheckAlternativeSet(oneof, 2);
144 EXPECT_EQ(oneof.Get<2>(),
"some string!");
146 oneof.Set<3>(kValue1);
148 CheckAlternativeSet(oneof, 3);
149 EXPECT_EQ(oneof.Get<3>(), kValue1);
151 oneof.Set<4>({.f1 =
"test"});
153 CheckAlternativeSet(oneof, 4);
154 EXPECT_EQ(std::move(oneof).Get<4>().f1,
"test");
157TEST(OneofTest, Clear) {
160 EXPECT_NO_THROW(oneof.ClearOneof());
161 CheckAlternativeSet(oneof, kOneofNpos);
165 EXPECT_NO_THROW(oneof.Clear(1));
166 CheckAlternativeSet(oneof, 0);
167 EXPECT_EQ(oneof.Get<0>(), 1);
169 EXPECT_NO_THROW(oneof.Clear(0));
170 CheckAlternativeSet(oneof, kOneofNpos);
174 EXPECT_NO_THROW(oneof.ClearOneof());
175 CheckAlternativeSet(oneof, kOneofNpos);