userver: /data/code/userver/libraries/protobuf/tests/json/utils.cpp Source File
Loading...
Searching...
No Matches
utils.cpp
1#include "utils.hpp"
2
3#include <algorithm>
4#include <cmath>
5#include <stdexcept>
6
7#include <fmt/format.h>
8#include <google/protobuf/util/json_util.h>
9
10#include <userver/formats/json/serialize.hpp>
11#include <userver/utils/meta.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace protobuf::json::tests {
16
17template <typename T>
18using SupportsCheckMessageEqual = decltype(CheckMessageEqual(std::declval<const T&>(), std::declval<const T&>()));
19
20template <typename T>
21inline constexpr bool kSupportsCheckMessageEqual = meta::IsDetected<SupportsCheckMessageEqual, T>;
22
23template <typename T>
24void AreProtobufRepeatedEqual(const T& lhs, const T& rhs) {
25 ASSERT_EQ(lhs.size(), rhs.size());
26
27 for (int i = 0; i < lhs.size(); ++i) {
28 if constexpr (kSupportsCheckMessageEqual<typename T::value_type>) {
29 CheckMessageEqual(lhs[i], rhs[i]);
30 } else {
31 EXPECT_EQ(lhs[i], rhs[i]);
32 }
33 }
34}
35
36template <typename T>
37void AreProtobufMapsEqual(const T& lhs, const T& rhs) {
38 EXPECT_EQ(lhs.size(), rhs.size());
39
40 for (const auto& [key, val] : lhs) {
41 ASSERT_TRUE(rhs.contains(key));
42
43 if constexpr (kSupportsCheckMessageEqual<typename T::mapped_type>) {
44 CheckMessageEqual(val, rhs.at(key));
45 } else {
46 EXPECT_EQ(val, rhs.at(key));
47 }
48 }
49}
50
51formats::json::Value PrepareJsonTestData(const std::string& json_data) { return formats::json::FromString(json_data); }
52
53formats::json::Value CreateSampleJson(const ::google::protobuf::Message& message, const WriteOptions& options) {
54 using StringType = std::decay_t<decltype(message.DebugString())>;
55
56 StringType result;
57 ::google::protobuf::util::JsonPrintOptions native_options;
58#if GOOGLE_PROTOBUF_VERSION >= 5026001
59 native_options.always_print_fields_with_no_presence = options.always_print_fields_with_no_presence;
60#else
61 native_options.always_print_primitive_fields = options.always_print_fields_with_no_presence;
62#endif
63 native_options.always_print_enums_as_ints = options.always_print_enums_as_ints;
64 native_options.preserve_proto_field_names = options.preserve_proto_field_names;
65
66 auto status = ::google::protobuf::util::MessageToJsonString(message, &result, native_options);
67
68 if (status.ok()) {
69 return formats::json::FromString(result);
70 } else {
71 throw SampleError(fmt::format("Failed to create sample JSON from protobuf message: {}", status.message()));
72 }
73}
74
75void InitSampleMessage(const std::string& json, const ReadOptions& options, ::google::protobuf::Message& message) {
76 ::google::protobuf::util::ParseOptions native_options;
77 native_options.ignore_unknown_fields = options.ignore_unknown_fields;
78
79 auto status = ::google::protobuf::util::JsonStringToMessage(json, &message, native_options);
80
81 if (!status.ok()) {
82 throw SampleError(fmt::format("Failed to initialize sample message from JSON: {}", status.message()));
83 }
84}
85
86::google::protobuf::Value ProtoValueToNative(const ProtoValue& data) {
87 struct Visitor {
88 ::google::protobuf::Value result;
89
90 ::google::protobuf::Value operator()(std::monostate) { return result; }
91
92 ::google::protobuf::Value operator()(ProtoNullValue) {
93 result.set_null_value(::google::protobuf::NULL_VALUE);
94 return result;
95 }
96
97 ::google::protobuf::Value operator()(double val) {
98 result.set_number_value(val);
99 return result;
100 }
101
102 ::google::protobuf::Value operator()(const std::string& val) {
103 result.set_string_value(val);
104 return result;
105 }
106
107 ::google::protobuf::Value operator()(bool val) {
108 result.set_bool_value(val);
109 return result;
110 }
111
112 ::google::protobuf::Value operator()(const std::vector<double>& val) {
113 auto& arr = *result.mutable_list_value();
114
115 for (const auto& item : val) {
116 arr.add_values()->set_number_value(item);
117 }
118
119 return result;
120 }
121
122 ::google::protobuf::Value operator()(const std::map<std::string, std::string>& val) {
123 auto& fields = *result.mutable_struct_value()->mutable_fields();
124
125 for (const auto& [key, value] : val) {
126 fields[key].set_string_value(value);
127 }
128
129 return result;
130 }
131 };
132
133 return std::visit(Visitor{}, data);
134}
135
136proto_json::messages::Int32Message PrepareTestData(const Int32MessageData& message_data) {
137 proto_json::messages::Int32Message message;
138 message.set_field1(message_data.field1);
139 message.set_field2(message_data.field2);
140 message.set_field3(message_data.field3);
141 return message;
142}
143
144void CheckMessageEqual(const proto_json::messages::Int32Message& lhs, const proto_json::messages::Int32Message& rhs) {
145 EXPECT_EQ(lhs.field1(), rhs.field1());
146 EXPECT_EQ(lhs.field2(), rhs.field2());
147 EXPECT_EQ(lhs.field3(), rhs.field3());
148}
149
150proto_json::messages::UInt32Message PrepareTestData(const UInt32MessageData& message_data) {
151 proto_json::messages::UInt32Message message;
152 message.set_field1(message_data.field1);
153 message.set_field2(message_data.field2);
154 return message;
155}
156
157void CheckMessageEqual(const proto_json::messages::UInt32Message& lhs, const proto_json::messages::UInt32Message& rhs) {
158 EXPECT_EQ(lhs.field1(), rhs.field1());
159 EXPECT_EQ(lhs.field2(), rhs.field2());
160}
161
162proto_json::messages::Int64Message PrepareTestData(const Int64MessageData& message_data) {
163 proto_json::messages::Int64Message message;
164 message.set_field1(message_data.field1);
165 message.set_field2(message_data.field2);
166 message.set_field3(message_data.field3);
167 return message;
168}
169
170void CheckMessageEqual(const proto_json::messages::Int64Message& lhs, const proto_json::messages::Int64Message& rhs) {
171 EXPECT_EQ(lhs.field1(), rhs.field1());
172 EXPECT_EQ(lhs.field2(), rhs.field2());
173 EXPECT_EQ(lhs.field3(), rhs.field3());
174}
175
176proto_json::messages::UInt64Message PrepareTestData(const UInt64MessageData& message_data) {
177 proto_json::messages::UInt64Message message;
178 message.set_field1(message_data.field1);
179 message.set_field2(message_data.field2);
180 return message;
181}
182
183void CheckMessageEqual(const proto_json::messages::UInt64Message& lhs, const proto_json::messages::UInt64Message& rhs) {
184 EXPECT_EQ(lhs.field1(), rhs.field1());
185 EXPECT_EQ(lhs.field2(), rhs.field2());
186}
187
188proto_json::messages::FloatMessage PrepareTestData(const FloatMessageData& message_data) {
189 proto_json::messages::FloatMessage message;
190 message.set_field1(message_data.field1);
191 return message;
192}
193
194void CheckMessageEqual(const proto_json::messages::FloatMessage& lhs, const proto_json::messages::FloatMessage& rhs) {
195 if (!std::isnan(lhs.field1())) {
196 EXPECT_EQ(lhs.field1(), rhs.field1());
197 } else {
198 EXPECT_TRUE(std::isnan(rhs.field1()));
199 }
200}
201
202proto_json::messages::DoubleMessage PrepareTestData(const DoubleMessageData& message_data) {
203 proto_json::messages::DoubleMessage message;
204 message.set_field1(message_data.field1);
205 return message;
206}
207
208void CheckMessageEqual(const proto_json::messages::DoubleMessage& lhs, const proto_json::messages::DoubleMessage& rhs) {
209 if (!std::isnan(lhs.field1())) {
210 EXPECT_EQ(lhs.field1(), rhs.field1());
211 } else {
212 EXPECT_TRUE(std::isnan(rhs.field1()));
213 }
214}
215
216proto_json::messages::BoolMessage PrepareTestData(const BoolMessageData& message_data) {
217 proto_json::messages::BoolMessage message;
218 message.set_field1(message_data.field1);
219 return message;
220}
221
222void CheckMessageEqual(const proto_json::messages::BoolMessage& lhs, const proto_json::messages::BoolMessage& rhs) {
223 EXPECT_EQ(lhs.field1(), rhs.field1());
224}
225
226proto_json::messages::StringMessage PrepareTestData(const StringMessageData& message_data) {
227 proto_json::messages::StringMessage message;
228 message.set_field1(message_data.field1);
229 return message;
230}
231
232void CheckMessageEqual(const proto_json::messages::StringMessage& lhs, const proto_json::messages::StringMessage& rhs) {
233 EXPECT_EQ(lhs.field1(), rhs.field1());
234}
235
236proto_json::messages::BytesMessage PrepareTestData(const BytesMessageData& message_data) {
237 proto_json::messages::BytesMessage message;
238 message.set_field1(message_data.field1);
239 return message;
240}
241
242void CheckMessageEqual(const proto_json::messages::BytesMessage& lhs, const proto_json::messages::BytesMessage& rhs) {
243 EXPECT_EQ(lhs.field1(), rhs.field1());
244}
245
246proto_json::messages::EnumMessage PrepareTestData(const EnumMessageData& message_data) {
247 proto_json::messages::EnumMessage message;
248 message.set_field1(message_data.field1);
249 return message;
250}
251
252void CheckMessageEqual(const proto_json::messages::EnumMessage& lhs, const proto_json::messages::EnumMessage& rhs) {
253 EXPECT_EQ(lhs.field1(), rhs.field1());
254}
255
256proto_json::messages::NestedMessage PrepareTestData(const NestedMessageData& message_data) {
257 proto_json::messages::NestedMessage message;
258 if (message_data.field1) {
259 message.mutable_parent()->set_field1(message_data.field1.value());
260 }
261 return message;
262}
263
264void CheckMessageEqual(const proto_json::messages::NestedMessage& lhs, const proto_json::messages::NestedMessage& rhs) {
265 EXPECT_TRUE((lhs.has_parent() && rhs.has_parent()) || (!lhs.has_parent() && !rhs.has_parent()));
266 EXPECT_EQ(lhs.parent().field1(), rhs.parent().field1());
267}
268
269proto_json::messages::WrapperMessage PrepareTestData(const WrapperMessageData& message_data) {
270 proto_json::messages::WrapperMessage message;
271
272 if (message_data.field1) {
273 message.mutable_field1()->set_value(message_data.field1.value());
274 }
275
276 if (message_data.field2) {
277 message.mutable_field2()->set_value(message_data.field2.value());
278 }
279
280 if (message_data.field3) {
281 message.mutable_field3()->set_value(message_data.field3.value());
282 }
283
284 if (message_data.field4) {
285 message.mutable_field4()->set_value(message_data.field4.value());
286 }
287
288 if (message_data.field5) {
289 message.mutable_field5()->set_value(message_data.field5.value());
290 }
291
292 if (message_data.field6) {
293 message.mutable_field6()->set_value(message_data.field6.value());
294 }
295
296 if (message_data.field7) {
297 message.mutable_field7()->set_value(message_data.field7.value());
298 }
299
300 if (message_data.field8) {
301 message.mutable_field8()->set_value(message_data.field8.value());
302 }
303
304 if (message_data.field9) {
305 message.mutable_field9()->set_value(message_data.field9.value());
306 }
307 return message;
308}
309
310void CheckMessageEqual(
311 const proto_json::messages::WrapperMessage& lhs,
312 const proto_json::messages::WrapperMessage& rhs
313) {
314 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
315 EXPECT_TRUE((lhs.has_field2() && rhs.has_field2()) || (!lhs.has_field2() && !rhs.has_field2()));
316 EXPECT_TRUE((lhs.has_field3() && rhs.has_field3()) || (!lhs.has_field3() && !rhs.has_field3()));
317 EXPECT_TRUE((lhs.has_field4() && rhs.has_field4()) || (!lhs.has_field4() && !rhs.has_field4()));
318 EXPECT_TRUE((lhs.has_field5() && rhs.has_field5()) || (!lhs.has_field5() && !rhs.has_field5()));
319 EXPECT_TRUE((lhs.has_field6() && rhs.has_field6()) || (!lhs.has_field6() && !rhs.has_field6()));
320 EXPECT_TRUE((lhs.has_field7() && rhs.has_field7()) || (!lhs.has_field7() && !rhs.has_field7()));
321 EXPECT_TRUE((lhs.has_field8() && rhs.has_field8()) || (!lhs.has_field8() && !rhs.has_field8()));
322 EXPECT_TRUE((lhs.has_field9() && rhs.has_field9()) || (!lhs.has_field9() && !rhs.has_field9()));
323
324 EXPECT_EQ(lhs.field1().value(), rhs.field1().value());
325 EXPECT_EQ(lhs.field2().value(), rhs.field2().value());
326 EXPECT_EQ(lhs.field3().value(), rhs.field3().value());
327 EXPECT_EQ(lhs.field4().value(), rhs.field4().value());
328 EXPECT_EQ(lhs.field5().value(), rhs.field5().value());
329 EXPECT_EQ(lhs.field6().value(), rhs.field6().value());
330 EXPECT_EQ(lhs.field7().value(), rhs.field7().value());
331 EXPECT_EQ(lhs.field8().value(), rhs.field8().value());
332 EXPECT_EQ(lhs.field9().value(), rhs.field9().value());
333}
334
335proto_json::messages::FieldMaskMessage PrepareTestData(const FieldMaskMessageData& message_data) {
336 proto_json::messages::FieldMaskMessage message;
337
338 if (!message_data.field1) {
339 return message;
340 }
341
342 (void)message.mutable_field1();
343
344 for (const auto& path : message_data.field1.value()) {
345 message.mutable_field1()->add_paths(path);
346 }
347
348 return message;
349}
350
351void CheckMessageEqual(const ::google::protobuf::FieldMask& lhs, const ::google::protobuf::FieldMask& rhs) {
352 std::vector<std::string> mask_lhs, mask_rhs;
353
354 for (const auto& path : lhs.paths()) {
355 mask_lhs.push_back(path);
356 }
357
358 for (const auto& path : rhs.paths()) {
359 mask_rhs.push_back(path);
360 }
361
362 std::sort(mask_lhs.begin(), mask_lhs.end());
363 std::sort(mask_rhs.begin(), mask_rhs.end());
364
365 EXPECT_EQ(mask_lhs, mask_rhs);
366}
367
368void CheckMessageEqual(
369 const proto_json::messages::FieldMaskMessage& lhs,
370 const proto_json::messages::FieldMaskMessage& rhs
371) {
372 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
373 CheckMessageEqual(lhs.field1(), rhs.field1());
374}
375
376proto_json::messages::DurationMessage PrepareTestData(const DurationMessageData& message_data) {
377 proto_json::messages::DurationMessage message;
378
379 if (!message_data.do_not_set) {
380 message.mutable_field1()->set_seconds(message_data.seconds);
381 message.mutable_field1()->set_nanos(message_data.nanos);
382 }
383
384 return message;
385}
386
387void CheckMessageEqual(const ::google::protobuf::Duration& lhs, const ::google::protobuf::Duration& rhs) {
388 EXPECT_EQ(lhs.seconds(), rhs.seconds());
389 EXPECT_EQ(lhs.nanos(), rhs.nanos());
390}
391
392void CheckMessageEqual(
393 const proto_json::messages::DurationMessage& lhs,
394 const proto_json::messages::DurationMessage& rhs
395) {
396 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
397 CheckMessageEqual(lhs.field1(), rhs.field1());
398}
399
400proto_json::messages::TimestampMessage PrepareTestData(const TimestampMessageData& message_data) {
401 proto_json::messages::TimestampMessage message;
402
403 if (!message_data.do_not_set) {
404 message.mutable_field1()->set_seconds(message_data.seconds);
405 message.mutable_field1()->set_nanos(message_data.nanos);
406 }
407
408 return message;
409}
410
411void CheckMessageEqual(const ::google::protobuf::Timestamp& lhs, const ::google::protobuf::Timestamp& rhs) {
412 EXPECT_EQ(lhs.seconds(), rhs.seconds());
413 EXPECT_EQ(lhs.nanos(), rhs.nanos());
414}
415
416void CheckMessageEqual(
417 const proto_json::messages::TimestampMessage& lhs,
418 const proto_json::messages::TimestampMessage& rhs
419) {
420 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
421 CheckMessageEqual(lhs.field1(), rhs.field1());
422}
423
424proto_json::messages::ValueMessage PrepareTestData(const ValueMessageData& message_data) {
425 struct Visitor {
426 proto_json::messages::ValueMessage result;
427
428 proto_json::messages::ValueMessage operator()(const ProtoValue& val) {
429 *result.mutable_field1() = ProtoValueToNative(val);
430 return result;
431 }
432
433 proto_json::messages::ValueMessage operator()(const std::vector<ProtoValue>& val) {
434 auto& arr = *result.mutable_field1()->mutable_list_value();
435
436 for (const auto& item : val) {
437 *arr.add_values() = ProtoValueToNative(item);
438 }
439
440 return result;
441 }
442
443 proto_json::messages::ValueMessage operator()(const std::map<std::string, ProtoValue>& val) {
444 auto& fields = *result.mutable_field1()->mutable_struct_value()->mutable_fields();
445
446 for (const auto& [key, value] : val) {
447 fields[key] = ProtoValueToNative(value);
448 }
449
450 return result;
451 }
452 };
453
454 if (message_data.field1) {
455 return std::visit(Visitor{}, *message_data.field1);
456 } else {
457 return proto_json::messages::ValueMessage{};
458 }
459}
460
461void CheckMessageEqual(const ::google::protobuf::Value& lhs, const ::google::protobuf::Value& rhs) {
462 if (lhs.has_null_value()) {
463 ASSERT_TRUE(rhs.has_null_value());
464 EXPECT_EQ(lhs.null_value(), rhs.null_value());
465 } else if (lhs.has_number_value()) {
466 ASSERT_TRUE(rhs.has_number_value());
467 EXPECT_EQ(lhs.number_value(), rhs.number_value());
468 } else if (lhs.has_string_value()) {
469 ASSERT_TRUE(rhs.has_string_value());
470 EXPECT_EQ(lhs.string_value(), rhs.string_value());
471 } else if (lhs.has_bool_value()) {
472 ASSERT_TRUE(rhs.has_bool_value());
473 EXPECT_EQ(lhs.bool_value(), rhs.bool_value());
474 } else if (lhs.has_list_value()) {
475 ASSERT_TRUE(rhs.has_list_value());
476 CheckMessageEqual(lhs.list_value(), rhs.list_value());
477 } else if (lhs.has_struct_value()) {
478 ASSERT_TRUE(rhs.has_struct_value());
479 CheckMessageEqual(lhs.struct_value(), rhs.struct_value());
480 } else {
481 EXPECT_TRUE(
482 !rhs.has_null_value() && !rhs.has_number_value() && !rhs.has_string_value() && !rhs.has_bool_value() &&
483 !rhs.has_list_value() && !rhs.has_struct_value()
484 );
485 }
486}
487
488void CheckMessageEqual(const ::google::protobuf::ListValue& lhs, const ::google::protobuf::ListValue& rhs) {
489 AreProtobufRepeatedEqual(lhs.values(), rhs.values());
490}
491
492void CheckMessageEqual(const ::google::protobuf::Struct& lhs, const ::google::protobuf::Struct& rhs) {
493 AreProtobufMapsEqual(lhs.fields(), rhs.fields());
494}
495
496void CheckMessageEqual(const proto_json::messages::ValueMessage& lhs, const proto_json::messages::ValueMessage& rhs) {
497 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
498 CheckMessageEqual(lhs.field1(), rhs.field1());
499}
500
501template <typename T>
502void CheckAnyPayloadEqual(const ::google::protobuf::Any& lhs, const ::google::protobuf::Any& rhs) {
503 ASSERT_TRUE(lhs.Is<T>());
504 ASSERT_TRUE(rhs.Is<T>());
505
506 T lhs_payload, rhs_payload;
507
508 ASSERT_TRUE(lhs.UnpackTo(&lhs_payload));
509 ASSERT_TRUE(rhs.UnpackTo(&rhs_payload));
510
511 CheckMessageEqual(lhs_payload, rhs_payload);
512}
513
514proto_json::messages::AnyMessage PrepareTestData(const AnyMessageData& message_data) {
515 struct Visitor {
516 ::google::protobuf::Any result;
517
518 ::google::protobuf::Any operator()(const Int32MessageData& payload) {
519 auto msg = PrepareTestData(payload);
520
521 if (!result.PackFrom(msg)) {
522 throw std::runtime_error("Failed to create 'google.protobuf.Any'");
523 }
524
525 return result;
526 }
527
528 ::google::protobuf::Any operator()(const DurationMessageData& payload) {
529 const auto msg = PrepareTestData(payload);
530
531 if (!result.PackFrom(msg.field1())) {
532 throw std::runtime_error("Failed to create 'google.protobuf.Any'");
533 }
534
535 return result;
536 }
537
538 ::google::protobuf::Any operator()(const ValueMessageData& payload) {
539 const auto msg = PrepareTestData(payload);
540
541 if (!result.PackFrom(msg.field1())) {
542 throw std::runtime_error("Failed to create 'google.protobuf.Any'");
543 }
544
545 return result;
546 }
547
548 ::google::protobuf::Any operator()(const RawAnyData& payload) {
549 result.set_type_url(payload.type_url);
550 result.set_value(payload.value);
551 return result;
552 }
553 };
554
555 proto_json::messages::AnyMessage result;
556
557 if (!message_data.field1) {
558 return result;
559 }
560
561 auto any_message = std::visit(Visitor{}, message_data.field1.value());
562
563 if (!message_data.add_nesting) {
564 *result.mutable_field1() = std::move(any_message);
565 } else {
566 ::google::protobuf::Any top;
567
568 if (!top.PackFrom(any_message)) {
569 throw std::runtime_error("Failed to create top-level 'google.protobuf.Any'");
570 }
571
572 *result.mutable_field1() = std::move(top);
573 }
574
575 return result;
576}
577
578void CheckMessageEqual(const ::google::protobuf::Any& lhs, const ::google::protobuf::Any& rhs) {
579 if (lhs.Is<proto_json::messages::Int32Message>()) {
580 CheckAnyPayloadEqual<proto_json::messages::Int32Message>(lhs, rhs);
581 } else if (lhs.Is<::google::protobuf::Duration>()) {
582 CheckAnyPayloadEqual<::google::protobuf::Duration>(lhs, rhs);
583 } else if (lhs.Is<::google::protobuf::Value>()) {
584 CheckAnyPayloadEqual<::google::protobuf::Value>(lhs, rhs);
585 } else if (lhs.Is<::google::protobuf::Any>()) {
586 CheckAnyPayloadEqual<::google::protobuf::Any>(lhs, rhs);
587 } else {
588 EXPECT_EQ(lhs.type_url(), rhs.type_url());
589 EXPECT_EQ(lhs.value(), rhs.value());
590 }
591}
592
593void CheckMessageEqual(const proto_json::messages::AnyMessage& lhs, const proto_json::messages::AnyMessage& rhs) {
594 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
595
596 if (lhs.has_field1()) {
597 CheckMessageEqual(lhs.field1(), rhs.field1());
598 }
599}
600
601proto_json::messages::OneofMessage PrepareTestData(const OneofMessageData& message_data) {
602 proto_json::messages::OneofMessage result;
603
604 if (message_data.field1) {
605 result.set_field1(message_data.field1.value());
606 } else if (message_data.field2) {
607 result.set_field2(message_data.field2.value());
608 }
609
610 return result;
611}
612
613void CheckMessageEqual(const proto_json::messages::OneofMessage& lhs, const proto_json::messages::OneofMessage& rhs) {
614 if (lhs.has_field1()) {
615 EXPECT_TRUE(rhs.has_field1());
616 EXPECT_EQ(lhs.field1(), rhs.field1());
617 } else if (lhs.has_field2()) {
618 EXPECT_TRUE(rhs.has_field2());
619 EXPECT_EQ(lhs.field2(), rhs.field2());
620 } else {
621 EXPECT_FALSE(rhs.has_field1() || rhs.has_field2());
622 }
623}
624
625proto_json::messages::RepeatedMessage PrepareTestData(const RepeatedMessageData& message_data) {
626 proto_json::messages::RepeatedMessage result;
627
628 for (const auto& item : message_data.field1) {
629 result.add_field1(item);
630 }
631
632 for (const auto& item : message_data.field2) {
633 *result.add_field2() = PrepareTestData(item);
634 }
635
636 for (const auto& item : message_data.field3) {
637 *result.add_field3() = PrepareTestData(item).field1();
638 }
639
640 return result;
641}
642
643void CheckMessageEqual(
644 const proto_json::messages::RepeatedMessage& lhs,
645 const proto_json::messages::RepeatedMessage& rhs
646) {
647 AreProtobufRepeatedEqual(lhs.field1(), rhs.field1());
648 AreProtobufRepeatedEqual(lhs.field2(), rhs.field2());
649 AreProtobufRepeatedEqual(lhs.field3(), rhs.field3());
650}
651
652proto_json::messages::MapMessage PrepareTestData(const MapMessageData& message_data) {
653 proto_json::messages::MapMessage result;
654
655 for (const auto& [key, val] : message_data.field1) {
656 (*result.mutable_field1())[key] = val;
657 }
658
659 for (const auto& [key, val] : message_data.field2) {
660 (*result.mutable_field2())[key] = val;
661 }
662
663 for (const auto& [key, val] : message_data.field3) {
664 (*result.mutable_field3())[key] = val;
665 }
666
667 for (const auto& [key, val] : message_data.field4) {
668 (*result.mutable_field4())[key] = val;
669 }
670
671 for (const auto& [key, val] : message_data.field5) {
672 (*result.mutable_field5())[key] = val;
673 }
674
675 for (const auto& [key, val] : message_data.field6) {
676 (*result.mutable_field6())[key] = PrepareTestData(val);
677 }
678
679 for (const auto& [key, val] : message_data.field7) {
680 (*result.mutable_field7())[key] = PrepareTestData(val).field1();
681 }
682
683 return result;
684}
685
686void CheckMessageEqual(const proto_json::messages::MapMessage& lhs, const proto_json::messages::MapMessage& rhs) {
687 AreProtobufMapsEqual(lhs.field1(), rhs.field1());
688 AreProtobufMapsEqual(lhs.field2(), rhs.field2());
689 AreProtobufMapsEqual(lhs.field3(), rhs.field3());
690 AreProtobufMapsEqual(lhs.field4(), rhs.field4());
691 AreProtobufMapsEqual(lhs.field5(), rhs.field5());
692 AreProtobufMapsEqual(lhs.field6(), rhs.field6());
693 AreProtobufMapsEqual(lhs.field7(), rhs.field7());
694}
695
696proto_json::messages::NullValueMessage PrepareTestData(const NullValueMessageData& message_data) {
697 proto_json::messages::NullValueMessage result;
698 result.set_field1(message_data.field1);
699
700 if (message_data.field2) {
701 result.set_field2(message_data.field2.value());
702 }
703
704 for (const auto& item : message_data.field3) {
705 result.add_field3(item);
706 }
707
708 for (const auto& [key, val] : message_data.field4) {
709 (*result.mutable_field4())[key] = val;
710 }
711
712 return result;
713}
714
715void CheckMessageEqual(
716 const proto_json::messages::NullValueMessage& lhs,
717 const proto_json::messages::NullValueMessage& rhs
718) {
719 EXPECT_EQ(lhs.field1(), rhs.field1());
720
721 if (lhs.has_field2()) {
722 EXPECT_TRUE(rhs.has_field2());
723 EXPECT_EQ(lhs.field2(), rhs.field2());
724 } else {
725 EXPECT_FALSE(rhs.has_field2());
726 }
727
728 AreProtobufRepeatedEqual(lhs.field3(), rhs.field3());
729 AreProtobufMapsEqual(lhs.field4(), rhs.field4());
730}
731
732proto_json::messages::PresenceMessage PrepareTestData(const PresenceMessageData& message_data) {
733 proto_json::messages::PresenceMessage result;
734
735 result.set_field1(message_data.field1);
736
737 if (message_data.field2) {
738 result.set_field2(message_data.field2.value());
739 }
740
741 if (message_data.field3) {
742 result.mutable_field3()->set_field1(message_data.field3->field1);
743 result.mutable_field3()->set_field2(message_data.field3->field2);
744 result.mutable_field3()->set_field3(message_data.field3->field3);
745 }
746
747 if (!message_data.field4.empty()) {
748 for (const auto& val : message_data.field4) {
749 result.add_field4(val);
750 }
751 }
752
753 if (!message_data.field5.empty()) {
754 for (const auto& [key, val] : message_data.field5) {
755 (*result.mutable_field5())[key] = val;
756 }
757 }
758
759 return result;
760}
761
762void CheckMessageEqual(
763 const proto_json::messages::PresenceMessage& lhs,
764 const proto_json::messages::PresenceMessage& rhs
765) {
766 EXPECT_EQ(lhs.field1(), rhs.field1());
767
768 if (lhs.has_field2()) {
769 EXPECT_TRUE(rhs.has_field2());
770 EXPECT_EQ(lhs.field2(), rhs.field2());
771 } else {
772 EXPECT_FALSE(rhs.has_field2());
773 }
774
775 if (lhs.has_field3()) {
776 EXPECT_TRUE(rhs.has_field3());
777 CheckMessageEqual(lhs.field3(), rhs.field3());
778 } else {
779 EXPECT_FALSE(rhs.has_field3());
780 }
781
782 AreProtobufRepeatedEqual(lhs.field4(), rhs.field4());
783 AreProtobufMapsEqual(lhs.field5(), rhs.field5());
784}
785
786proto_json::messages::UnknownFieldMessage PrepareTestData(const UnknownFieldMessageData& message_data) {
787 proto_json::messages::UnknownFieldMessage result;
788
789 *result.mutable_field1() = PrepareTestData(message_data.field1);
790
791 for (const auto& item : message_data.field2) {
792 *result.add_field2() = PrepareTestData(item);
793 }
794
795 for (const auto& [key, val] : message_data.field3) {
796 (*result.mutable_field3())[key] = PrepareTestData(val);
797 }
798
799 return result;
800}
801
802void CheckMessageEqual(
803 const proto_json::messages::UnknownFieldMessage& lhs,
804 const proto_json::messages::UnknownFieldMessage& rhs
805) {
806 EXPECT_TRUE((lhs.has_field1() && rhs.has_field1()) || (!lhs.has_field1() && !rhs.has_field1()));
807 CheckMessageEqual(lhs.field1(), rhs.field1());
808
809 AreProtobufRepeatedEqual(lhs.field2(), rhs.field2());
810 AreProtobufMapsEqual(lhs.field3(), rhs.field3());
811}
812
813} // namespace protobuf::json::tests
814
815USERVER_NAMESPACE_END