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_struct.h>
18
19 #include <thrift/lib/cpp2/reflection/internal/test_helpers.h>
20
21 #include <folly/portability/GTest.h>
22
23 FATAL_S(struct1s, "struct1");
24 FATAL_S(field0s, "field0");
25 FATAL_S(field1s, "field1");
26 FATAL_S(field2s, "field2");
27 FATAL_S(field3s, "field3");
28 FATAL_S(field4s, "field4");
29 FATAL_S(field5s, "field5");
30 FATAL_S(fieldAs, "fieldA");
31 FATAL_S(fieldBs, "fieldB");
32 FATAL_S(fieldCs, "fieldC");
33 FATAL_S(fieldDs, "fieldD");
34 FATAL_S(fieldEs, "fieldE");
35 FATAL_S(fieldFs, "fieldF");
36 FATAL_S(fieldGs, "fieldG");
37
38 template <apache::thrift::field_id_t Id>
39 using field_id = std::integral_constant<apache::thrift::field_id_t, Id>;
40
41 template <apache::thrift::optionality Optionality>
42 using required =
43 std::integral_constant<apache::thrift::optionality, Optionality>;
44
45 namespace test_cpp2 {
46 namespace cpp_reflection {
47
48 using apache::thrift::detail::st::IsThriftClass;
49 using apache::thrift::detail::st::IsThriftUnion;
50
51 static_assert(IsThriftClass<union1>::value);
52 static_assert(IsThriftClass<union2>::value);
53 static_assert(IsThriftClass<union3>::value);
54 static_assert(IsThriftClass<struct1>::value);
55 static_assert(IsThriftClass<struct2>::value);
56 static_assert(IsThriftClass<struct3>::value);
57 static_assert(!IsThriftClass<enum1>::value);
58 static_assert(!IsThriftClass<enum2>::value);
59 static_assert(!IsThriftClass<enum3>::value);
60 static_assert(IsThriftUnion<union1>::value);
61 static_assert(IsThriftUnion<union2>::value);
62 static_assert(IsThriftUnion<union3>::value);
63 static_assert(!IsThriftUnion<struct1>::value);
64 static_assert(!IsThriftUnion<struct2>::value);
65 static_assert(!IsThriftUnion<struct3>::value);
66 static_assert(!IsThriftUnion<enum1>::value);
67 static_assert(!IsThriftUnion<enum2>::value);
68 static_assert(!IsThriftUnion<enum3>::value);
69
TEST(fatal_struct,struct1_sanity_check)70 TEST(fatal_struct, struct1_sanity_check) {
71 using traits = apache::thrift::reflect_struct<struct1>;
72
73 EXPECT_SAME<struct1, traits::type>();
74 EXPECT_SAME<struct1s, traits::name>();
75 EXPECT_SAME<reflection_tags::module, traits::module>();
76
77 EXPECT_SAME<traits, apache::thrift::try_reflect_struct<struct1, void>>();
78 EXPECT_SAME<void, apache::thrift::try_reflect_struct<int, void>>();
79
80 EXPECT_SAME<field0s, traits::member::field0::name>();
81 EXPECT_SAME<field1s, traits::member::field1::name>();
82 EXPECT_SAME<field2s, traits::member::field2::name>();
83 EXPECT_SAME<field3s, traits::member::field3::name>();
84 EXPECT_SAME<field4s, traits::member::field4::name>();
85 EXPECT_SAME<field5s, traits::member::field5::name>();
86
87 struct1 pod;
88 *pod.field0_ref() = 19;
89 pod.field1_ref() = "hello";
90 *pod.field2_ref() = enum1::field2;
91 *pod.field3_ref() = enum2::field1_2;
92 pod.field4_ref() = {};
93 pod.field4_ref()->set_ud(5.6);
94 pod.field5_ref()->set_us_2("world");
95
96 EXPECT_EQ(*pod.field0_ref(), traits::member::field0::getter{}(pod));
97 EXPECT_EQ(*pod.field1_ref(), traits::member::field1::getter{}(pod));
98 EXPECT_EQ(*pod.field2_ref(), traits::member::field2::getter{}(pod));
99 EXPECT_EQ(*pod.field3_ref(), traits::member::field3::getter{}(pod));
100 EXPECT_EQ(*pod.field4_ref(), traits::member::field4::getter{}(pod));
101 EXPECT_EQ(*pod.field5_ref(), traits::member::field5::getter{}(pod));
102
103 traits::member::field0::getter{}(pod) = 98;
104 EXPECT_EQ(98, *pod.field0_ref());
105
106 traits::member::field1::getter{}(pod) = "test";
107 EXPECT_EQ("test", *pod.field1_ref());
108
109 traits::member::field2::getter{}(pod) = enum1::field0;
110 EXPECT_EQ(enum1::field0, *pod.field2_ref());
111
112 traits::member::field3::getter{}(pod) = enum2::field2_2;
113 EXPECT_EQ(enum2::field2_2, *pod.field3_ref());
114
115 traits::member::field4::getter{}(pod).set_ui(56);
116 EXPECT_EQ(union1::Type::ui, pod.field4_ref()->getType());
117 EXPECT_EQ(56, pod.field4_ref()->get_ui());
118
119 traits::member::field5::getter{}(pod).set_ue_2(enum1::field1);
120 EXPECT_EQ(union2::Type::ue_2, pod.field5_ref()->getType());
121 EXPECT_EQ(enum1::field1, pod.field5_ref()->get_ue_2());
122
123 EXPECT_SAME<
124 field0s,
125 fatal::get<traits::members, field0s, fatal::get_type::name>::name>();
126 EXPECT_SAME<
127 field1s,
128 fatal::get<traits::members, field1s, fatal::get_type::name>::name>();
129 EXPECT_SAME<
130 field2s,
131 fatal::get<traits::members, field2s, fatal::get_type::name>::name>();
132 EXPECT_SAME<
133 field3s,
134 fatal::get<traits::members, field3s, fatal::get_type::name>::name>();
135 EXPECT_SAME<
136 field4s,
137 fatal::get<traits::members, field4s, fatal::get_type::name>::name>();
138 EXPECT_SAME<
139 field5s,
140 fatal::get<traits::members, field5s, fatal::get_type::name>::name>();
141
142 EXPECT_SAME<
143 std::int32_t,
144 fatal::get<traits::members, field0s, fatal::get_type::name>::type>();
145 EXPECT_SAME<
146 std::string,
147 fatal::get<traits::members, field1s, fatal::get_type::name>::type>();
148 EXPECT_SAME<
149 enum1,
150 fatal::get<traits::members, field2s, fatal::get_type::name>::type>();
151 EXPECT_SAME<
152 enum2,
153 fatal::get<traits::members, field3s, fatal::get_type::name>::type>();
154 EXPECT_SAME<
155 union1,
156 fatal::get<traits::members, field4s, fatal::get_type::name>::type>();
157 EXPECT_SAME<
158 union2,
159 fatal::get<traits::members, field5s, fatal::get_type::name>::type>();
160
161 EXPECT_SAME<
162 field_id<1>,
163 fatal::get<traits::members, field0s, fatal::get_type::name>::id>();
164 EXPECT_SAME<
165 field_id<2>,
166 fatal::get<traits::members, field1s, fatal::get_type::name>::id>();
167 EXPECT_SAME<
168 field_id<4>,
169 fatal::get<traits::members, field2s, fatal::get_type::name>::id>();
170 EXPECT_SAME<
171 field_id<8>,
172 fatal::get<traits::members, field3s, fatal::get_type::name>::id>();
173 EXPECT_SAME<
174 field_id<16>,
175 fatal::get<traits::members, field4s, fatal::get_type::name>::id>();
176 EXPECT_SAME<
177 field_id<32>,
178 fatal::get<traits::members, field5s, fatal::get_type::name>::id>();
179
180 EXPECT_SAME<
181 required<apache::thrift::optionality::required>,
182 fatal::get<traits::members, field0s, fatal::get_type::name>::optional>();
183 EXPECT_SAME<
184 required<apache::thrift::optionality::optional>,
185 fatal::get<traits::members, field1s, fatal::get_type::name>::optional>();
186 EXPECT_SAME<
187 required<apache::thrift::optionality::required_of_writer>,
188 fatal::get<traits::members, field2s, fatal::get_type::name>::optional>();
189 EXPECT_SAME<
190 required<apache::thrift::optionality::required>,
191 fatal::get<traits::members, field3s, fatal::get_type::name>::optional>();
192 EXPECT_SAME<
193 required<apache::thrift::optionality::optional>,
194 fatal::get<traits::members, field4s, fatal::get_type::name>::optional>();
195 EXPECT_SAME<
196 required<apache::thrift::optionality::required_of_writer>,
197 fatal::get<traits::members, field5s, fatal::get_type::name>::optional>();
198
199 EXPECT_EQ(
200 98,
201 (fatal::get<
202 traits::members,
203 traits::member::field0::name,
204 fatal::get_type::name>::getter{}(pod)));
205 EXPECT_EQ(
206 "test",
207 (fatal::get<
208 traits::members,
209 traits::member::field1::name,
210 fatal::get_type::name>::getter{}(pod)));
211 EXPECT_EQ(
212 enum1::field0,
213 (fatal::get<
214 traits::members,
215 traits::member::field2::name,
216 fatal::get_type::name>::getter{}(pod)));
217 EXPECT_EQ(
218 enum2::field2_2,
219 (fatal::get<
220 traits::members,
221 traits::member::field3::name,
222 fatal::get_type::name>::getter{}(pod)));
223 EXPECT_EQ(
224 union1::Type::ui,
225 (fatal::get<
226 traits::members,
227 traits::member::field4::name,
228 fatal::get_type::name>::getter{}(pod)
229 .getType()));
230 EXPECT_EQ(
231 56,
232 (fatal::get<
233 traits::members,
234 traits::member::field4::name,
235 fatal::get_type::name>::getter{}(pod)
236 .get_ui()));
237 EXPECT_EQ(
238 union2::Type::ue_2,
239 (fatal::get<
240 traits::members,
241 traits::member::field5::name,
242 fatal::get_type::name>::getter{}(pod)
243 .getType()));
244 EXPECT_EQ(
245 enum1::field1,
246 (fatal::get<
247 traits::members,
248 traits::member::field5::name,
249 fatal::get_type::name>::getter{}(pod)
250 .get_ue_2()));
251
252 EXPECT_SAME<
253 apache::thrift::type_class::integral,
254 fatal::get<traits::members, field0s, fatal::get_type::name>::
255 type_class>();
256 EXPECT_SAME<
257 apache::thrift::type_class::string,
258 fatal::get<traits::members, field1s, fatal::get_type::name>::
259 type_class>();
260 EXPECT_SAME<
261 apache::thrift::type_class::enumeration,
262 fatal::get<traits::members, field2s, fatal::get_type::name>::
263 type_class>();
264 EXPECT_SAME<
265 apache::thrift::type_class::enumeration,
266 fatal::get<traits::members, field3s, fatal::get_type::name>::
267 type_class>();
268 EXPECT_SAME<
269 apache::thrift::type_class::variant,
270 fatal::get<traits::members, field4s, fatal::get_type::name>::
271 type_class>();
272 EXPECT_SAME<
273 apache::thrift::type_class::variant,
274 fatal::get<traits::members, field5s, fatal::get_type::name>::
275 type_class>();
276
277 EXPECT_SAME<
278 traits::member::field0,
279 fatal::get<
280 traits::members,
281 traits::member::field0::name,
282 fatal::get_type::name>>();
283 EXPECT_SAME<
284 traits::member::field1,
285 fatal::get<
286 traits::members,
287 traits::member::field1::name,
288 fatal::get_type::name>>();
289 EXPECT_SAME<
290 traits::member::field2,
291 fatal::get<
292 traits::members,
293 traits::member::field2::name,
294 fatal::get_type::name>>();
295 EXPECT_SAME<
296 traits::member::field3,
297 fatal::get<
298 traits::members,
299 traits::member::field3::name,
300 fatal::get_type::name>>();
301 EXPECT_SAME<
302 traits::member::field4,
303 fatal::get<
304 traits::members,
305 traits::member::field4::name,
306 fatal::get_type::name>>();
307 EXPECT_SAME<
308 traits::member::field5,
309 fatal::get<
310 traits::members,
311 traits::member::field5::name,
312 fatal::get_type::name>>();
313 }
314
315 FATAL_S(structB_annotation1k, "multi_line_annotation");
316 FATAL_S(structB_annotation1v, "line one\nline two");
317 FATAL_S(structB_annotation2k, "some.annotation");
318 FATAL_S(structB_annotation2v, "this is its value");
319 FATAL_S(structB_annotation3k, "some.other.annotation");
320 FATAL_S(structB_annotation3v, "this is its other value");
321
TEST(fatal_struct,annotations)322 TEST(fatal_struct, annotations) {
323 EXPECT_SAME<
324 fatal::list<>,
325 apache::thrift::reflect_struct<struct1>::annotations::map>();
326
327 EXPECT_SAME<
328 fatal::list<>,
329 apache::thrift::reflect_struct<struct2>::annotations::map>();
330
331 EXPECT_SAME<
332 fatal::list<>,
333 apache::thrift::reflect_struct<struct3>::annotations::map>();
334
335 EXPECT_SAME<
336 fatal::list<>,
337 apache::thrift::reflect_struct<structA>::annotations::map>();
338
339 using structB_annotations =
340 apache::thrift::reflect_struct<structB>::annotations;
341
342 EXPECT_SAME<
343 structB_annotation1k,
344 structB_annotations::keys::multi_line_annotation>();
345 EXPECT_SAME<
346 structB_annotation1v,
347 structB_annotations::values::multi_line_annotation>();
348 EXPECT_SAME<
349 structB_annotation2k,
350 structB_annotations::keys::some_annotation>();
351 EXPECT_SAME<
352 structB_annotation2v,
353 structB_annotations::values::some_annotation>();
354 EXPECT_SAME<
355 structB_annotation3k,
356 structB_annotations::keys::some_other_annotation>();
357 EXPECT_SAME<
358 structB_annotation3v,
359 structB_annotations::values::some_other_annotation>();
360 EXPECT_SAME<
361 fatal::list<
362 apache::thrift::
363 annotation<structB_annotation1k, structB_annotation1v>,
364 apache::thrift::
365 annotation<structB_annotation2k, structB_annotation2v>,
366 apache::thrift::
367 annotation<structB_annotation3k, structB_annotation3v>>,
368 structB_annotations::map>();
369
370 EXPECT_SAME<
371 fatal::list<>,
372 apache::thrift::reflect_struct<structC>::annotations::map>();
373 }
374
375 FATAL_S(structBd_annotation1k, "another.annotation");
376 FATAL_S(structBd_annotation1v, "another value");
377 FATAL_S(structBd_annotation2k, "some.annotation");
378 FATAL_S(structBd_annotation2v, "some value");
379
TEST(fatal_struct,member_annotations)380 TEST(fatal_struct, member_annotations) {
381 using info = apache::thrift::reflect_struct<structB>;
382
383 EXPECT_SAME<fatal::list<>, info::members_annotations::c::map>();
384 EXPECT_SAME<
385 fatal::list<>,
386 fatal::get<info::members, info::member::c::name, fatal::get_type::name>::
387 annotations::map>();
388
389 using annotations_d =
390 fatal::get<info::members, info::member::d::name, fatal::get_type::name>::
391 annotations;
392 using expected_d_map = fatal::list<
393 apache::thrift::annotation<structBd_annotation1k, structBd_annotation1v>,
394 apache::thrift::annotation<structBd_annotation2k, structBd_annotation2v>>;
395
396 EXPECT_SAME<expected_d_map, info::members_annotations::d::map>();
397 EXPECT_SAME<expected_d_map, annotations_d::map>();
398
399 EXPECT_SAME<
400 structBd_annotation1k,
401 info::members_annotations::d::keys::another_annotation>();
402 EXPECT_SAME<
403 structBd_annotation1v,
404 info::members_annotations::d::values::another_annotation>();
405 EXPECT_SAME<
406 structBd_annotation2k,
407 info::members_annotations::d::keys::some_annotation>();
408 EXPECT_SAME<
409 structBd_annotation2v,
410 info::members_annotations::d::values::some_annotation>();
411
412 EXPECT_SAME<structBd_annotation1k, annotations_d::keys::another_annotation>();
413 EXPECT_SAME<
414 structBd_annotation1v,
415 annotations_d::values::another_annotation>();
416 EXPECT_SAME<structBd_annotation2k, annotations_d::keys::some_annotation>();
417 EXPECT_SAME<structBd_annotation2v, annotations_d::values::some_annotation>();
418 }
419
420 FATAL_S(annotated_s_b_false, "s_b_false");
421 FATAL_S(annotated_s_b_true, "s_b_true");
422 FATAL_S(annotated_s_int, "s_int");
423 FATAL_S(annotated_s_string, "s_string");
424 FATAL_S(annotated_s_int_list, "s_int_list");
425 FATAL_S(annotated_s_str_list, "s_str_list");
426 FATAL_S(annotated_s_mixed_list, "s_mixed_list");
427 FATAL_S(annotated_s_int_map, "s_int_map");
428 FATAL_S(annotated_s_str_map, "s_str_map");
429 FATAL_S(annotated_s_mixed_map, "s_mixed_map");
430
431 FATAL_S(annotated_v_s_b_false, "false");
432 FATAL_S(annotated_v_s_b_true, "true");
433 FATAL_S(annotated_v_s_int, "10");
434 FATAL_S(annotated_v_s_string, "\"hello\"");
435 FATAL_S(annotated_v_s_int_list, "[-1, 2, 3]");
436 FATAL_S(annotated_v_s_str_list, "[\"a\", \"b\", \"c\"]");
437 FATAL_S(annotated_v_s_mixed_list, "[\"a\", 1, \"b\", 2]");
438 FATAL_S(annotated_v_s_int_map, "{\"a\": 1, \"b\": -2, \"c\": -3}");
439 FATAL_S(annotated_v_s_str_map, "{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\"}");
440 FATAL_S(annotated_v_s_mixed_map, "{\"a\": -2, \"b\": \"B\", \"c\": 3}");
441
TEST(fatal_struct,structured_annotations)442 TEST(fatal_struct, structured_annotations) {
443 using info = apache::thrift::reflect_struct<annotated>::annotations;
444
445 using bf =
446 apache::thrift::annotation<annotated_s_b_false, annotated_v_s_b_false>;
447 using bt =
448 apache::thrift::annotation<annotated_s_b_true, annotated_v_s_b_true>;
449 using i = apache::thrift::annotation<annotated_s_int, annotated_v_s_int>;
450 using s =
451 apache::thrift::annotation<annotated_s_string, annotated_v_s_string>;
452 using il =
453 apache::thrift::annotation<annotated_s_int_list, annotated_v_s_int_list>;
454 using sl =
455 apache::thrift::annotation<annotated_s_str_list, annotated_v_s_str_list>;
456 using ml = apache::thrift::
457 annotation<annotated_s_mixed_list, annotated_v_s_mixed_list>;
458 using im =
459 apache::thrift::annotation<annotated_s_int_map, annotated_v_s_int_map>;
460 using sm =
461 apache::thrift::annotation<annotated_s_str_map, annotated_v_s_str_map>;
462 using mm = apache::thrift::
463 annotation<annotated_s_mixed_map, annotated_v_s_mixed_map>;
464
465 EXPECT_SAME<bf, fatal::get<info::map, info::keys::s_b_false>>();
466 EXPECT_SAME<bt, fatal::get<info::map, info::keys::s_b_true>>();
467 EXPECT_SAME<i, fatal::get<info::map, info::keys::s_int>>();
468 EXPECT_SAME<s, fatal::get<info::map, info::keys::s_string>>();
469 EXPECT_SAME<il, fatal::get<info::map, info::keys::s_int_list>>();
470 EXPECT_SAME<sl, fatal::get<info::map, info::keys::s_str_list>>();
471 EXPECT_SAME<ml, fatal::get<info::map, info::keys::s_mixed_list>>();
472 EXPECT_SAME<im, fatal::get<info::map, info::keys::s_int_map>>();
473 EXPECT_SAME<sm, fatal::get<info::map, info::keys::s_str_map>>();
474 EXPECT_SAME<mm, fatal::get<info::map, info::keys::s_mixed_map>>();
475
476 EXPECT_SAME<fatal::list<bf, bt, i, il, im, ml, mm, sl, sm, s>, info::map>();
477 }
478
479 FATAL_S(annotated_m_b_false, "m_b_false");
480 FATAL_S(annotated_m_b_true, "m_b_true");
481 FATAL_S(annotated_m_int, "m_int");
482 FATAL_S(annotated_m_string, "m_string");
483 FATAL_S(annotated_m_int_list, "m_int_list");
484 FATAL_S(annotated_m_str_list, "m_str_list");
485 FATAL_S(annotated_m_mixed_list, "m_mixed_list");
486 FATAL_S(annotated_m_int_map, "m_int_map");
487 FATAL_S(annotated_m_str_map, "m_str_map");
488 FATAL_S(annotated_m_mixed_map, "m_mixed_map");
489
490 FATAL_S(annotated_v_m_b_false, "false");
491 FATAL_S(annotated_v_m_b_true, "true");
492 FATAL_S(annotated_v_m_int, "10");
493 FATAL_S(annotated_v_m_string, "\"hello\"");
494 FATAL_S(annotated_v_m_int_list, "[-1, 2, 3]");
495 FATAL_S(annotated_v_m_str_list, "[\"a\", \"b\", \"c\"]");
496 FATAL_S(annotated_v_m_mixed_list, "[\"a\", 1, \"b\", 2]");
497 FATAL_S(annotated_v_m_int_map, "{\"a\": 1, \"b\": -2, \"c\": -3}");
498 FATAL_S(annotated_v_m_str_map, "{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\"}");
499 FATAL_S(annotated_v_m_mixed_map, "{\"a\": -2, \"b\": \"B\", \"c\": 3}");
500
TEST(fatal_struct,structured_member_annotations)501 TEST(fatal_struct, structured_member_annotations) {
502 using info =
503 apache::thrift::reflect_struct<annotated>::members_annotations::a;
504
505 using bf =
506 apache::thrift::annotation<annotated_m_b_false, annotated_v_m_b_false>;
507 using bt =
508 apache::thrift::annotation<annotated_m_b_true, annotated_v_m_b_true>;
509 using i = apache::thrift::annotation<annotated_m_int, annotated_v_m_int>;
510 using s =
511 apache::thrift::annotation<annotated_m_string, annotated_v_m_string>;
512 using il =
513 apache::thrift::annotation<annotated_m_int_list, annotated_v_m_int_list>;
514 using sl =
515 apache::thrift::annotation<annotated_m_str_list, annotated_v_m_str_list>;
516 using ml = apache::thrift::
517 annotation<annotated_m_mixed_list, annotated_v_m_mixed_list>;
518 using im =
519 apache::thrift::annotation<annotated_m_int_map, annotated_v_m_int_map>;
520 using sm =
521 apache::thrift::annotation<annotated_m_str_map, annotated_v_m_str_map>;
522 using mm = apache::thrift::
523 annotation<annotated_m_mixed_map, annotated_v_m_mixed_map>;
524
525 EXPECT_SAME<bf, fatal::get<info::map, info::keys::m_b_false>>();
526 EXPECT_SAME<bt, fatal::get<info::map, info::keys::m_b_true>>();
527 EXPECT_SAME<i, fatal::get<info::map, info::keys::m_int>>();
528 EXPECT_SAME<s, fatal::get<info::map, info::keys::m_string>>();
529 EXPECT_SAME<il, fatal::get<info::map, info::keys::m_int_list>>();
530 EXPECT_SAME<sl, fatal::get<info::map, info::keys::m_str_list>>();
531 EXPECT_SAME<ml, fatal::get<info::map, info::keys::m_mixed_list>>();
532 EXPECT_SAME<im, fatal::get<info::map, info::keys::m_int_map>>();
533 EXPECT_SAME<sm, fatal::get<info::map, info::keys::m_str_map>>();
534 EXPECT_SAME<mm, fatal::get<info::map, info::keys::m_mixed_map>>();
535
536 EXPECT_SAME<fatal::list<bf, bt, i, il, im, ml, mm, sl, sm, s>, info::map>();
537 }
538
TEST(fatal_struct,set_methods)539 TEST(fatal_struct, set_methods) {
540 using info = apache::thrift::reflect_struct<struct4>;
541 using req_field = fatal::
542 get<info::members, info::member::field0::name, fatal::get_type::name>;
543 using opt_field = fatal::
544 get<info::members, info::member::field1::name, fatal::get_type::name>;
545 using def_field = fatal::
546 get<info::members, info::member::field2::name, fatal::get_type::name>;
547
548 using ref_field = fatal::
549 get<info::members, info::member::field3::name, fatal::get_type::name>;
550
551 struct4 a;
552 EXPECT_TRUE(req_field::is_set(a));
553 EXPECT_TRUE(req_field::mark_set(a, true));
554 EXPECT_TRUE(req_field::is_set(a));
555 EXPECT_FALSE(req_field::mark_set(a, false));
556 EXPECT_TRUE(req_field::is_set(a));
557
558 EXPECT_FALSE(opt_field::is_set(a));
559 EXPECT_TRUE(opt_field::mark_set(a, true));
560 EXPECT_TRUE(opt_field::is_set(a));
561 EXPECT_FALSE(opt_field::mark_set(a, false));
562 EXPECT_FALSE(opt_field::is_set(a));
563
564 EXPECT_FALSE(def_field::is_set(a));
565 EXPECT_TRUE(def_field::mark_set(a, true));
566 EXPECT_TRUE(def_field::is_set(a));
567 EXPECT_FALSE(def_field::mark_set(a, false));
568 EXPECT_FALSE(def_field::is_set(a));
569
570 EXPECT_TRUE(ref_field::is_set(a));
571 EXPECT_TRUE(ref_field::mark_set(a, true));
572 }
573
TEST(fatal_struct,field_ref_getter)574 TEST(fatal_struct, field_ref_getter) {
575 using info = apache::thrift::reflect_struct<struct4>;
576 using req_field = fatal::
577 get<info::members, info::member::field0::name, fatal::get_type::name>;
578 using opt_field = fatal::
579 get<info::members, info::member::field1::name, fatal::get_type::name>;
580 using def_field = fatal::
581 get<info::members, info::member::field2::name, fatal::get_type::name>;
582
583 using ref_field = fatal::
584 get<info::members, info::member::field3::name, fatal::get_type::name>;
585
586 struct4 a;
587
588 req_field::field_ref_getter req;
589 EXPECT_TRUE(req(a).has_value());
590 req(a) = 1;
591 EXPECT_EQ(a.field0_ref(), 1);
592 a.field0_ref() = 2;
593 EXPECT_EQ(req(a), 2);
594 static_assert(
595 std::is_same<
596 apache::thrift::required_field_ref<std::int32_t&>,
597 decltype(req(a))>::value,
598 "");
599
600 opt_field::field_ref_getter opt;
601 EXPECT_FALSE(opt(a));
602 opt(a) = "1";
603 EXPECT_EQ(a.field1_ref(), "1");
604 a.field1_ref() = "2";
605 EXPECT_EQ(opt(a), "2");
606 static_assert(
607 std::is_same<
608 apache::thrift::optional_field_ref<std::string&>,
609 decltype(opt(a))>::value,
610 "");
611
612 def_field::field_ref_getter def;
613 EXPECT_FALSE(def(a).is_set());
614 def(a) = enum1::field1;
615 EXPECT_EQ(a.field2_ref(), enum1::field1);
616 a.field2_ref() = enum1::field2;
617 EXPECT_EQ(def(a), enum1::field2);
618 static_assert(
619 std::is_same<apache::thrift::field_ref<enum1&>, decltype(def(a))>::value,
620 "");
621
622 ref_field::field_ref_getter ref;
623 EXPECT_TRUE(ref(a));
624 ref(a)->a_ref() = 1;
625 EXPECT_EQ(a.field3_ref()->a_ref(), 1);
626 a.field3_ref()->a_ref() = 2;
627 EXPECT_EQ(ref(a)->a_ref(), 2);
628 static_assert(
629 std::is_same<std::unique_ptr<structA>&, decltype(ref(a))>::value, "");
630 }
631
TEST(fatal_struct,renamed_field)632 TEST(fatal_struct, renamed_field) {
633 using meta = apache::thrift::reflect_struct<struct_with_renamed_field>;
634 using fmeta = meta::member::boring_cxx_name;
635 auto fname = fatal::to_instance<std::string, fmeta::name>();
636 EXPECT_EQ("fancy.idl.name", fname);
637 }
638
639 } // namespace cpp_reflection
640 } // namespace test_cpp2
641