1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <thrift/test/reflection/gen-cpp2/reflection_fatal_union.h>
18
19 #include <thrift/lib/cpp2/reflection/internal/test_helpers.h>
20 #include <thrift/lib/cpp2/reflection/reflection.h>
21
22 #include <folly/portability/GTest.h>
23
24 #include <fatal/type/transform.h>
25
26 namespace test_cpp2 {
27 namespace cpp_reflection {
28
29 FATAL_S(union1s, "union1");
30 FATAL_S(uis, "ui");
31 FATAL_S(uds, "ud");
32 FATAL_S(uss, "us");
33 FATAL_S(ues, "ue");
34
35 using uii = std::integral_constant<union1::Type, union1::Type::ui>;
36 using udi = std::integral_constant<union1::Type, union1::Type::ud>;
37 using usi = std::integral_constant<union1::Type, union1::Type::us>;
38 using uei = std::integral_constant<union1::Type, union1::Type::ue>;
39
TEST(fatal_union,variants)40 TEST(fatal_union, variants) {
41 using traits = fatal::variant_traits<union1>;
42
43 EXPECT_SAME<union1, traits::type>();
44 EXPECT_SAME<union1s, traits::name>();
45 EXPECT_SAME<union1::Type, traits::id>();
46
47 EXPECT_SAME<uii, traits::ids::ui>();
48 EXPECT_SAME<udi, traits::ids::ud>();
49 EXPECT_SAME<usi, traits::ids::us>();
50 EXPECT_SAME<uei, traits::ids::ue>();
51
52 EXPECT_SAME<
53 fatal::list<uii, udi, usi, uei>,
54 fatal::transform<traits::descriptors, fatal::get_type::id>>();
55
56 EXPECT_SAME<
57 fatal::list<std::int32_t, double, std::string, enum1>,
58 fatal::transform<traits::descriptors, fatal::get_type::type>>();
59 }
60
TEST(fatal_union,by_id)61 TEST(fatal_union, by_id) {
62 using vtraits = fatal::variant_traits<union1>;
63 using traits = vtraits::by_id;
64
65 EXPECT_SAME<uii, traits::id<uii>>();
66 EXPECT_SAME<udi, traits::id<udi>>();
67 EXPECT_SAME<usi, traits::id<usi>>();
68 EXPECT_SAME<uei, traits::id<uei>>();
69
70 EXPECT_SAME<std::int32_t, traits::type<uii>>();
71 EXPECT_SAME<double, traits::type<udi>>();
72 EXPECT_SAME<std::string, traits::type<usi>>();
73 EXPECT_SAME<enum1, traits::type<uei>>();
74
75 union1 u;
76 union1 const& uc = u;
77 union1& ul = u;
78 union1&& ur = std::move(u);
79 EXPECT_TRUE(vtraits::empty(u));
80 EXPECT_TRUE(vtraits::empty(uc));
81 EXPECT_TRUE(vtraits::empty(ul));
82 EXPECT_TRUE(vtraits::empty(ur));
83
84 traits::set<uii>(u, 10);
85 EXPECT_FALSE(vtraits::empty(u));
86 EXPECT_FALSE(vtraits::empty(uc));
87 EXPECT_FALSE(vtraits::empty(ul));
88 EXPECT_FALSE(vtraits::empty(ur));
89 EXPECT_EQ(union1::Type::ui, u.getType());
90 EXPECT_EQ(union1::Type::ui, vtraits::get_id(u));
91 EXPECT_EQ(union1::Type::ui, vtraits::get_id(uc));
92 EXPECT_EQ(union1::Type::ui, vtraits::get_id(ul));
93 EXPECT_EQ(union1::Type::ui, vtraits::get_id(ur));
94 EXPECT_EQ(10, u.get_ui());
95 EXPECT_EQ(10, traits::get<uii>(ul));
96 EXPECT_EQ(10, traits::get<uii>(uc));
97 EXPECT_EQ(10, traits::get<uii>(ur));
98
99 traits::set<udi>(u, 5.6);
100 EXPECT_FALSE(vtraits::empty(u));
101 EXPECT_FALSE(vtraits::empty(uc));
102 EXPECT_FALSE(vtraits::empty(ul));
103 EXPECT_FALSE(vtraits::empty(ur));
104 EXPECT_EQ(union1::Type::ud, u.getType());
105 EXPECT_EQ(union1::Type::ud, vtraits::get_id(u));
106 EXPECT_EQ(union1::Type::ud, vtraits::get_id(uc));
107 EXPECT_EQ(union1::Type::ud, vtraits::get_id(ul));
108 EXPECT_EQ(union1::Type::ud, vtraits::get_id(ur));
109 EXPECT_EQ(5.6, u.get_ud());
110 EXPECT_EQ(5.6, traits::get<udi>(ul));
111 EXPECT_EQ(5.6, traits::get<udi>(uc));
112 EXPECT_EQ(5.6, traits::get<udi>(ur));
113
114 traits::set<usi>(u, "hello");
115 EXPECT_FALSE(vtraits::empty(u));
116 EXPECT_FALSE(vtraits::empty(uc));
117 EXPECT_FALSE(vtraits::empty(ul));
118 EXPECT_FALSE(vtraits::empty(ur));
119 EXPECT_EQ(union1::Type::us, u.getType());
120 EXPECT_EQ(union1::Type::us, vtraits::get_id(u));
121 EXPECT_EQ(union1::Type::us, vtraits::get_id(uc));
122 EXPECT_EQ(union1::Type::us, vtraits::get_id(ul));
123 EXPECT_EQ(union1::Type::us, vtraits::get_id(ur));
124 EXPECT_EQ("hello", u.get_us());
125 EXPECT_EQ("hello", traits::get<usi>(ul));
126 EXPECT_EQ("hello", traits::get<usi>(uc));
127 EXPECT_EQ("hello", traits::get<usi>(ur));
128
129 traits::set<uei>(u, enum1::field1);
130 EXPECT_FALSE(vtraits::empty(u));
131 EXPECT_FALSE(vtraits::empty(uc));
132 EXPECT_FALSE(vtraits::empty(ul));
133 EXPECT_FALSE(vtraits::empty(ur));
134 EXPECT_EQ(union1::Type::ue, u.getType());
135 EXPECT_EQ(union1::Type::ue, vtraits::get_id(u));
136 EXPECT_EQ(union1::Type::ue, vtraits::get_id(uc));
137 EXPECT_EQ(union1::Type::ue, vtraits::get_id(ul));
138 EXPECT_EQ(union1::Type::ue, vtraits::get_id(ur));
139 EXPECT_EQ(enum1::field1, u.get_ue());
140 EXPECT_EQ(enum1::field1, traits::get<uei>(ul));
141 EXPECT_EQ(enum1::field1, traits::get<uei>(uc));
142 EXPECT_EQ(enum1::field1, traits::get<uei>(ur));
143 }
144
TEST(fatal_union,by_type)145 TEST(fatal_union, by_type) {
146 using vtraits = fatal::variant_traits<union1>;
147 using traits = vtraits::by_type;
148
149 EXPECT_SAME<uii, traits::id<std::int32_t>>();
150 EXPECT_SAME<udi, traits::id<double>>();
151 EXPECT_SAME<usi, traits::id<std::string>>();
152 EXPECT_SAME<uei, traits::id<enum1>>();
153
154 EXPECT_SAME<std::int32_t, traits::type<std::int32_t>>();
155 EXPECT_SAME<double, traits::type<double>>();
156 EXPECT_SAME<std::string, traits::type<std::string>>();
157 EXPECT_SAME<enum1, traits::type<enum1>>();
158
159 union1 u;
160 union1 const& uc = u;
161 union1& ul = u;
162 union1&& ur = std::move(u);
163 EXPECT_TRUE(vtraits::empty(u));
164 EXPECT_TRUE(vtraits::empty(uc));
165 EXPECT_TRUE(vtraits::empty(ul));
166 EXPECT_TRUE(vtraits::empty(ur));
167
168 traits::set<std::int32_t>(u, 10);
169 EXPECT_FALSE(vtraits::empty(u));
170 EXPECT_FALSE(vtraits::empty(uc));
171 EXPECT_FALSE(vtraits::empty(ul));
172 EXPECT_FALSE(vtraits::empty(ur));
173 EXPECT_EQ(union1::Type::ui, u.getType());
174 EXPECT_EQ(union1::Type::ui, vtraits::get_id(u));
175 EXPECT_EQ(union1::Type::ui, vtraits::get_id(uc));
176 EXPECT_EQ(union1::Type::ui, vtraits::get_id(ul));
177 EXPECT_EQ(union1::Type::ui, vtraits::get_id(ur));
178 EXPECT_EQ(10, u.get_ui());
179 EXPECT_EQ(10, traits::get<std::int32_t>(ul));
180 EXPECT_EQ(10, traits::get<std::int32_t>(uc));
181 EXPECT_EQ(10, traits::get<std::int32_t>(ur));
182
183 traits::set<double>(u, 5.6);
184 EXPECT_FALSE(vtraits::empty(u));
185 EXPECT_FALSE(vtraits::empty(uc));
186 EXPECT_FALSE(vtraits::empty(ul));
187 EXPECT_FALSE(vtraits::empty(ur));
188 EXPECT_EQ(union1::Type::ud, u.getType());
189 EXPECT_EQ(union1::Type::ud, vtraits::get_id(u));
190 EXPECT_EQ(union1::Type::ud, vtraits::get_id(uc));
191 EXPECT_EQ(union1::Type::ud, vtraits::get_id(ul));
192 EXPECT_EQ(union1::Type::ud, vtraits::get_id(ur));
193 EXPECT_EQ(5.6, u.get_ud());
194 EXPECT_EQ(5.6, traits::get<double>(ul));
195 EXPECT_EQ(5.6, traits::get<double>(uc));
196 EXPECT_EQ(5.6, traits::get<double>(ur));
197
198 traits::set<std::string>(u, "hello");
199 EXPECT_FALSE(vtraits::empty(u));
200 EXPECT_FALSE(vtraits::empty(uc));
201 EXPECT_FALSE(vtraits::empty(ul));
202 EXPECT_FALSE(vtraits::empty(ur));
203 EXPECT_EQ(union1::Type::us, u.getType());
204 EXPECT_EQ(union1::Type::us, vtraits::get_id(u));
205 EXPECT_EQ(union1::Type::us, vtraits::get_id(uc));
206 EXPECT_EQ(union1::Type::us, vtraits::get_id(ul));
207 EXPECT_EQ(union1::Type::us, vtraits::get_id(ur));
208 EXPECT_EQ("hello", u.get_us());
209 EXPECT_EQ("hello", traits::get<std::string>(ul));
210 EXPECT_EQ("hello", traits::get<std::string>(uc));
211 EXPECT_EQ("hello", traits::get<std::string>(ur));
212
213 traits::set<enum1>(u, enum1::field1);
214 EXPECT_FALSE(vtraits::empty(u));
215 EXPECT_FALSE(vtraits::empty(uc));
216 EXPECT_FALSE(vtraits::empty(ul));
217 EXPECT_FALSE(vtraits::empty(ur));
218 EXPECT_EQ(union1::Type::ue, u.getType());
219 EXPECT_EQ(union1::Type::ue, vtraits::get_id(u));
220 EXPECT_EQ(union1::Type::ue, vtraits::get_id(uc));
221 EXPECT_EQ(union1::Type::ue, vtraits::get_id(ul));
222 EXPECT_EQ(union1::Type::ue, vtraits::get_id(ur));
223 EXPECT_EQ(enum1::field1, u.get_ue());
224 EXPECT_EQ(enum1::field1, traits::get<enum1>(ul));
225 EXPECT_EQ(enum1::field1, traits::get<enum1>(uc));
226 EXPECT_EQ(enum1::field1, traits::get<enum1>(ur));
227 }
228
229 FATAL_S(unionA_annotation1k, "another.annotation");
230 FATAL_S(unionA_annotation1v, "some more text");
231 FATAL_S(unionA_annotation2k, "sample.annotation");
232 FATAL_S(unionA_annotation2v, "some text here");
233
TEST(fatal_union,annotations)234 TEST(fatal_union, annotations) {
235 EXPECT_SAME<
236 fatal::list<>,
237 apache::thrift::reflect_variant<union1>::annotations::map>();
238
239 EXPECT_SAME<
240 fatal::list<>,
241 apache::thrift::reflect_variant<union2>::annotations::map>();
242
243 EXPECT_SAME<
244 fatal::list<>,
245 apache::thrift::reflect_variant<union3>::annotations::map>();
246
247 using actual_unionA = apache::thrift::reflect_variant<unionA>::annotations;
248
249 EXPECT_SAME<unionA_annotation1k, actual_unionA::keys::another_annotation>();
250 EXPECT_SAME<unionA_annotation1v, actual_unionA::values::another_annotation>();
251 EXPECT_SAME<unionA_annotation2k, actual_unionA::keys::sample_annotation>();
252 EXPECT_SAME<unionA_annotation2v, actual_unionA::values::sample_annotation>();
253
254 EXPECT_SAME<
255 fatal::list<
256 apache::thrift::annotation<unionA_annotation1k, unionA_annotation1v>,
257 apache::thrift::annotation<unionA_annotation2k, unionA_annotation2v>>,
258 actual_unionA::map>();
259 }
260
TEST(fatal_union,by_name)261 TEST(fatal_union, by_name) {
262 using id_traits = fatal::enum_traits<union1::Type>;
263 using info = apache::thrift::reflect_variant<union1>;
264 using member_info = info::by_name<id_traits::member::ui::name>;
265
266 union1 u;
267 u.set_ui(10);
268
269 ASSERT_EQ(u.getType(), union1::Type::ui);
270 EXPECT_EQ(10, member_info::get(u));
271 }
272
TEST(fatal_union,by_type_id)273 TEST(fatal_union, by_type_id) {
274 using info = apache::thrift::reflect_variant<union1>;
275 using member_info = info::by_type_id<union1::Type::ui>;
276
277 union1 u;
278 u.set_ui(10);
279
280 ASSERT_EQ(u.getType(), union1::Type::ui);
281 EXPECT_EQ(10, member_info::get(u));
282 }
283
TEST(fatal_union,by_field_id)284 TEST(fatal_union, by_field_id) {
285 using info = apache::thrift::reflect_variant<union1>;
286 using member_info = info::by_field_id<1>;
287
288 union1 u;
289 u.set_ui(10);
290
291 ASSERT_EQ(u.getType(), union1::Type::ui);
292 EXPECT_EQ(10, member_info::get(u));
293 }
294
TEST(fatal_struct,renamed_field)295 TEST(fatal_struct, renamed_field) {
296 using emeta = fatal::enum_traits<union_with_renamed_field::Type>;
297 using vmeta = emeta::member::boring_cxx_name;
298 auto vname = fatal::to_instance<std::string, vmeta::name>();
299 EXPECT_EQ("fancy.idl.name", vname);
300
301 using umeta = apache::thrift::reflect_variant<union_with_renamed_field>;
302 using fmeta =
303 umeta::by_type_id<union_with_renamed_field::Type::boring_cxx_name>;
304 auto fname = fatal::to_instance<std::string, fmeta::metadata::name>();
305 EXPECT_EQ("fancy.idl.name", fname);
306 }
307
308 } // namespace cpp_reflection
309 } // namespace test_cpp2
310