userver: /data/code/userver/libraries/proto-structs/tests/message_to_struct_test.cpp Source File
Loading...
Searching...
No Matches
message_to_struct_test.cpp
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <limits>
5
6#include <google/protobuf/util/time_util.h>
7
8#include <userver/proto-structs/convert.hpp>
9#include <userver/utest/assert_macros.hpp>
10
11#include "messages.pb.h"
12#include "structs.hpp"
13
14USERVER_NAMESPACE_BEGIN
15
16namespace proto_structs::tests {
17
18TEST(MessageToStruct, Empty) {
19 messages::Empty msg;
20 structs::Empty obj;
21
22 UASSERT_NO_THROW(MessageToStruct(msg, obj));
23 UASSERT_NO_THROW((obj = MessageToStruct<structs::Empty>(msg)));
24}
25
26TEST(MessageToStruct, Scalar) {
27 {
28 messages::Scalar msg;
29 msg.set_f1(true);
30 msg.set_f2(std::numeric_limits<int32_t>::min());
31 msg.set_f3(std::numeric_limits<uint32_t>::max());
32 msg.set_f4(std::numeric_limits<int64_t>::min());
33 msg.set_f5(std::numeric_limits<uint64_t>::max());
34 msg.set_f6(static_cast<float>(1.5));
35 msg.set_f7(-2.5);
36 msg.set_f8("test1");
37 msg.set_f9("test2");
38 msg.set_f10(messages::TestEnum::TEST_ENUM_VALUE1);
39 msg.set_f11(123);
40
41 auto obj = MessageToStruct<structs::Scalar>(msg);
42
43 CheckScalarEqual(obj, msg);
44 }
45
46 {
47 messages::Scalar msg;
48 structs::Scalar obj;
49
50 CheckScalarEqual(obj, msg);
51
52 msg.set_f2(1001);
53 obj.f2 = 1;
54 obj.f3 = 2;
55 obj.f8 = "test";
56
57 UASSERT_NO_THROW(MessageToStruct(msg, obj));
58 CheckScalarEqual(obj, msg);
59
60 msg.set_f8("hello");
61 msg.set_f9("world");
62 msg.set_f11(456);
63
64 UASSERT_NO_THROW(MessageToStruct(msg, obj));
65 CheckScalarEqual(obj, msg);
66 }
67
68 {
69 messages::Scalar msg;
70 msg.set_f11(-1);
71
72 UEXPECT_THROW_MSG(static_cast<void>(MessageToStruct<structs::Scalar>(msg)), ReadError, "'messages.Scalar.f11'");
73 }
74}
75
76TEST(MessageToStruct, WellKnownStd) {
77 auto create_valid = []() {
78 messages::WellKnownStd msg;
79 msg.mutable_f3()->set_year(1);
80 msg.mutable_f3()->set_month(1);
81 msg.mutable_f3()->set_day(1);
82 return msg;
83 };
84
85 UASSERT_NO_THROW(static_cast<void>(MessageToStruct<structs::WellKnownStd>(create_valid())));
86
87 {
88 messages::WellKnownStd msg;
89 *msg.mutable_f1() = ::google::protobuf::util::TimeUtil::NanosecondsToTimestamp(123'456'789'987'654'321LL);
90 *msg.mutable_f2() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(987'654'321'123'456'789LL);
91 msg.mutable_f3()->set_year(2025);
92 msg.mutable_f3()->set_month(8);
93 msg.mutable_f3()->set_day(27);
94 msg.mutable_f4()->set_hours(19);
95 msg.mutable_f4()->set_minutes(30);
96 msg.mutable_f4()->set_seconds(50);
97 msg.mutable_f4()->set_nanos(123'456'789);
98
99 auto obj = MessageToStruct<structs::WellKnownStd>(msg);
100
101 CheckWellKnownStdEqual(obj, msg);
102 }
103
104 {
105 messages::WellKnownStd msg = create_valid();
106 structs::WellKnownStd obj;
107
108 *msg.mutable_f1() = ::google::protobuf::util::TimeUtil::NanosecondsToTimestamp(-987'654'321'123'456'789LL);
109 obj.f1 = std::chrono::system_clock::now();
110 obj.f2 = std::chrono::milliseconds(1001);
111
112 UASSERT_NO_THROW(MessageToStruct(msg, obj));
113 CheckWellKnownStdEqual(obj, msg);
114
115 *msg.mutable_f2() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(-123'456'789'987'654'321LL);
116 msg.mutable_f4()->set_hours(24);
117 msg.mutable_f4()->set_minutes(0);
118 msg.mutable_f4()->set_seconds(0);
119 msg.mutable_f4()->set_nanos(0);
120
121 UASSERT_NO_THROW(MessageToStruct(msg, obj));
122 CheckWellKnownStdEqual(obj, msg);
123 }
124
125 {
126 messages::WellKnownStd msg = create_valid();
127 msg.mutable_f1()->set_nanos(1'999'999'999);
128
129 UEXPECT_THROW_MSG(
130 static_cast<void>(MessageToStruct<structs::WellKnownStd>(msg)),
131 ReadError,
132 "'messages.WellKnownStd.f1'"
133 );
134 }
135
136 {
137 messages::WellKnownStd msg = create_valid();
138 msg.mutable_f2()->set_nanos(-1'999'999'999);
139
140 UEXPECT_THROW_MSG(
141 static_cast<void>(MessageToStruct<structs::WellKnownStd>(msg)),
142 ReadError,
143 "'messages.WellKnownStd.f2'"
144 );
145 }
146
147 {
148 messages::WellKnownStd msg = create_valid();
149 msg.mutable_f3()->set_day(0); // not full date is not allowed for std::chrono::year_month_day
150
151 UEXPECT_THROW_MSG(
152 static_cast<void>(MessageToStruct<structs::WellKnownStd>(msg)),
153 ReadError,
154 "'messages.WellKnownStd.f3'"
155 );
156 }
157
158 {
159 messages::WellKnownStd msg = create_valid();
160 msg.mutable_f4()->set_seconds(60); // leap second is not allowed for std::chrono::hh_mm_ss
161
162 UEXPECT_THROW_MSG(
163 static_cast<void>(MessageToStruct<structs::WellKnownStd>(msg)),
164 ReadError,
165 "'messages.WellKnownStd.f4'"
166 );
167 }
168}
169
170TEST(MessageToStruct, WellKnownUsrv) {
171 auto create_valid = []() {
172 messages::WellKnownUsrv msg;
173 msg.mutable_f7()->set_value("0.000");
174 return msg;
175 };
176
177 UASSERT_NO_THROW(static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(create_valid())));
178
179 {
180 messages::WellKnownUsrv msg;
181 messages::Simple any_payload;
182
183 any_payload.set_f1(100);
184
185 ASSERT_TRUE(msg.mutable_f1()->PackFrom(any_payload));
186 *msg.mutable_f2() = ::google::protobuf::util::TimeUtil::NanosecondsToTimestamp(123'456'789'987'654'321LL);
187 *msg.mutable_f3() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(987'654'321'123'456'789LL);
188 msg.mutable_f4()->set_year(2025);
189 msg.mutable_f4()->set_month(8);
190 msg.mutable_f4()->set_day(27);
191 msg.mutable_f5()->set_hours(19);
192 msg.mutable_f5()->set_minutes(30);
193 msg.mutable_f5()->set_seconds(50);
194 msg.mutable_f5()->set_nanos(123'456'789);
195 msg.mutable_f6()->set_hours(2);
196 msg.mutable_f6()->set_minutes(10);
197 msg.mutable_f6()->set_seconds(11);
198 msg.mutable_f6()->set_nanos(987'654'321);
199 msg.mutable_f7()->set_value("1.123");
200
201 auto obj = MessageToStruct<structs::WellKnownUsrv>(msg);
202
203 CheckWellKnownUsrvEqual(obj, msg);
204 CheckSimpleEqual(obj.f1.Unpack<structs::Simple>(), any_payload);
205 }
206
207 {
208 messages::WellKnownUsrv msg = create_valid();
209 structs::WellKnownUsrv obj;
210 messages::Simple any_payload;
211
212 *msg.mutable_f2() = ::google::protobuf::util::TimeUtil::NanosecondsToTimestamp(-987'654'321'123'456'789LL);
213 msg.mutable_f7()->set_value("1001.001");
214 obj.f1.Pack<structs::Scalar>({.f10 = structs::TestEnum::kValue1});
215 obj.f2 = std::chrono::system_clock::now();
216 obj.f3 = std::chrono::milliseconds(1001);
217
218 UASSERT_NO_THROW(MessageToStruct(msg, obj));
219 CheckWellKnownUsrvEqual(obj, msg);
220
221 any_payload.set_f1(5);
222 ASSERT_TRUE(msg.mutable_f1()->PackFrom(any_payload));
223
224 *msg.mutable_f3() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(-123'456'789'987'654'321LL);
225 msg.mutable_f5()->set_hours(24);
226 msg.mutable_f5()->set_minutes(0);
227 msg.mutable_f5()->set_seconds(0);
228 msg.mutable_f5()->set_nanos(0);
229 msg.mutable_f7()->set_value("-1001.001");
230
231 UASSERT_NO_THROW(MessageToStruct(msg, obj));
232 CheckWellKnownUsrvEqual(obj, msg);
233 CheckSimpleEqual(obj.f1.Unpack<structs::Simple>(), any_payload);
234 }
235
236 {
237 messages::WellKnownUsrv msg = create_valid();
238 msg.mutable_f2()->set_nanos(1'999'999'999);
239
240 UEXPECT_THROW_MSG(
241 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
242 ReadError,
243 "'messages.WellKnownUsrv.f2'"
244 );
245 }
246
247 {
248 messages::WellKnownUsrv msg = create_valid();
249 msg.mutable_f3()->set_nanos(-1'999'999'999);
250
251 UEXPECT_THROW_MSG(
252 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
253 ReadError,
254 "'messages.WellKnownUsrv.f3'"
255 );
256 }
257
258 {
259 messages::WellKnownUsrv msg = create_valid();
260 msg.mutable_f4()->set_year(10'000);
261
262 UEXPECT_THROW_MSG(
263 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
264 ReadError,
265 "'messages.WellKnownUsrv.f4'"
266 );
267 }
268
269 {
270 messages::WellKnownUsrv msg = create_valid();
271 msg.mutable_f5()->set_hours(-1);
272
273 UEXPECT_THROW_MSG(
274 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
275 ReadError,
276 "'messages.WellKnownUsrv.f5'"
277 );
278 }
279
280 {
281 messages::WellKnownUsrv msg = create_valid();
282 msg.mutable_f6()->set_hours(24);
283
284 UEXPECT_THROW_MSG(
285 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
286 ReadError,
287 "'messages.WellKnownUsrv.f6'"
288 );
289
290 msg = create_valid();
291 msg.mutable_f6()->set_seconds(60);
292
293 UEXPECT_THROW_MSG(
294 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
295 ReadError,
296 "'messages.WellKnownUsrv.f6'"
297 );
298 }
299
300 {
301 messages::WellKnownUsrv msg = create_valid();
302 msg.mutable_f7()->set_value("");
303
304 UEXPECT_THROW_MSG(
305 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
306 ReadError,
307 "'messages.WellKnownUsrv.f7'"
308 );
309
310 msg.Clear();
311 msg.mutable_f7()->set_value("1.1234");
312
313 UEXPECT_THROW_MSG(
314 static_cast<void>(MessageToStruct<structs::WellKnownUsrv>(msg)),
315 ReadError,
316 "'messages.WellKnownUsrv.f7'"
317 );
318 }
319}
320
321TEST(MessageToStruct, WellKnownJson) {
322 auto create_valid = []() {
323 messages::WellKnownJson msg;
324 msg.mutable_f1()->set_null_value(::google::protobuf::NULL_VALUE);
325 return msg;
326 };
327
328 auto create_list = [](double num, const std::string& str, bool b) {
329 ::google::protobuf::ListValue list;
330 list.add_values()->set_null_value(::google::protobuf::NULL_VALUE);
331 list.add_values()->set_number_value(num);
332 list.add_values()->set_string_value(str);
333 list.add_values()->set_bool_value(b);
334 return list;
335 };
336
337 auto create_struct = [](double num, const std::string& str, bool b) {
338 ::google::protobuf::Struct obj;
339 (*obj.mutable_fields())["key0"].set_null_value(::google::protobuf::NULL_VALUE);
340 (*obj.mutable_fields())["key1"].set_number_value(num);
341 (*obj.mutable_fields())["key2"].set_string_value(str);
342 (*obj.mutable_fields())["key3"].set_bool_value(b);
343 return obj;
344 };
345
346 UASSERT_NO_THROW(static_cast<void>(MessageToStruct<structs::WellKnownJson>(create_valid())));
347
348 {
349 messages::WellKnownJson msg = create_valid();
350 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
351
352 CheckWellKnownJsonEqual(obj, msg);
353 }
354
355 {
356 messages::WellKnownJson msg;
357 *(msg.mutable_f1()->mutable_list_value()) = create_list(1, "test", true);
358 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
359
360 CheckWellKnownJsonEqual(obj, msg);
361 }
362
363 {
364 messages::WellKnownJson msg;
365 *(msg.mutable_f1()->mutable_struct_value()) = create_struct(5, "test2", false);
366 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
367
368 CheckWellKnownJsonEqual(obj, msg);
369 }
370
371 {
372 messages::WellKnownJson msg;
373 msg.mutable_f1()->set_number_value(1001);
374 *msg.mutable_f2() = create_list(10, "hello", false);
375 *msg.mutable_f3() = create_struct(20, "world", true);
376
377 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
378
379 CheckWellKnownJsonEqual(obj, msg);
380 }
381
382 {
383 messages::WellKnownJson msg;
384 *msg.mutable_f1()->mutable_list_value()->add_values()->mutable_list_value() = create_list(5, "hi", true);
385 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
386
387 CheckWellKnownJsonEqual(obj, msg);
388 }
389
390 {
391 messages::WellKnownJson msg;
392 auto& top = *msg.mutable_f1()->mutable_struct_value()->mutable_fields();
393 *top["top"].mutable_struct_value() = create_struct(6, "bonjour", false);
394 auto obj = MessageToStruct<structs::WellKnownJson>(msg);
395
396 CheckWellKnownJsonEqual(obj, msg);
397 }
398
399 {
400 messages::WellKnownJson msg = create_valid();
401 msg.mutable_f2()->add_values();
402
403 UEXPECT_THROW_MSG(
404 static_cast<void>(MessageToStruct<structs::WellKnownJson>(msg)),
405 ReadError,
406 "'messages.WellKnownJson.f2'"
407 );
408 }
409
410 {
411 messages::WellKnownJson msg = create_valid();
412 static_cast<void>((*msg.mutable_f3()->mutable_fields())["key"]);
413
414 UEXPECT_THROW_MSG(
415 static_cast<void>(MessageToStruct<structs::WellKnownJson>(msg)),
416 ReadError,
417 "'messages.WellKnownJson.f3'"
418 );
419 }
420}
421
422TEST(MessageToStruct, Optional) {
423 {
424 messages::Optional msg;
425 msg.set_f1(1001);
426 msg.set_f2("test");
427 msg.set_f3(messages::TestEnum::TEST_ENUM_VALUE1);
428 msg.mutable_f4()->set_f1(10);
429
430 auto obj = MessageToStruct<structs::Optional>(msg);
431
432 CheckOptionalEqual(obj, msg);
433 }
434
435 {
436 messages::Optional msg;
437 structs::Optional obj;
438
439 CheckOptionalEqual(obj, msg);
440
441 msg.set_f1(1001);
442 msg.mutable_f4()->set_f1(13);
443 obj.f2 = "test2";
444 obj.f3 = structs::TestEnum::kValue2;
445 obj.f4 = {.f1 = 5};
446
447 UASSERT_NO_THROW(MessageToStruct(msg, obj));
448 CheckOptionalEqual(obj, msg);
449
450 msg.set_f2("test3");
451
452 UASSERT_NO_THROW(MessageToStruct(msg, obj));
453 CheckOptionalEqual(obj, msg);
454 }
455}
456
457TEST(MessageToStruct, Repeated) {
458 {
459 messages::Repeated msg;
460 msg.add_f1(10);
461 msg.add_f1(11);
462 msg.add_f1(12);
463 msg.add_f2("test1");
464 msg.add_f2("test2");
465 msg.add_f3(messages::TestEnum::TEST_ENUM_VALUE1);
466 msg.add_f3(messages::TestEnum::TEST_ENUM_UNSPECIFIED);
467 msg.add_f3(messages::TestEnum::TEST_ENUM_VALUE2);
468 msg.add_f3(static_cast<messages::TestEnum>(1001));
469 msg.mutable_f4()->Add()->set_f1(1000);
470 msg.mutable_f4()->Add()->set_f1(1001);
471
472 auto obj = MessageToStruct<structs::Repeated>(msg);
473
474 CheckRepeatedEqual(obj, msg);
475 }
476
477 {
478 messages::Repeated msg;
479 structs::Repeated obj;
480
481 CheckRepeatedEqual(obj, msg);
482
483 msg.add_f1(1);
484 msg.mutable_f4()->Add()->set_f1(13);
485 obj.f1 = {1, 2, 3};
486 obj.f2 = {"test2"};
487 obj.f4 = {{.f1 = 5}};
488
489 UASSERT_NO_THROW(MessageToStruct(msg, obj));
490 CheckRepeatedEqual(obj, msg);
491
492 msg.add_f2("hello");
493
494 UASSERT_NO_THROW(MessageToStruct(msg, obj));
495 CheckRepeatedEqual(obj, msg);
496 }
497}
498
499TEST(MessageToStruct, Map) {
500 {
501 messages::Map msg;
502 (*msg.mutable_f1())[5] = 15;
503 (*msg.mutable_f1())[6] = 16;
504 (*msg.mutable_f1())[7] = 17;
505 (*msg.mutable_f2())["key1"] = "value1";
506 (*msg.mutable_f2())["key2"] = "value2";
507 (*msg.mutable_f3())[false] = messages::TestEnum::TEST_ENUM_UNSPECIFIED;
508 (*msg.mutable_f3())[true] = messages::TestEnum::TEST_ENUM_VALUE2;
509 (*msg.mutable_f4())["simple1"].set_f1(1001);
510 (*msg.mutable_f4())["simple2"].set_f1(1002);
511
512 auto obj = MessageToStruct<structs::Map>(msg);
513
514 CheckMapEqual(obj, msg);
515 }
516
517 {
518 messages::Map msg;
519 structs::Map obj;
520
521 CheckMapEqual(obj, msg);
522
523 (*msg.mutable_f1())[5] = 15;
524 (*msg.mutable_f4())["simple1"].set_f1(1001);
525 obj.f1 = {{1, 1}, {2, 2}, {3, 3}};
526 obj.f2 = {{"key1", "value1"}};
527 obj.f4 = {{"simple1", {.f1 = 5}}};
528
529 UASSERT_NO_THROW(MessageToStruct(msg, obj));
530 CheckMapEqual(obj, msg);
531
532 (*msg.mutable_f2())["key2"] = "value2";
533
534 UASSERT_NO_THROW(MessageToStruct(msg, obj));
535 CheckMapEqual(obj, msg);
536 }
537}
538
539TEST(MessageToStruct, Oneof) {
540 {
541 messages::Oneof msg;
542 msg.set_f1(1001);
543
544 auto obj = MessageToStruct<structs::Oneof>(msg);
545
546 CheckOneofEqual(obj, msg);
547 }
548
549 {
550 messages::Oneof msg;
551 structs::Oneof obj;
552
553 CheckOneofEqual(obj, msg);
554
555 msg.set_f2("test");
556 obj.test_oneof.Set<0>(1);
557
558 UASSERT_NO_THROW(MessageToStruct(msg, obj));
559 CheckOneofEqual(obj, msg);
560
561 msg.set_f3(messages::TestEnum::TEST_ENUM_UNSPECIFIED);
562
563 UASSERT_NO_THROW(MessageToStruct(msg, obj));
564 CheckOneofEqual(obj, msg);
565
566 msg.mutable_f4()->set_f1(1001);
567
568 UASSERT_NO_THROW(MessageToStruct(msg, obj));
569 CheckOneofEqual(obj, msg);
570 }
571}
572
573TEST(MessageToStruct, Indirect) {
574 {
575 messages::Indirect msg;
576 msg.mutable_f1()->set_f1(1);
577 *msg.mutable_f2() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(123'456'789'987'654'321LL);
578 msg.mutable_f3()->Add()->set_f1(3);
579 msg.mutable_f3()->Add()->set_f1(4);
580 (*msg.mutable_f4())[1].set_f1(5);
581 (*msg.mutable_f4())[2].set_f1(6);
582 msg.mutable_f5()->set_f1(7);
583 msg.set_f7(1001);
584 msg.add_f8(messages::TEST_ENUM_UNSPECIFIED);
585 (*msg.mutable_f9())["3"].set_f1(8);
586
587 auto obj = MessageToStruct<structs::Indirect>(msg);
588
589 CheckIndirectEqual(obj, msg);
590 }
591
592 {
593 messages::Indirect msg;
594 structs::Indirect obj;
595
596 CheckIndirectEqual(obj, msg);
597
598 msg.mutable_f1()->set_f1(10);
599 msg.mutable_f3()->Add()->set_f1(11);
600 msg.set_f6("hello");
601 obj.f1 = {.f1 = 1001};
602 obj.f4 = {{10, structs::Simple{.f1 = 1002}}};
603 obj.test_oneof.Set<0>(structs::Simple{.f1 = 30});
604
605 UASSERT_NO_THROW(MessageToStruct(msg, obj));
606 CheckIndirectEqual(obj, msg);
607
608 msg.mutable_f5()->set_f1(12);
609 msg.add_f8(messages::TEST_ENUM_VALUE2);
610 msg.add_f8(messages::TEST_ENUM_VALUE1);
611 obj.test_oneof.Set<0>(structs::Simple{.f1 = 1003});
612
613 UASSERT_NO_THROW(MessageToStruct(msg, obj));
614 CheckIndirectEqual(obj, msg);
615 }
616}
617
618TEST(MessageToStruct, Strong) {
619 {
620 messages::Strong msg;
621 msg.set_f1(1001);
622 msg.set_f2("hello");
623 msg.add_f3(messages::TestEnum::TEST_ENUM_VALUE1);
624 msg.add_f3(messages::TestEnum::TEST_ENUM_VALUE2);
625 (*msg.mutable_f4())[1].set_f1(1002);
626 (*msg.mutable_f4())[2].set_f1(1003);
627 *msg.mutable_f5() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(123'456'789'987'654'321LL);
628
629 auto obj = MessageToStruct<structs::Strong>(msg);
630
631 CheckStrongEqual(obj, msg);
632 }
633
634 {
635 messages::Strong msg;
636 structs::Strong obj;
637
638 CheckStrongEqual(obj, msg);
639
640 msg.set_f1(10);
641 *msg.mutable_f5() = ::google::protobuf::util::TimeUtil::NanosecondsToDuration(-123'456'789'987'654'321LL);
642 obj.f1 = structs::Strong::F1Strong{5};
643 obj.f4[100] = structs::Strong::F4Strong{structs::Simple{.f1 = 6}};
644
645 UASSERT_NO_THROW(MessageToStruct(msg, obj));
646 CheckStrongEqual(obj, msg);
647
648 msg.set_f2("test");
649 obj.test_oneof.Set<0>(structs::Strong::F5Strong{std::chrono::nanoseconds{123'456'789'987'654'321}});
650
651 UASSERT_NO_THROW(MessageToStruct(msg, obj));
652 CheckStrongEqual(obj, msg);
653 }
654}
655
656TEST(MessageToStruct, Erroneous) {
657 {
658 messages::Erroneous msg;
659 structs::Erroneous obj;
660
661 EXPECT_NO_THROW(obj = MessageToStruct<structs::Erroneous>(msg));
662 }
663
664 {
665 messages::Erroneous msg;
666 msg.mutable_f1()->set_error_type(messages::ConversionFailure::TYPE_EXCEPTION);
667
668 try {
669 auto result = MessageToStruct<structs::Erroneous>(msg);
670 FAIL() << "exception should be thrown";
671 } catch (const ReadError& e) {
672 EXPECT_THAT(e.what(), ::testing::HasSubstr("'messages.Erroneous.f1'"));
673 EXPECT_THAT(e.what(), ::testing::HasSubstr("conversion_failure_exception"));
674 } catch (...) {
675 FAIL() << "unexpected exception type";
676 }
677 }
678
679 {
680 messages::Erroneous msg;
681 msg.mutable_f2()->Add()->set_error_type(messages::ConversionFailure::TYPE_ERROR);
682
683 try {
684 auto result = MessageToStruct<structs::Erroneous>(msg);
685 FAIL() << "exception should be thrown";
686 } catch (const ReadError& e) {
687 EXPECT_THAT(e.what(), ::testing::HasSubstr("'messages.Erroneous.f2.error_field'"));
688 EXPECT_THAT(e.what(), ::testing::HasSubstr("conversion_failure_error"));
689 } catch (...) {
690 FAIL() << "unexpected exception type";
691 }
692 }
693
694 {
695 messages::Erroneous msg;
696 (*msg.mutable_f3())[10].set_error_type(messages::ConversionFailure::TYPE_ERROR_WITH_UNKNOWN_FIELD);
697
698 try {
699 auto result = MessageToStruct<structs::Erroneous>(msg);
700 FAIL() << "exception should be thrown";
701 } catch (const ReadError& e) {
702 EXPECT_THAT(e.what(), ::testing::HasSubstr("'messages.Erroneous.f3.<unknown_1001>'"));
703 EXPECT_THAT(e.what(), ::testing::HasSubstr("conversion_failure_error_with_unknown_field"));
704 } catch (...) {
705 FAIL() << "unexpected exception type";
706 }
707 }
708
709 {
710 messages::Erroneous msg;
711 msg.mutable_f4()->set_error_type(messages::ConversionFailure::TYPE_ERROR_WITH_UNKNOWN_FIELD);
712
713 try {
714 auto result = MessageToStruct<structs::Erroneous>(msg);
715 FAIL() << "exception should be thrown";
716 } catch (const ReadError& e) {
717 EXPECT_THAT(e.what(), ::testing::HasSubstr("'messages.Erroneous.f4.<unknown_1001>'"));
718 EXPECT_THAT(e.what(), ::testing::HasSubstr("conversion_failure_error_with_unknown_field"));
719 } catch (...) {
720 FAIL() << "unexpected exception type";
721 }
722 }
723}
724
725} // namespace proto_structs::tests
726
727USERVER_NAMESPACE_END