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