1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: jschorr@google.com (Joseph Schorr)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11 //
12 // TODO: Move some of these tests to field_comparator_test.cc.
13
14 #include "google/protobuf/util/message_differencer.h"
15
16 #include <algorithm>
17 #include <random>
18 #include <string>
19 #include <vector>
20
21 #include "google/protobuf/stubs/common.h"
22 #include <gmock/gmock.h>
23 #include "google/protobuf/testing/googletest.h"
24 #include <gtest/gtest.h>
25 #include "absl/functional/bind_front.h"
26 #include "absl/log/absl_check.h"
27 #include "absl/memory/memory.h"
28 #include "absl/strings/str_cat.h"
29 #include "absl/strings/str_split.h"
30 #include "absl/strings/string_view.h"
31 #include "google/protobuf/any_test.pb.h"
32 #include "google/protobuf/descriptor.h"
33 #include "google/protobuf/map_test_util.h"
34 #include "google/protobuf/map_unittest.pb.h"
35 #include "google/protobuf/message.h"
36 #include "google/protobuf/test_util.h"
37 #include "google/protobuf/text_format.h"
38 #include "google/protobuf/unittest.pb.h"
39 #include "google/protobuf/util/field_comparator.h"
40 #include "google/protobuf/util/message_differencer_unittest.pb.h"
41 #include "google/protobuf/util/message_differencer_unittest_proto3.pb.h"
42 #include "google/protobuf/wire_format.h"
43 #include "google/protobuf/wire_format_lite.h"
44
45
46 namespace google {
47 namespace protobuf {
48
49 namespace internal {
50 class UnsetFieldsMetadataMessageDifferencerTestUtil {
51 public:
AddExplicitUnsetField(const Message & message,const FieldDescriptor & fd,TextFormat::Parser::UnsetFieldsMetadata * metadata)52 static void AddExplicitUnsetField(
53 const Message& message, const FieldDescriptor& fd,
54 TextFormat::Parser::UnsetFieldsMetadata* metadata) {
55 metadata->ids_.insert(metadata->GetUnsetFieldId(message, fd));
56 }
57 };
58 } // namespace internal
59
60 namespace {
61
62 using ::google::protobuf::internal::UnsetFieldsMetadataMessageDifferencerTestUtil;
63
64
MakeTestNoPresenceField()65 proto3_unittest::TestNoPresenceField MakeTestNoPresenceField() {
66 proto3_unittest::TestNoPresenceField msg1, msg2;
67 msg1.set_no_presence_bool(true);
68 msg1.set_no_presence_bool2(true);
69 msg1.set_no_presence_bool3(true);
70 msg1.set_no_presence_string("yolo");
71 msg2 = msg1;
72 *msg1.mutable_no_presence_nested() = msg2;
73 *msg1.add_no_presence_repeated_nested() = msg2;
74 return msg1;
75 }
76
GetFieldDescriptor(const Message & message,const std::string & field_name)77 const FieldDescriptor* GetFieldDescriptor(const Message& message,
78 const std::string& field_name) {
79 std::vector<std::string> field_path =
80 absl::StrSplit(field_name, ".", absl::SkipEmpty());
81 const Descriptor* descriptor = message.GetDescriptor();
82 const FieldDescriptor* field = nullptr;
83 for (int i = 0; i < field_path.size(); i++) {
84 field = descriptor->FindFieldByName(field_path[i]);
85 descriptor = field->message_type();
86 }
87 return field;
88 }
89
ExpectEqualsWithDifferencer(util::MessageDifferencer * differencer,const Message & msg1,const Message & msg2)90 void ExpectEqualsWithDifferencer(util::MessageDifferencer* differencer,
91 const Message& msg1, const Message& msg2) {
92 differencer->set_scope(util::MessageDifferencer::FULL);
93 EXPECT_TRUE(differencer->Compare(msg1, msg2));
94
95 differencer->set_scope(util::MessageDifferencer::PARTIAL);
96 EXPECT_TRUE(differencer->Compare(msg1, msg2));
97 }
98
TEST(MessageDifferencerTest,BasicEqualityTest)99 TEST(MessageDifferencerTest, BasicEqualityTest) {
100 // Create the testing protos
101 unittest::TestAllTypes msg1;
102 unittest::TestAllTypes msg2;
103
104 TestUtil::SetAllFields(&msg1);
105 TestUtil::SetAllFields(&msg2);
106
107 // Compare
108 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
109 }
110
TEST(MessageDifferencerTest,BasicInequalityTest)111 TEST(MessageDifferencerTest, BasicInequalityTest) {
112 // Create the testing protos
113 unittest::TestAllTypes msg1;
114 unittest::TestAllTypes msg2;
115
116 TestUtil::SetAllFields(&msg1);
117 TestUtil::SetAllFields(&msg2);
118
119 msg1.set_optional_int32(-1);
120
121 // Compare
122 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
123 }
124
TEST(MessageDifferencerTest,RepeatedFieldInequalityTest)125 TEST(MessageDifferencerTest, RepeatedFieldInequalityTest) {
126 // Create the testing protos
127 unittest::TestAllTypes msg1;
128 unittest::TestAllTypes msg2;
129
130 TestUtil::SetAllFields(&msg1);
131 TestUtil::SetAllFields(&msg2);
132
133 msg1.add_repeated_int32(-1);
134
135 // Compare
136 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
137 }
138
TEST(MessageDifferencerTest,RepeatedFieldSetOptimizationTest)139 TEST(MessageDifferencerTest, RepeatedFieldSetOptimizationTest) {
140 util::MessageDifferencer differencer;
141 protobuf_unittest::TestDiffMessage msg1;
142 protobuf_unittest::TestDiffMessage msg2;
143 protobuf_unittest::TestDiffMessage::Item* item1 = msg1.add_item();
144 protobuf_unittest::TestDiffMessage::Item* item2 = msg2.add_item();
145 differencer.TreatAsSet(item1->GetDescriptor()->FindFieldByName("ra"));
146 differencer.TreatAsSet(item2->GetDescriptor()->FindFieldByName("ra"));
147 for (int i = 0; i < 1000; i++) {
148 item1->add_ra(i);
149 item2->add_ra(i);
150 }
151 EXPECT_TRUE(differencer.Compare(msg1, msg2));
152 item2->add_ra(1001);
153 EXPECT_FALSE(differencer.Compare(msg1, msg2));
154 item1->add_ra(1001);
155 EXPECT_TRUE(differencer.Compare(msg1, msg2));
156 item1->add_ra(1002);
157 EXPECT_FALSE(differencer.Compare(msg1, msg2));
158 }
159
TEST(MessageDifferencerTest,MapFieldEqualityTest)160 TEST(MessageDifferencerTest, MapFieldEqualityTest) {
161 // Create the testing protos
162 unittest::TestMap msg1;
163 unittest::TestMap msg2;
164
165 MapReflectionTester tester(unittest::TestMap::descriptor());
166 tester.SetMapFieldsViaReflection(&msg1);
167 tester.SetMapFieldsViaReflection(&msg2);
168 tester.SwapMapsViaReflection(&msg1);
169
170 // Compare
171 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
172
173 // Get map entries by index will sync map to repeated field
174 MapTestUtil::GetMapEntries(msg1, 0);
175 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
176
177 // Compare values not match
178 (*msg1.mutable_map_int32_int32())[1] = 2;
179 (*msg2.mutable_map_int32_int32())[1] = 3;
180 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
181
182 // Compare keys not match
183 msg1.Clear();
184 msg2.Clear();
185 (*msg1.mutable_map_string_string())["1"] = "";
186 (*msg2.mutable_map_string_string())["2"] = "";
187 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
188
189 // Compare message values not match
190 msg1.Clear();
191 msg2.Clear();
192 (*msg1.mutable_map_int32_foreign_message())[1].set_c(1);
193 (*msg2.mutable_map_int32_foreign_message())[1].set_c(2);
194 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
195 }
196
TEST(MessageDifferencerTest,BasicPartialEqualityTest)197 TEST(MessageDifferencerTest, BasicPartialEqualityTest) {
198 // Create the testing protos
199 unittest::TestAllTypes msg1;
200 unittest::TestAllTypes msg2;
201
202 TestUtil::SetAllFields(&msg1);
203 TestUtil::SetAllFields(&msg2);
204
205 // Compare
206 util::MessageDifferencer differencer;
207 differencer.set_scope(util::MessageDifferencer::PARTIAL);
208 EXPECT_TRUE(differencer.Compare(msg1, msg2));
209 }
210
TEST(MessageDifferencerTest,BasicPartialEqualityTestNoPresenceForceCompare)211 TEST(MessageDifferencerTest, BasicPartialEqualityTestNoPresenceForceCompare) {
212 util::MessageDifferencer differencer;
213 differencer.set_scope(util::MessageDifferencer::PARTIAL);
214 differencer.set_force_compare_no_presence(true);
215
216 // Create the testing protos
217 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
218 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
219 EXPECT_TRUE(differencer.Compare(msg1, msg2));
220 }
221
TEST(MessageDifferencerTest,PartialEqualityTestExtraField)222 TEST(MessageDifferencerTest, PartialEqualityTestExtraField) {
223 // Create the testing protos
224 unittest::TestAllTypes msg1;
225 unittest::TestAllTypes msg2;
226
227 TestUtil::SetAllFields(&msg1);
228 TestUtil::SetAllFields(&msg2);
229
230 msg1.clear_optional_int32();
231
232 // Compare
233 util::MessageDifferencer differencer;
234 differencer.set_scope(util::MessageDifferencer::PARTIAL);
235 EXPECT_TRUE(differencer.Compare(msg1, msg2));
236 }
237
TEST(MessageDifferencerTest,PartialEqualityTestExtraFieldNoPresenceForceCompare)238 TEST(MessageDifferencerTest,
239 PartialEqualityTestExtraFieldNoPresenceForceCompare) {
240 util::MessageDifferencer force_compare_differencer;
241 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
242 force_compare_differencer.set_force_compare_no_presence(true);
243
244 // This differencer is not setting force_compare_no_presence.
245 util::MessageDifferencer default_differencer;
246 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
247 default_differencer.set_force_compare_no_presence(false);
248
249
250 // Create the testing protos
251 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
252 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
253
254 // Clearing a no presence field inside a repeated field in a nested message.
255 msg1.mutable_no_presence_repeated_nested(0)->clear_no_presence_bool();
256 EXPECT_FALSE(force_compare_differencer.Compare(msg1, msg2));
257 EXPECT_THAT(force_compare_differencer.NoPresenceFieldsCausingFailure(),
258 testing::UnorderedElementsAre(
259 "proto3_unittest.TestNoPresenceField.no_presence_bool"));
260 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
261 EXPECT_TRUE(default_differencer.NoPresenceFieldsCausingFailure().empty());
262 force_compare_differencer.ReportDifferencesTo(nullptr);
263
264 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
265 EXPECT_TRUE(
266 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
267 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
268 EXPECT_TRUE(default_differencer.NoPresenceFieldsCausingFailure().empty());
269 }
270
271
TEST(MessageDifferencerTest,PartialEqualityTestForceCompareWorksForRepeatedField)272 TEST(MessageDifferencerTest,
273 PartialEqualityTestForceCompareWorksForRepeatedField) {
274 util::MessageDifferencer force_compare_differencer;
275 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
276 force_compare_differencer.set_force_compare_no_presence(true);
277
278 // This differencer is not setting force_compare_no_presence.
279 util::MessageDifferencer default_differencer;
280 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
281 default_differencer.set_force_compare_no_presence(false);
282
283 // Repeated fields always have presence, so clearing them would remove them
284 // from the comparison.
285 // Create the testing protos
286 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
287 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
288
289 msg1.clear_no_presence_repeated_nested();
290 EXPECT_TRUE(force_compare_differencer.Compare(msg1, msg2));
291 EXPECT_TRUE(
292 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
293 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
294 EXPECT_TRUE(default_differencer.NoPresenceFieldsCausingFailure().empty());
295
296 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
297 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
298 }
299
TEST(MessageDifferencerTest,PartialEqualityTestForceCompareWorksForRepeatedFieldInstance)300 TEST(MessageDifferencerTest,
301 PartialEqualityTestForceCompareWorksForRepeatedFieldInstance) {
302 util::MessageDifferencer force_compare_differencer;
303 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
304 force_compare_differencer.set_force_compare_no_presence(true);
305
306 // This differencer is not setting force_compare_no_presence.
307 util::MessageDifferencer default_differencer;
308 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
309 default_differencer.set_force_compare_no_presence(false);
310
311 // Clearing a field inside a repeated field will trigger a failure when
312 // forcing comparison for no presence fields.
313 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
314 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
315
316 msg1.mutable_no_presence_nested()->clear_no_presence_bool();
317 EXPECT_FALSE(force_compare_differencer.Compare(msg1, msg2));
318 EXPECT_THAT(force_compare_differencer.NoPresenceFieldsCausingFailure(),
319 testing::UnorderedElementsAre(
320 "proto3_unittest.TestNoPresenceField.no_presence_bool"));
321 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
322
323 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
324 EXPECT_TRUE(
325 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
326 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
327 }
328
TEST(MessageDifferencerTest,PartialEqualityTestForceCompareIsNoOptForNestedMessages)329 TEST(MessageDifferencerTest,
330 PartialEqualityTestForceCompareIsNoOptForNestedMessages) {
331 util::MessageDifferencer force_compare_differencer;
332 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
333 force_compare_differencer.set_force_compare_no_presence(true);
334
335 // This differencer is not setting force_compare_no_presence.
336 util::MessageDifferencer default_differencer;
337 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
338 default_differencer.set_force_compare_no_presence(false);
339
340 // Nested fields always have presence, so clearing them would remove them
341 // from the comparison.
342 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
343 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
344
345 msg1.clear_no_presence_nested();
346 EXPECT_TRUE(force_compare_differencer.Compare(msg1, msg2));
347 EXPECT_TRUE(
348 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
349 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
350
351 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
352 EXPECT_TRUE(
353 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
354 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
355
356 // Creating an instance of the nested field will cause the comparison to fail
357 // since it contains a no presence singualr field.
358 msg1.mutable_no_presence_nested();
359 EXPECT_FALSE(force_compare_differencer.Compare(msg1, msg2));
360 EXPECT_THAT(force_compare_differencer.NoPresenceFieldsCausingFailure(),
361 testing::UnorderedElementsAre(
362 "proto3_unittest.TestNoPresenceField.no_presence_bool"));
363 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
364
365 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
366 EXPECT_TRUE(
367 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
368 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
369 }
370
TEST(MessageDifferencerTest,PartialEqualityTestSingularNoPresenceFieldMissing)371 TEST(MessageDifferencerTest,
372 PartialEqualityTestSingularNoPresenceFieldMissing) {
373 util::MessageDifferencer force_compare_differencer;
374 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
375 force_compare_differencer.set_force_compare_no_presence(true);
376
377 // This differencer is not setting force_compare_no_presence.
378 util::MessageDifferencer default_differencer;
379 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
380 default_differencer.set_force_compare_no_presence(false);
381
382 // When clearing a singular no presence field, it will be included in the
383 // comparison.
384 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
385 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
386
387 msg1.clear_no_presence_bool();
388 EXPECT_FALSE(force_compare_differencer.Compare(msg1, msg2));
389 EXPECT_TRUE(
390 !force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
391 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
392
393 EXPECT_FALSE(force_compare_differencer.Compare(msg2, msg1));
394 EXPECT_TRUE(
395 force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
396 EXPECT_FALSE(default_differencer.Compare(msg2, msg1));
397 }
398
TEST(MessageDifferencerTest,PartialEqualityTestBooleanPresenceFieldMissingWithAddress)399 TEST(MessageDifferencerTest,
400 PartialEqualityTestBooleanPresenceFieldMissingWithAddress) {
401 util::MessageDifferencer address_differencer;
402 address_differencer.set_scope(util::MessageDifferencer::PARTIAL);
403
404 // This differencer is not setting force_compare_no_presence.
405 util::MessageDifferencer default_differencer;
406 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
407 default_differencer.set_force_compare_no_presence(false);
408
409 // When clearing a singular no presence field, it will be included in the
410 // comparison.
411 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
412 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
413
414 const FieldDescriptor* fd1 = msg1.GetDescriptor()->FindFieldByNumber(1);
415 TextFormat::Parser::UnsetFieldsMetadata metadata;
416 UnsetFieldsMetadataMessageDifferencerTestUtil::AddExplicitUnsetField(
417 msg1, *fd1, &metadata);
418 address_differencer.set_require_no_presence_fields(metadata);
419
420 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
421 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
422
423 msg1.clear_no_presence_bool();
424
425 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
426 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
427
428 msg2.clear_no_presence_bool();
429
430 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
431 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
432
433 msg1.set_no_presence_bool(true);
434
435 EXPECT_FALSE(default_differencer.Compare(msg1, msg2));
436 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
437 }
438
TEST(MessageDifferencerTest,PartialEqualityTestStringPresenceFieldMissingWithAddress)439 TEST(MessageDifferencerTest,
440 PartialEqualityTestStringPresenceFieldMissingWithAddress) {
441 util::MessageDifferencer address_differencer;
442 address_differencer.set_scope(util::MessageDifferencer::PARTIAL);
443
444 // This differencer is not setting force_compare_no_presence.
445 util::MessageDifferencer default_differencer;
446 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
447 default_differencer.set_force_compare_no_presence(false);
448
449 // When clearing a singular no presence field, it will be included in the
450 // comparison.
451 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
452 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
453
454 const FieldDescriptor* fd1 = msg1.GetDescriptor()->FindFieldByNumber(4);
455 TextFormat::Parser::UnsetFieldsMetadata metadata;
456 UnsetFieldsMetadataMessageDifferencerTestUtil::AddExplicitUnsetField(
457 msg1, *fd1, &metadata);
458 address_differencer.set_require_no_presence_fields(metadata);
459
460 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
461 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
462
463 msg1.clear_no_presence_string();
464
465 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
466 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
467
468 msg2.clear_no_presence_string();
469
470 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
471 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
472
473 msg1.set_no_presence_string("yolo");
474
475 EXPECT_FALSE(default_differencer.Compare(msg1, msg2));
476 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
477 }
478
479 // Ensure multiple booleans are addressed distinctly. This is trivially the case
480 // now, but tests against possible optimizations in the future to use bitfields.
TEST(MessageDifferencerTest,PartialEqualityTestTwoBoolsPresenceFieldMissingWithAddress)481 TEST(MessageDifferencerTest,
482 PartialEqualityTestTwoBoolsPresenceFieldMissingWithAddress) {
483 util::MessageDifferencer address_differencer;
484 address_differencer.set_scope(util::MessageDifferencer::PARTIAL);
485
486 // This differencer is not setting force_compare_no_presence.
487 util::MessageDifferencer default_differencer;
488 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
489 default_differencer.set_force_compare_no_presence(false);
490
491 // When clearing a singular no presence field, it will be included in the
492 // comparison.
493 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
494 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
495
496 const FieldDescriptor* fd1 = msg1.GetDescriptor()->FindFieldByNumber(5);
497 TextFormat::Parser::UnsetFieldsMetadata metadata;
498 UnsetFieldsMetadataMessageDifferencerTestUtil::AddExplicitUnsetField(
499 msg1, *fd1, &metadata);
500 address_differencer.set_require_no_presence_fields(metadata);
501
502 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
503 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
504
505 // Trigger on bool2.
506 msg1.clear_no_presence_bool2();
507
508 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
509 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
510
511 // Triggering on bool2 still ignores bool3.
512 msg1.set_no_presence_bool2(true);
513 msg1.clear_no_presence_bool3();
514
515 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
516 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
517 }
518
TEST(MessageDifferencerTest,PartialEqualityTestBooleanNestedMessagePresenceFieldMissingWithAddress)519 TEST(MessageDifferencerTest,
520 PartialEqualityTestBooleanNestedMessagePresenceFieldMissingWithAddress) {
521 util::MessageDifferencer address_differencer;
522 address_differencer.set_scope(util::MessageDifferencer::PARTIAL);
523
524 // This differencer is not setting force_compare_no_presence.
525 util::MessageDifferencer default_differencer;
526 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
527 default_differencer.set_force_compare_no_presence(false);
528
529 // When clearing a singular no presence field, it will be included in the
530 // comparison.
531 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
532 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
533
534 const FieldDescriptor* fd1 = msg1.GetDescriptor()->FindFieldByNumber(1);
535 TextFormat::Parser::UnsetFieldsMetadata metadata;
536 UnsetFieldsMetadataMessageDifferencerTestUtil::AddExplicitUnsetField(
537 msg1.no_presence_nested(), *fd1, &metadata);
538 address_differencer.set_require_no_presence_fields(metadata);
539
540 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
541 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
542
543 msg1.mutable_no_presence_nested()->clear_no_presence_bool();
544
545 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
546 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
547
548 msg2.mutable_no_presence_nested()->clear_no_presence_bool();
549
550 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
551 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
552
553 msg1.mutable_no_presence_nested()->set_no_presence_bool(true);
554
555 EXPECT_FALSE(default_differencer.Compare(msg1, msg2));
556 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
557 }
558
TEST(MessageDifferencerTest,PartialEqualityTestBooleanRepeatedMessagePresenceFieldMissingWithAddress)559 TEST(MessageDifferencerTest,
560 PartialEqualityTestBooleanRepeatedMessagePresenceFieldMissingWithAddress) {
561 util::MessageDifferencer address_differencer;
562 address_differencer.set_scope(util::MessageDifferencer::PARTIAL);
563
564 // This differencer is not setting force_compare_no_presence.
565 util::MessageDifferencer default_differencer;
566 default_differencer.set_scope(util::MessageDifferencer::PARTIAL);
567 default_differencer.set_force_compare_no_presence(false);
568
569 // When clearing a singular no presence field, it will be included in the
570 // comparison.
571 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
572 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
573
574 const FieldDescriptor* fd1 = msg1.GetDescriptor()->FindFieldByNumber(1);
575 TextFormat::Parser::UnsetFieldsMetadata metadata;
576 UnsetFieldsMetadataMessageDifferencerTestUtil::AddExplicitUnsetField(
577 msg1.no_presence_repeated_nested(0), *fd1, &metadata);
578 address_differencer.set_require_no_presence_fields(metadata);
579
580 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
581 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
582
583 msg1.mutable_no_presence_repeated_nested(0)->clear_no_presence_bool();
584
585 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
586 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
587
588 msg2.mutable_no_presence_repeated_nested(0)->clear_no_presence_bool();
589
590 EXPECT_TRUE(address_differencer.Compare(msg1, msg2));
591 EXPECT_TRUE(default_differencer.Compare(msg1, msg2));
592
593 msg1.mutable_no_presence_repeated_nested(0)->set_no_presence_bool(true);
594
595 EXPECT_FALSE(default_differencer.Compare(msg1, msg2));
596 EXPECT_FALSE(address_differencer.Compare(msg1, msg2));
597 }
598
TEST(MessageDifferencerTest,PartialEqualityTestExtraFieldNoPresenceForceCompareReporterAware)599 TEST(MessageDifferencerTest,
600 PartialEqualityTestExtraFieldNoPresenceForceCompareReporterAware) {
601 std::string output;
602 // Before we can check the output string, we must make sure the
603 // StreamReporter is destroyed because its destructor will
604 // flush the stream.
605 {
606 io::StringOutputStream output_stream(&output);
607 util::MessageDifferencer::StreamReporter reporter(&output_stream);
608
609 util::MessageDifferencer force_compare_differencer;
610 force_compare_differencer.set_scope(util::MessageDifferencer::PARTIAL);
611 force_compare_differencer.set_force_compare_no_presence(true);
612 force_compare_differencer.ReportDifferencesTo(&reporter);
613
614 // Clearing a no presence field inside a repeated field.
615 proto3_unittest::TestNoPresenceField msg1 = MakeTestNoPresenceField();
616 proto3_unittest::TestNoPresenceField msg2 = MakeTestNoPresenceField();
617
618 msg1.mutable_no_presence_repeated_nested(0)->clear_no_presence_bool();
619 EXPECT_FALSE(force_compare_differencer.Compare(msg1, msg2));
620 EXPECT_TRUE(
621 !force_compare_differencer.NoPresenceFieldsCausingFailure().empty());
622 }
623 EXPECT_EQ(output,
624 "added: no_presence_repeated_nested[0].no_presence_bool (added for "
625 "better PARTIAL comparison): true\n");
626 }
627
TEST(MessageDifferencerTest,PartialEqualityTestSkipRequiredField)628 TEST(MessageDifferencerTest, PartialEqualityTestSkipRequiredField) {
629 // Create the testing protos
630 unittest::TestRequired msg1;
631 unittest::TestRequired msg2;
632
633 msg1.set_a(401);
634 msg2.set_a(401);
635 msg2.set_b(402);
636
637 // Compare
638 util::MessageDifferencer differencer;
639 differencer.set_scope(util::MessageDifferencer::PARTIAL);
640 EXPECT_TRUE(differencer.Compare(msg1, msg2));
641 }
642
TEST(MessageDifferencerTest,BasicPartialInequalityTest)643 TEST(MessageDifferencerTest, BasicPartialInequalityTest) {
644 // Create the testing protos
645 unittest::TestAllTypes msg1;
646 unittest::TestAllTypes msg2;
647
648 TestUtil::SetAllFields(&msg1);
649 TestUtil::SetAllFields(&msg2);
650
651 msg1.set_optional_int32(-1);
652
653 // Compare
654 util::MessageDifferencer differencer;
655 differencer.set_scope(util::MessageDifferencer::PARTIAL);
656 EXPECT_FALSE(differencer.Compare(msg1, msg2));
657 }
658
TEST(MessageDifferencerTest,PartialInequalityMissingFieldTest)659 TEST(MessageDifferencerTest, PartialInequalityMissingFieldTest) {
660 // Create the testing protos
661 unittest::TestAllTypes msg1;
662 unittest::TestAllTypes msg2;
663
664 TestUtil::SetAllFields(&msg1);
665 TestUtil::SetAllFields(&msg2);
666
667 msg2.clear_optional_int32();
668
669 // Compare
670 util::MessageDifferencer differencer;
671 differencer.set_scope(util::MessageDifferencer::PARTIAL);
672 EXPECT_FALSE(differencer.Compare(msg1, msg2));
673 }
674
TEST(MessageDifferencerTest,RepeatedFieldPartialInequalityTest)675 TEST(MessageDifferencerTest, RepeatedFieldPartialInequalityTest) {
676 // Create the testing protos
677 unittest::TestAllTypes msg1;
678 unittest::TestAllTypes msg2;
679
680 TestUtil::SetAllFields(&msg1);
681 TestUtil::SetAllFields(&msg2);
682
683 msg1.add_repeated_int32(-1);
684
685 // Compare
686 util::MessageDifferencer differencer;
687 differencer.set_scope(util::MessageDifferencer::PARTIAL);
688 EXPECT_FALSE(differencer.Compare(msg1, msg2));
689 }
690
TEST(MessageDifferencerTest,BasicEquivalencyTest)691 TEST(MessageDifferencerTest, BasicEquivalencyTest) {
692 // Create the testing protos
693 unittest::TestAllTypes msg1;
694 unittest::TestAllTypes msg2;
695
696 TestUtil::SetAllFields(&msg1);
697 TestUtil::SetAllFields(&msg2);
698
699 // Compare
700 EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
701 }
702
TEST(MessageDifferencerTest,EquivalencyNotEqualTest)703 TEST(MessageDifferencerTest, EquivalencyNotEqualTest) {
704 // Create the testing protos
705 unittest::TestAllTypes msg1;
706 unittest::TestAllTypes msg2;
707
708 TestUtil::SetAllFields(&msg1);
709 TestUtil::SetAllFields(&msg2);
710
711 msg1.clear_optional_int32();
712 msg2.set_optional_int32(0);
713
714 // Compare
715 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
716 EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
717 }
718
TEST(MessageDifferencerTest,BasicInequivalencyTest)719 TEST(MessageDifferencerTest, BasicInequivalencyTest) {
720 // Create the testing protos
721 unittest::TestAllTypes msg1;
722 unittest::TestAllTypes msg2;
723
724 TestUtil::SetAllFields(&msg1);
725 TestUtil::SetAllFields(&msg2);
726
727 msg1.set_optional_int32(-1);
728
729 // Compare
730 EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
731 }
732
TEST(MessageDifferencerTest,BasicEquivalencyNonSetTest)733 TEST(MessageDifferencerTest, BasicEquivalencyNonSetTest) {
734 // Create the testing protos
735 unittest::TestAllTypes msg1;
736 unittest::TestAllTypes msg2;
737
738 // Compare
739 EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
740 }
741
TEST(MessageDifferencerTest,BasicInequivalencyNonSetTest)742 TEST(MessageDifferencerTest, BasicInequivalencyNonSetTest) {
743 // Create the testing protos
744 unittest::TestAllTypes msg1;
745 unittest::TestAllTypes msg2;
746
747 msg1.set_optional_int32(-1);
748
749 // Compare
750 EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
751 }
752
TEST(MessageDifferencerTest,BasicPartialEquivalencyTest)753 TEST(MessageDifferencerTest, BasicPartialEquivalencyTest) {
754 // Create the testing protos
755 unittest::TestAllTypes msg1;
756 unittest::TestAllTypes msg2;
757
758 TestUtil::SetAllFields(&msg1);
759 TestUtil::SetAllFields(&msg2);
760
761 // Compare
762 util::MessageDifferencer differencer;
763 differencer.set_message_field_comparison(
764 util::MessageDifferencer::EQUIVALENT);
765 differencer.set_scope(util::MessageDifferencer::PARTIAL);
766 EXPECT_TRUE(differencer.Compare(msg1, msg2));
767 }
768
TEST(MessageDifferencerTest,PartialEquivalencyNotEqualTest)769 TEST(MessageDifferencerTest, PartialEquivalencyNotEqualTest) {
770 // Create the testing protos
771 unittest::TestAllTypes msg1;
772 unittest::TestAllTypes msg2;
773
774 TestUtil::SetAllFields(&msg1);
775 TestUtil::SetAllFields(&msg2);
776
777 msg1.set_optional_int32(0);
778 msg2.clear_optional_int32();
779
780 // Compare
781 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
782 util::MessageDifferencer differencer;
783 differencer.set_message_field_comparison(
784 util::MessageDifferencer::EQUIVALENT);
785 differencer.set_scope(util::MessageDifferencer::PARTIAL);
786 EXPECT_TRUE(differencer.Compare(msg1, msg2));
787 }
788
TEST(MessageDifferencerTest,PartialEquivalencyTestExtraField)789 TEST(MessageDifferencerTest, PartialEquivalencyTestExtraField) {
790 // Create the testing protos
791 unittest::TestAllTypes msg1;
792 unittest::TestAllTypes msg2;
793
794 TestUtil::SetAllFields(&msg1);
795 TestUtil::SetAllFields(&msg2);
796
797 msg1.clear_optional_int32();
798
799 // Compare
800 util::MessageDifferencer differencer;
801 differencer.set_message_field_comparison(
802 util::MessageDifferencer::EQUIVALENT);
803 differencer.set_scope(util::MessageDifferencer::PARTIAL);
804 EXPECT_TRUE(differencer.Compare(msg1, msg2));
805 }
806
TEST(MessageDifferencerTest,PartialEquivalencyTestSkipRequiredField)807 TEST(MessageDifferencerTest, PartialEquivalencyTestSkipRequiredField) {
808 // Create the testing protos
809 unittest::TestRequired msg1;
810 unittest::TestRequired msg2;
811
812 msg1.set_a(401);
813 msg2.set_a(401);
814 msg2.set_b(402);
815
816 // Compare
817 util::MessageDifferencer differencer;
818 differencer.set_message_field_comparison(
819 util::MessageDifferencer::EQUIVALENT);
820 differencer.set_scope(util::MessageDifferencer::PARTIAL);
821 EXPECT_TRUE(differencer.Compare(msg1, msg2));
822 }
823
TEST(MessageDifferencerTest,BasicPartialInequivalencyTest)824 TEST(MessageDifferencerTest, BasicPartialInequivalencyTest) {
825 // Create the testing protos
826 unittest::TestAllTypes msg1;
827 unittest::TestAllTypes msg2;
828
829 TestUtil::SetAllFields(&msg1);
830 TestUtil::SetAllFields(&msg2);
831
832 msg1.set_optional_int32(-1);
833
834 // Compare
835 util::MessageDifferencer differencer;
836 differencer.set_message_field_comparison(
837 util::MessageDifferencer::EQUIVALENT);
838 differencer.set_scope(util::MessageDifferencer::PARTIAL);
839 EXPECT_FALSE(differencer.Compare(msg1, msg2));
840 }
841
TEST(MessageDifferencerTest,BasicPartialEquivalencyNonSetTest)842 TEST(MessageDifferencerTest, BasicPartialEquivalencyNonSetTest) {
843 // Create the testing protos
844 unittest::TestAllTypes msg1;
845 unittest::TestAllTypes msg2;
846
847 // Compare
848 util::MessageDifferencer differencer;
849 differencer.set_message_field_comparison(
850 util::MessageDifferencer::EQUIVALENT);
851 differencer.set_scope(util::MessageDifferencer::PARTIAL);
852 EXPECT_TRUE(differencer.Compare(msg1, msg2));
853 }
854
TEST(MessageDifferencerTest,BasicPartialInequivalencyNonSetTest)855 TEST(MessageDifferencerTest, BasicPartialInequivalencyNonSetTest) {
856 // Create the testing protos
857 unittest::TestAllTypes msg1;
858 unittest::TestAllTypes msg2;
859
860 msg1.set_optional_int32(-1);
861
862 // Compare
863 util::MessageDifferencer differencer;
864 differencer.set_message_field_comparison(
865 util::MessageDifferencer::EQUIVALENT);
866 differencer.set_scope(util::MessageDifferencer::PARTIAL);
867 EXPECT_FALSE(differencer.Compare(msg1, msg2));
868 }
869
TEST(MessageDifferencerTest,ApproximateEqualityTest)870 TEST(MessageDifferencerTest, ApproximateEqualityTest) {
871 // Create the testing protos
872 unittest::TestAllTypes msg1;
873 unittest::TestAllTypes msg2;
874
875 TestUtil::SetAllFields(&msg1);
876 TestUtil::SetAllFields(&msg2);
877
878 // Compare
879 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
880 }
881
TEST(MessageDifferencerTest,ApproximateModifiedEqualityTest)882 TEST(MessageDifferencerTest, ApproximateModifiedEqualityTest) {
883 // Create the testing protos
884 unittest::TestAllTypes msg1;
885 unittest::TestAllTypes msg2;
886
887 TestUtil::SetAllFields(&msg1);
888 TestUtil::SetAllFields(&msg2);
889
890 const float v1 = 2.300005f;
891 const float v2 = 2.300006f;
892 msg1.set_optional_float(v1);
893 msg2.set_optional_float(v2);
894
895 // Compare
896 ASSERT_NE(v1, v2) << "Should not be the same: " << v1 << ", " << v2;
897 ASSERT_FLOAT_EQ(v1, v2) << "Should be approx. equal: " << v1 << ", " << v2;
898 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
899 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
900 }
901
TEST(MessageDifferencerTest,ApproximateEquivalencyTest)902 TEST(MessageDifferencerTest, ApproximateEquivalencyTest) {
903 // Create the testing protos
904 unittest::TestAllTypes msg1;
905 unittest::TestAllTypes msg2;
906
907 TestUtil::SetAllFields(&msg1);
908 TestUtil::SetAllFields(&msg2);
909
910 // Compare
911 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
912 }
913
TEST(MessageDifferencerTest,ApproximateModifiedEquivalencyTest)914 TEST(MessageDifferencerTest, ApproximateModifiedEquivalencyTest) {
915 // Create the testing protos
916 unittest::TestAllTypes msg1;
917 unittest::TestAllTypes msg2;
918
919 TestUtil::SetAllFields(&msg1);
920 TestUtil::SetAllFields(&msg2);
921
922 // Modify the approximateness requirement
923 const float v1 = 2.300005f;
924 const float v2 = 2.300006f;
925 msg1.set_optional_float(v1);
926 msg2.set_optional_float(v2);
927
928 // Compare
929 ASSERT_NE(v1, v2) << "Should not be the same: " << v1 << ", " << v2;
930 ASSERT_FLOAT_EQ(v1, v2) << "Should be approx. equal: " << v1 << ", " << v2;
931 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
932 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
933
934 // Modify the equivalency requirement too
935 msg1.clear_optional_int32();
936 msg2.set_optional_int32(0);
937
938 // Compare. Now should only pass on ApproximatelyEquivalent
939 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
940 EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
941 EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
942 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
943 }
944
TEST(MessageDifferencerTest,ApproximateInequivalencyTest)945 TEST(MessageDifferencerTest, ApproximateInequivalencyTest) {
946 // Create the testing protos
947 unittest::TestAllTypes msg1;
948 unittest::TestAllTypes msg2;
949
950 TestUtil::SetAllFields(&msg1);
951 TestUtil::SetAllFields(&msg2);
952
953 // Should fail on equivalency
954 msg1.set_optional_int32(-1);
955 EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
956
957 // Make these fields the same again.
958 msg1.set_optional_int32(0);
959 msg2.set_optional_int32(0);
960 EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
961
962 // Should fail on approximate equality check
963 const float v1 = 2.3f;
964 const float v2 = 9.3f;
965 msg1.set_optional_float(v1);
966 msg2.set_optional_float(v2);
967 EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
968 }
969
TEST(MessageDifferencerTest,WithinFractionOrMarginFloatTest)970 TEST(MessageDifferencerTest, WithinFractionOrMarginFloatTest) {
971 // Create the testing protos
972 unittest::TestAllTypes msg1;
973 unittest::TestAllTypes msg2;
974
975 TestUtil::SetAllFields(&msg1);
976 TestUtil::SetAllFields(&msg2);
977
978 // Should fail on approximate equality check
979 const float v1 = 100.0f;
980 const float v2 = 109.9f;
981 msg1.set_optional_float(v1);
982 msg2.set_optional_float(v2);
983
984 // Compare
985 util::MessageDifferencer differencer;
986 EXPECT_FALSE(differencer.Compare(msg1, msg2));
987 const FieldDescriptor* fd =
988 msg1.GetDescriptor()->FindFieldByName("optional_float");
989
990 // Set float comparison to exact, margin and fraction value should not matter.
991 differencer.set_float_comparison(util::MessageDifferencer::EXACT);
992 // Set margin for float comparison.
993 differencer.SetFractionAndMargin(fd, 0.0, 10.0);
994 EXPECT_FALSE(differencer.Compare(msg1, msg2));
995
996 // Margin and fraction float comparison is activated when float comparison is
997 // set to approximate.
998 differencer.set_float_comparison(util::MessageDifferencer::APPROXIMATE);
999 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1000
1001 // Test out float comparison with fraction.
1002 differencer.SetFractionAndMargin(fd, 0.2, 0.0);
1003 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1004
1005 // Should fail since the fraction is smaller than error.
1006 differencer.SetFractionAndMargin(fd, 0.01, 0.0);
1007 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1008
1009 // Should pass if either fraction or margin are satisfied.
1010 differencer.SetFractionAndMargin(fd, 0.01, 10.0);
1011 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1012
1013 // Make sure that the margin and fraction only affects the field that it was
1014 // set for.
1015 msg1.set_default_float(v1);
1016 msg2.set_default_float(v2);
1017 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1018 msg1.set_default_float(v1);
1019 msg2.set_default_float(v1);
1020 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1021 }
1022
TEST(MessageDifferencerTest,WithinFractionOrMarginDoubleTest)1023 TEST(MessageDifferencerTest, WithinFractionOrMarginDoubleTest) {
1024 // Create the testing protos
1025 unittest::TestAllTypes msg1;
1026 unittest::TestAllTypes msg2;
1027
1028 TestUtil::SetAllFields(&msg1);
1029 TestUtil::SetAllFields(&msg2);
1030
1031 // Should fail on approximate equality check
1032 const double v1 = 100.0;
1033 const double v2 = 109.9;
1034 msg1.set_optional_double(v1);
1035 msg2.set_optional_double(v2);
1036
1037 // Compare
1038 util::MessageDifferencer differencer;
1039 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1040
1041 // Set comparison to exact, margin and fraction value should not matter.
1042 differencer.set_float_comparison(util::MessageDifferencer::EXACT);
1043 // Set margin for float comparison.
1044 const FieldDescriptor* fd =
1045 msg1.GetDescriptor()->FindFieldByName("optional_double");
1046 differencer.SetFractionAndMargin(fd, 0.0, 10.0);
1047 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1048
1049 // Margin and fraction comparison is activated when float comparison is
1050 // set to approximate.
1051 differencer.set_float_comparison(util::MessageDifferencer::APPROXIMATE);
1052 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1053
1054 // Test out comparison with fraction.
1055 differencer.SetFractionAndMargin(fd, 0.2, 0.0);
1056 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1057
1058 // Should fail since the fraction is smaller than error.
1059 differencer.SetFractionAndMargin(fd, 0.01, 0.0);
1060 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1061
1062 // Should pass if either fraction or margin are satisfied.
1063 differencer.SetFractionAndMargin(fd, 0.01, 10.0);
1064 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1065
1066 // Make sure that the margin and fraction only affects the field that it was
1067 // set for.
1068 msg1.set_default_double(v1);
1069 msg2.set_default_double(v2);
1070 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1071 msg1.set_default_double(v1);
1072 msg2.set_default_double(v1);
1073 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1074 }
1075
TEST(MessageDifferencerTest,WithinDefaultFractionOrMarginDoubleTest)1076 TEST(MessageDifferencerTest, WithinDefaultFractionOrMarginDoubleTest) {
1077 // Create the testing protos
1078 unittest::TestAllTypes msg1;
1079 unittest::TestAllTypes msg2;
1080
1081 TestUtil::SetAllFields(&msg1);
1082 TestUtil::SetAllFields(&msg2);
1083
1084 // Should fail on approximate equality check
1085 const double v1 = 100.0;
1086 const double v2 = 109.9;
1087 msg1.set_optional_double(v1);
1088 msg2.set_optional_double(v2);
1089
1090 util::MessageDifferencer differencer;
1091
1092 // Compare
1093 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1094
1095 // Set up a custom field comparator, with a default fraction and margin for
1096 // float and double comparison.
1097 util::DefaultFieldComparator field_comparator;
1098 field_comparator.SetDefaultFractionAndMargin(0.0, 10.0);
1099 differencer.set_field_comparator(&field_comparator);
1100
1101 // Set comparison to exact, margin and fraction value should not matter.
1102 field_comparator.set_float_comparison(util::DefaultFieldComparator::EXACT);
1103 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1104
1105 // Margin and fraction comparison is activated when float comparison is
1106 // set to approximate.
1107 field_comparator.set_float_comparison(
1108 util::DefaultFieldComparator::APPROXIMATE);
1109 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1110
1111 // Test out comparison with fraction.
1112 field_comparator.SetDefaultFractionAndMargin(0.2, 0.0);
1113 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1114
1115 // Should fail since the fraction is smaller than error.
1116 field_comparator.SetDefaultFractionAndMargin(0.01, 0.0);
1117 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1118
1119 // Should pass if either fraction or margin are satisfied.
1120 field_comparator.SetDefaultFractionAndMargin(0.01, 10.0);
1121 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1122
1123 // Make sure that the default margin and fraction affects all fields
1124 msg1.set_default_double(v1);
1125 msg2.set_default_double(v2);
1126 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1127 }
1128
TEST(MessageDifferencerTest,BasicFieldOrderingsTest)1129 TEST(MessageDifferencerTest, BasicFieldOrderingsTest) {
1130 // Create the testing protos
1131 unittest::TestFieldOrderings msg1;
1132 unittest::TestFieldOrderings msg2;
1133
1134 TestUtil::SetAllFieldsAndExtensions(&msg1);
1135 TestUtil::SetAllFieldsAndExtensions(&msg2);
1136
1137 // Compare
1138 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
1139 }
1140
TEST(MessageDifferencerTest,BasicFieldOrderingInequalityTest)1141 TEST(MessageDifferencerTest, BasicFieldOrderingInequalityTest) {
1142 // Create the testing protos
1143 unittest::TestFieldOrderings msg1;
1144 unittest::TestFieldOrderings msg2;
1145
1146 TestUtil::SetAllFieldsAndExtensions(&msg1);
1147 TestUtil::SetAllFieldsAndExtensions(&msg2);
1148
1149 msg1.set_my_float(15.00);
1150 msg2.set_my_float(16.00);
1151
1152 // Compare
1153 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
1154 }
1155
TEST(MessageDifferencerTest,BasicRepeatedFieldOrderingInequalityTest)1156 TEST(MessageDifferencerTest, BasicRepeatedFieldOrderingInequalityTest) {
1157 // Create the testing protos
1158 unittest::MoreString msg1;
1159 unittest::MoreString msg2;
1160
1161 msg1.add_data("a");
1162 msg1.add_data("b");
1163 msg2.add_data("b");
1164 msg2.add_data("a");
1165
1166 // Compare
1167 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
1168 EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
1169 }
1170
TEST(MessageDifferencerTest,BasicExtensionTest)1171 TEST(MessageDifferencerTest, BasicExtensionTest) {
1172 // Create the testing protos
1173 unittest::TestAllExtensions msg1;
1174 unittest::TestAllExtensions msg2;
1175
1176 TestUtil::SetAllExtensions(&msg1);
1177 TestUtil::SetAllExtensions(&msg2);
1178
1179 // Compare
1180 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
1181 }
1182
TEST(MessageDifferencerTest,BasicExtensionInequalityTest)1183 TEST(MessageDifferencerTest, BasicExtensionInequalityTest) {
1184 // Create the testing protos
1185 unittest::TestAllExtensions msg1;
1186 unittest::TestAllExtensions msg2;
1187
1188 TestUtil::SetAllExtensions(&msg1);
1189 TestUtil::SetAllExtensions(&msg2);
1190
1191 msg1.SetExtension(unittest::optional_int32_extension, 101);
1192 msg2.SetExtension(unittest::optional_int32_extension, 102);
1193
1194 // Compare
1195 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
1196 }
1197
TEST(MessageDifferencerTest,OneofTest)1198 TEST(MessageDifferencerTest, OneofTest) {
1199 // Create the testing protos
1200 unittest::TestOneof2 msg1;
1201 unittest::TestOneof2 msg2;
1202
1203 TestUtil::SetOneof1(&msg1);
1204 TestUtil::SetOneof1(&msg2);
1205
1206 // Compare
1207 EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
1208 }
1209
TEST(MessageDifferencerTest,OneofInequalityTest)1210 TEST(MessageDifferencerTest, OneofInequalityTest) {
1211 // Create the testing protos
1212 unittest::TestOneof2 msg1;
1213 unittest::TestOneof2 msg2;
1214
1215 TestUtil::SetOneof1(&msg1);
1216 TestUtil::SetOneof2(&msg2);
1217
1218 // Compare
1219 EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
1220 }
1221
TEST(MessageDifferencerTest,UnknownFieldPartialEqualTest)1222 TEST(MessageDifferencerTest, UnknownFieldPartialEqualTest) {
1223 unittest::TestEmptyMessage empty1;
1224 unittest::TestEmptyMessage empty2;
1225
1226 UnknownFieldSet* unknown1 = empty1.mutable_unknown_fields();
1227 UnknownFieldSet* unknown2 = empty2.mutable_unknown_fields();
1228
1229 unknown1->AddVarint(243, 122);
1230 unknown1->AddLengthDelimited(245, "abc");
1231 unknown1->AddGroup(246)->AddFixed32(248, 1);
1232 unknown1->mutable_field(2)->mutable_group()->AddFixed32(248, 2);
1233
1234 unknown2->AddVarint(243, 122);
1235 unknown2->AddLengthDelimited(245, "abc");
1236 unknown2->AddGroup(246)->AddFixed32(248, 1);
1237 unknown2->mutable_field(2)->mutable_group()->AddFixed32(248, 2);
1238
1239 util::MessageDifferencer differencer;
1240 differencer.set_scope(util::MessageDifferencer::PARTIAL);
1241 EXPECT_TRUE(differencer.Compare(empty1, empty2));
1242 }
1243
TEST(MessageDifferencerTest,SpecifiedFieldsEqualityAllTest)1244 TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllTest) {
1245 unittest::TestAllTypes msg1;
1246 unittest::TestAllTypes msg2;
1247
1248 TestUtil::SetAllFields(&msg1);
1249 TestUtil::SetAllFields(&msg2);
1250
1251 std::vector<const FieldDescriptor*> fields1;
1252 std::vector<const FieldDescriptor*> fields2;
1253 msg1.GetReflection()->ListFields(msg1, &fields1);
1254 msg2.GetReflection()->ListFields(msg2, &fields2);
1255
1256 util::MessageDifferencer differencer;
1257 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1258 }
1259
TEST(MessageDifferencerTest,SpecifiedFieldsInequalityAllTest)1260 TEST(MessageDifferencerTest, SpecifiedFieldsInequalityAllTest) {
1261 unittest::TestAllTypes msg1;
1262 unittest::TestAllTypes msg2;
1263
1264 TestUtil::SetAllFields(&msg1);
1265
1266 std::vector<const FieldDescriptor*> fields1;
1267 std::vector<const FieldDescriptor*> fields2;
1268 msg1.GetReflection()->ListFields(msg1, &fields1);
1269 msg2.GetReflection()->ListFields(msg2, &fields2);
1270
1271 util::MessageDifferencer differencer;
1272 EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1273 }
1274
TEST(MessageDifferencerTest,SpecifiedFieldsEmptyListAlwaysSucceeds)1275 TEST(MessageDifferencerTest, SpecifiedFieldsEmptyListAlwaysSucceeds) {
1276 unittest::TestAllTypes msg1;
1277 unittest::TestAllTypes msg2;
1278
1279 TestUtil::SetAllFields(&msg1);
1280
1281 std::vector<const FieldDescriptor*> empty_fields;
1282
1283 util::MessageDifferencer differencer;
1284 EXPECT_TRUE(
1285 differencer.CompareWithFields(msg1, msg2, empty_fields, empty_fields));
1286
1287 TestUtil::SetAllFields(&msg2);
1288 EXPECT_TRUE(
1289 differencer.CompareWithFields(msg1, msg2, empty_fields, empty_fields));
1290 }
1291
TEST(MessageDifferencerTest,SpecifiedFieldsCompareWithSelf)1292 TEST(MessageDifferencerTest, SpecifiedFieldsCompareWithSelf) {
1293 unittest::TestAllTypes msg1;
1294 TestUtil::SetAllFields(&msg1);
1295
1296 std::vector<const FieldDescriptor*> fields;
1297 msg1.GetReflection()->ListFields(msg1, &fields);
1298
1299 util::MessageDifferencer differencer;
1300 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg1, fields, fields));
1301
1302 {
1303 // Compare with a subset of fields.
1304 std::vector<const FieldDescriptor*> compare_fields;
1305 for (int i = 0; i < fields.size(); ++i) {
1306 if (i % 2 == 0) {
1307 compare_fields.push_back(fields[i]);
1308 }
1309 }
1310 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg1, compare_fields,
1311 compare_fields));
1312 }
1313 {
1314 // Specify a different set of fields to compare, even though we're using the
1315 // same message. This should fail, since we are explicitly saying that the
1316 // set of fields are different.
1317 std::vector<const FieldDescriptor*> compare_fields1;
1318 std::vector<const FieldDescriptor*> compare_fields2;
1319 for (int i = 0; i < fields.size(); ++i) {
1320 if (i % 2 == 0) {
1321 compare_fields1.push_back(fields[i]);
1322 } else {
1323 compare_fields2.push_back(fields[i]);
1324 }
1325 }
1326 EXPECT_FALSE(differencer.CompareWithFields(msg1, msg1, compare_fields1,
1327 compare_fields2));
1328 }
1329 }
1330
TEST(MessageDifferencerTest,SpecifiedFieldsEqualityAllShuffledTest)1331 TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllShuffledTest) {
1332 // This is a public function, so make sure there are no assumptions about the
1333 // list of fields. Randomly shuffle them to make sure that they are properly
1334 // ordered for comparison.
1335 unittest::TestAllTypes msg1;
1336 unittest::TestAllTypes msg2;
1337
1338 TestUtil::SetAllFields(&msg1);
1339 TestUtil::SetAllFields(&msg2);
1340
1341 std::vector<const FieldDescriptor*> fields1;
1342 std::vector<const FieldDescriptor*> fields2;
1343 msg1.GetReflection()->ListFields(msg1, &fields1);
1344 msg2.GetReflection()->ListFields(msg2, &fields2);
1345
1346 std::default_random_engine rng;
1347 std::shuffle(fields1.begin(), fields1.end(), rng);
1348 std::shuffle(fields2.begin(), fields2.end(), rng);
1349
1350 util::MessageDifferencer differencer;
1351 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1352 }
1353
TEST(MessageDifferencerTest,SpecifiedFieldsSubsetEqualityTest)1354 TEST(MessageDifferencerTest, SpecifiedFieldsSubsetEqualityTest) {
1355 // Specify a set of fields to compare. All the fields are equal.
1356 unittest::TestAllTypes msg1;
1357 unittest::TestAllTypes msg2;
1358 TestUtil::SetAllFields(&msg1);
1359 TestUtil::SetAllFields(&msg2);
1360
1361 std::vector<const FieldDescriptor*> fields1;
1362 msg1.GetReflection()->ListFields(msg1, &fields1);
1363
1364 std::vector<const FieldDescriptor*> compare_fields;
1365 // Only compare the field descriptors with even indices.
1366 for (int i = 0; i < fields1.size(); ++i) {
1367 if (i % 2 == 0) {
1368 compare_fields.push_back(fields1[i]);
1369 }
1370 }
1371
1372 util::MessageDifferencer differencer;
1373 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, compare_fields,
1374 compare_fields));
1375 }
1376
TEST(MessageDifferencerTest,SpecifiedFieldsSubsetIgnoresOtherFieldDifferencesTest)1377 TEST(MessageDifferencerTest,
1378 SpecifiedFieldsSubsetIgnoresOtherFieldDifferencesTest) {
1379 // Specify a set of fields to compare, but clear all the other fields in one
1380 // of the messages. This should fail a regular compare, but CompareWithFields
1381 // should succeed.
1382 unittest::TestAllTypes msg1;
1383 unittest::TestAllTypes msg2;
1384 TestUtil::SetAllFields(&msg1);
1385 TestUtil::SetAllFields(&msg2);
1386
1387 std::vector<const FieldDescriptor*> fields1;
1388 const Reflection* reflection = msg1.GetReflection();
1389 reflection->ListFields(msg1, &fields1);
1390
1391 std::vector<const FieldDescriptor*> compare_fields;
1392 // Only compare the field descriptors with even indices.
1393 for (int i = 0; i < fields1.size(); ++i) {
1394 if (i % 2 == 0) {
1395 compare_fields.push_back(fields1[i]);
1396 } else {
1397 reflection->ClearField(&msg2, fields1[i]);
1398 }
1399 }
1400
1401 util::MessageDifferencer differencer;
1402 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1403 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, compare_fields,
1404 compare_fields));
1405 }
1406
TEST(MessageDifferencerTest,SpecifiedFieldsDetectsDifferencesTest)1407 TEST(MessageDifferencerTest, SpecifiedFieldsDetectsDifferencesTest) {
1408 // Change all of the repeated fields in one of the messages, and use only
1409 // those fields for comparison.
1410 unittest::TestAllTypes msg1;
1411 unittest::TestAllTypes msg2;
1412 TestUtil::SetAllFields(&msg1);
1413 TestUtil::SetAllFields(&msg2);
1414 TestUtil::ModifyRepeatedFields(&msg2);
1415
1416 std::vector<const FieldDescriptor*> fields1;
1417 msg1.GetReflection()->ListFields(msg1, &fields1);
1418
1419 std::vector<const FieldDescriptor*> compare_fields;
1420 // Only compare the repeated field descriptors.
1421 for (int i = 0; i < fields1.size(); ++i) {
1422 if (fields1[i]->is_repeated()) {
1423 compare_fields.push_back(fields1[i]);
1424 }
1425 }
1426
1427 util::MessageDifferencer differencer;
1428 EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, compare_fields,
1429 compare_fields));
1430 }
1431
TEST(MessageDifferencerTest,SpecifiedFieldsEquivalenceAllTest)1432 TEST(MessageDifferencerTest, SpecifiedFieldsEquivalenceAllTest) {
1433 unittest::TestAllTypes msg1;
1434 unittest::TestAllTypes msg2;
1435
1436 TestUtil::SetAllFields(&msg1);
1437 TestUtil::SetAllFields(&msg2);
1438
1439 std::vector<const FieldDescriptor*> fields1;
1440 std::vector<const FieldDescriptor*> fields2;
1441 msg1.GetReflection()->ListFields(msg1, &fields1);
1442 msg2.GetReflection()->ListFields(msg2, &fields2);
1443
1444 util::MessageDifferencer differencer;
1445 differencer.set_message_field_comparison(
1446 util::MessageDifferencer::EQUIVALENT);
1447 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1448 }
1449
TEST(MessageDifferencerTest,SpecifiedFieldsEquivalenceIgnoresOtherFieldDifferencesTest)1450 TEST(MessageDifferencerTest,
1451 SpecifiedFieldsEquivalenceIgnoresOtherFieldDifferencesTest) {
1452 unittest::TestAllTypes msg1;
1453 unittest::TestAllTypes msg2;
1454 const Descriptor* desc = msg1.GetDescriptor();
1455
1456 const FieldDescriptor* optional_int32_desc =
1457 desc->FindFieldByName("optional_int32");
1458 const FieldDescriptor* optional_int64_desc =
1459 desc->FindFieldByName("optional_int64");
1460 const FieldDescriptor* default_int64_desc =
1461 desc->FindFieldByName("default_int64");
1462 ASSERT_TRUE(optional_int32_desc != nullptr);
1463 ASSERT_TRUE(optional_int64_desc != nullptr);
1464 ASSERT_TRUE(default_int64_desc != nullptr);
1465 msg1.set_optional_int32(0);
1466 msg2.set_optional_int64(0);
1467 msg1.set_default_int64(default_int64_desc->default_value_int64());
1468
1469 // Set a field to a non-default value so we know that field selection is
1470 // actually doing something.
1471 msg2.set_optional_uint64(23);
1472
1473 std::vector<const FieldDescriptor*> fields1;
1474 std::vector<const FieldDescriptor*> fields2;
1475 fields1.push_back(optional_int32_desc);
1476 fields1.push_back(default_int64_desc);
1477
1478 fields2.push_back(optional_int64_desc);
1479
1480 util::MessageDifferencer differencer;
1481 EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1482 differencer.set_message_field_comparison(
1483 util::MessageDifferencer::EQUIVALENT);
1484 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1485 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1486 }
1487
TEST(MessageDifferencerTest,RepeatedFieldTreatmentChangeListToSet)1488 TEST(MessageDifferencerTest, RepeatedFieldTreatmentChangeListToSet) {
1489 protobuf_unittest::TestDiffMessage msg1;
1490 protobuf_unittest::TestDiffMessage msg2;
1491
1492 msg1.add_rv(1);
1493 msg1.add_rv(2);
1494 msg2.add_rv(2);
1495 msg2.add_rv(1);
1496
1497 util::MessageDifferencer differencer;
1498 differencer.TreatAsList(
1499 protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
1500 differencer.TreatAsSet(
1501 protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
1502
1503 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1504 }
1505
TEST(MessageDifferencerTest,RepeatedFieldTreatmentChangeSetToList)1506 TEST(MessageDifferencerTest, RepeatedFieldTreatmentChangeSetToList) {
1507 protobuf_unittest::TestDiffMessage msg1;
1508 protobuf_unittest::TestDiffMessage msg2;
1509
1510 msg1.add_rv(1);
1511 msg1.add_rv(2);
1512 msg2.add_rv(2);
1513 msg2.add_rv(1);
1514
1515 util::MessageDifferencer differencer;
1516 differencer.TreatAsSet(
1517 protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
1518 differencer.TreatAsList(
1519 protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
1520
1521 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1522 }
1523
TEST(MessageDifferencerTest,RepeatedFieldSmartListTest)1524 TEST(MessageDifferencerTest, RepeatedFieldSmartListTest) {
1525 // Create the testing protos
1526 protobuf_unittest::TestDiffMessage msg1;
1527 protobuf_unittest::TestDiffMessage msg2;
1528
1529 msg1.add_rv(1);
1530 msg1.add_rv(2);
1531 msg1.add_rv(3);
1532 msg1.add_rv(9);
1533 msg1.add_rv(4);
1534 msg1.add_rv(5);
1535 msg1.add_rv(7);
1536 msg1.add_rv(2);
1537 msg2.add_rv(9);
1538 msg2.add_rv(0);
1539 msg2.add_rv(2);
1540 msg2.add_rv(7);
1541 msg2.add_rv(3);
1542 msg2.add_rv(4);
1543 msg2.add_rv(5);
1544 msg2.add_rv(6);
1545 msg2.add_rv(2);
1546 // Compare
1547 // a: 1, 2, 3, 9, 4, 5, 7, 2
1548 // b: 9, 0, 2, 7, 3, 4, 5, 6, 2
1549 std::string diff_report;
1550 util::MessageDifferencer differencer;
1551 differencer.ReportDifferencesToString(&diff_report);
1552 differencer.set_repeated_field_comparison(
1553 util::MessageDifferencer::AS_SMART_LIST);
1554 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1555 EXPECT_EQ(
1556 "deleted: rv[0]: 1\n"
1557 "added: rv[0]: 9\n"
1558 "added: rv[1]: 0\n"
1559 "moved: rv[1] -> rv[2] : 2\n"
1560 "added: rv[3]: 7\n"
1561 "moved: rv[2] -> rv[4] : 3\n"
1562 "deleted: rv[3]: 9\n"
1563 "moved: rv[4] -> rv[5] : 4\n"
1564 "moved: rv[5] -> rv[6] : 5\n"
1565 "deleted: rv[6]: 7\n"
1566 "added: rv[7]: 6\n"
1567 "moved: rv[7] -> rv[8] : 2\n",
1568 diff_report);
1569
1570 // Compare two sub messages
1571 // a: 1, 2, 3, 4, 5
1572 // b: 2, 6, 4,
1573 msg1.Clear();
1574 msg2.Clear();
1575 msg1.add_rm()->set_a(1);
1576 msg1.add_rm()->set_a(2);
1577 msg1.add_rm()->set_a(3);
1578 msg1.add_rm()->set_a(4);
1579 msg1.add_rm()->set_a(5);
1580 msg2.add_rm()->set_a(2);
1581 msg2.add_rm()->set_a(6);
1582 msg2.add_rm()->set_a(4);
1583 differencer.ReportDifferencesToString(&diff_report);
1584 differencer.set_repeated_field_comparison(
1585 util::MessageDifferencer::AS_SMART_LIST);
1586 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1587 EXPECT_EQ(
1588 "deleted: rm[0]: { a: 1 }\n"
1589 "moved: rm[1] -> rm[0] : { a: 2 }\n"
1590 "deleted: rm[2]: { a: 3 }\n"
1591 "added: rm[1]: { a: 6 }\n"
1592 "moved: rm[3] -> rm[2] : { a: 4 }\n"
1593 "deleted: rm[4]: { a: 5 }\n",
1594 diff_report);
1595 }
1596
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest)1597 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest) {
1598 // Create the testing protos
1599 protobuf_unittest::TestDiffMessage msg1;
1600 protobuf_unittest::TestDiffMessage msg2;
1601 protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
1602 protobuf_unittest::TestField elem1_2, elem2_2, elem3_2;
1603
1604 // Only one field is different for each pair of elements
1605 elem1_1.set_a(1);
1606 elem1_2.set_a(0);
1607 elem1_1.set_b(1);
1608 elem1_2.set_b(1);
1609 elem1_1.set_c(1);
1610 elem1_2.set_c(1);
1611 elem2_1.set_a(2);
1612 elem2_2.set_a(2);
1613 elem2_1.set_b(2);
1614 elem2_2.set_b(0);
1615 elem2_1.set_c(2);
1616 elem2_2.set_c(2);
1617 elem3_1.set_a(3);
1618 elem3_2.set_a(3);
1619 elem3_1.set_b(3);
1620 elem3_2.set_b(0);
1621 elem3_1.set_c(3);
1622 elem3_2.set_c(3);
1623
1624 *msg1.add_rm() = elem1_1;
1625 *msg1.add_rm() = elem2_1;
1626 *msg1.add_rm() = elem3_1;
1627 // Change the order of those elements for the second message.
1628 *msg2.add_rm() = elem3_2;
1629 *msg2.add_rm() = elem1_2;
1630 *msg2.add_rm() = elem2_2;
1631
1632 std::string diff_report;
1633 util::MessageDifferencer differencer;
1634 differencer.ReportDifferencesToString(&diff_report);
1635 differencer.set_repeated_field_comparison(
1636 util::MessageDifferencer::AS_SMART_SET);
1637 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1638 EXPECT_EQ(
1639 "modified: rm[0].a -> rm[1].a: 1 -> 0\n"
1640 "modified: rm[1].b -> rm[2].b: 2 -> 0\n"
1641 "modified: rm[2].b -> rm[0].b: 3 -> 0\n",
1642 diff_report);
1643 }
1644
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest_IdenticalElements)1645 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_IdenticalElements) {
1646 // Create the testing protos
1647 protobuf_unittest::TestDiffMessage msg1;
1648 protobuf_unittest::TestDiffMessage msg2;
1649 protobuf_unittest::TestField elem;
1650
1651 elem.set_a(1);
1652 elem.set_b(1);
1653 elem.set_c(1);
1654
1655 *msg1.add_rm() = elem;
1656 *msg1.add_rm() = elem;
1657 *msg2.add_rm() = elem;
1658 *msg2.add_rm() = elem;
1659
1660 util::MessageDifferencer differencer;
1661 differencer.set_repeated_field_comparison(
1662 util::MessageDifferencer::AS_SMART_SET);
1663 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1664 }
1665
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest_PreviouslyMatch)1666 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_PreviouslyMatch) {
1667 // Create the testing protos
1668 protobuf_unittest::TestDiffMessage msg1;
1669 protobuf_unittest::TestDiffMessage msg2;
1670 protobuf_unittest::TestField elem1_1, elem1_2;
1671 protobuf_unittest::TestField elem2_1, elem2_2;
1672
1673 elem1_1.set_a(1);
1674 elem1_1.set_b(1);
1675 elem1_1.set_c(1);
1676 elem1_2.set_a(1);
1677 elem1_2.set_b(1);
1678 elem1_2.set_c(0);
1679
1680 elem2_1.set_a(1);
1681 elem2_1.set_b(1);
1682 elem2_1.set_c(1);
1683 elem2_2.set_a(1);
1684 elem2_2.set_b(0);
1685 elem2_2.set_c(1);
1686
1687 *msg1.add_rm() = elem1_1;
1688 *msg1.add_rm() = elem2_1;
1689 *msg2.add_rm() = elem1_2;
1690 *msg2.add_rm() = elem2_2;
1691
1692 std::string diff_report;
1693 util::MessageDifferencer differencer;
1694 differencer.ReportDifferencesToString(&diff_report);
1695 differencer.set_repeated_field_comparison(
1696 util::MessageDifferencer::AS_SMART_SET);
1697 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1698 EXPECT_EQ(
1699 "modified: rm[0].c: 1 -> 0\n"
1700 "modified: rm[1].b: 1 -> 0\n",
1701 diff_report);
1702 }
1703
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_MultipleMatches)1704 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatches) {
1705 // Create the testing protos
1706 protobuf_unittest::TestDiffMessage msg1;
1707 protobuf_unittest::TestDiffMessage msg2;
1708 protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
1709 protobuf_unittest::TestField elem2_2, elem3_2;
1710
1711 // Only one field is different for each pair of elements
1712 elem1_1.set_a(1);
1713 elem1_1.set_b(1);
1714 elem1_1.set_c(1);
1715 elem2_1.set_a(2);
1716 elem2_2.set_a(2);
1717 elem2_1.set_b(2);
1718 elem2_2.set_b(0);
1719 elem2_1.set_c(2);
1720 elem2_2.set_c(2);
1721 elem3_1.set_a(3);
1722 elem3_2.set_a(3);
1723 elem3_1.set_b(3);
1724 elem3_2.set_b(0);
1725 elem3_1.set_c(3);
1726 elem3_2.set_c(3);
1727
1728 // In this testcase, elem1_1 will match with elem2_2 first and then get
1729 // reverted because elem2_1 matches with elem2_2 later.
1730 *msg1.add_rm() = elem1_1;
1731 *msg1.add_rm() = elem2_1;
1732 *msg1.add_rm() = elem3_1;
1733 *msg2.add_rm() = elem2_2;
1734 *msg2.add_rm() = elem3_2;
1735
1736 std::string diff_report;
1737 util::MessageDifferencer differencer;
1738 differencer.ReportDifferencesToString(&diff_report);
1739 differencer.set_repeated_field_comparison(
1740 util::MessageDifferencer::AS_SMART_SET);
1741 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1742 EXPECT_EQ(
1743 "modified: rm[1].b -> rm[0].b: 2 -> 0\n"
1744 "modified: rm[2].b -> rm[1].b: 3 -> 0\n"
1745 "deleted: rm[0]: { c: 1 a: 1 b: 1 }\n",
1746 diff_report);
1747 }
1748
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_MultipleMatchesNoReporter)1749 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatchesNoReporter) {
1750 protobuf_unittest::TestDiffMessage msg1;
1751 protobuf_unittest::TestDiffMessage msg2;
1752 protobuf_unittest::TestField elem1, elem2, elem3, elem4;
1753 elem1.set_a(1);
1754 elem2.set_a(2);
1755 elem3.set_a(3);
1756 elem4.set_a(4);
1757
1758 *msg1.add_rm() = elem1;
1759 *msg1.add_rm() = elem2;
1760 *msg1.add_rm() = elem3;
1761 *msg2.add_rm() = elem2;
1762 *msg2.add_rm() = elem3;
1763 *msg2.add_rm() = elem4;
1764
1765 util::MessageDifferencer differencer;
1766 differencer.set_repeated_field_comparison(
1767 util::MessageDifferencer::AS_SMART_SET);
1768 EXPECT_FALSE(differencer.Compare(msg1, msg2));
1769 }
1770
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_NonMessageTypeTest)1771 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_NonMessageTypeTest) {
1772 // Create the testing protos
1773 protobuf_unittest::TestDiffMessage msg1;
1774 protobuf_unittest::TestDiffMessage msg2;
1775
1776 // Create 3 elements, but in different order.
1777 msg1.add_rw("b");
1778 msg2.add_rw("a");
1779 msg1.add_rw("x");
1780 msg2.add_rw("x");
1781 msg1.add_rw("a");
1782 msg2.add_rw("b");
1783
1784 std::string diff_report;
1785 util::MessageDifferencer differencer;
1786 differencer.ReportDifferencesToString(&diff_report);
1787 differencer.set_repeated_field_comparison(
1788 util::MessageDifferencer::AS_SMART_SET);
1789 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1790 EXPECT_EQ(
1791 "moved: rw[0] -> rw[2] : \"b\"\n"
1792 "moved: rw[2] -> rw[0] : \"a\"\n",
1793 diff_report);
1794 }
1795
TEST(MessageDifferencerTest,RepeatedFieldSetTest_SetOfSet)1796 TEST(MessageDifferencerTest, RepeatedFieldSetTest_SetOfSet) {
1797 // Create the testing protos
1798 protobuf_unittest::TestDiffMessage msg1;
1799 protobuf_unittest::TestDiffMessage msg2;
1800
1801 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1802 item->add_ra(1);
1803 item->add_ra(2);
1804 item->add_ra(3);
1805 item = msg1.add_item();
1806 item->add_ra(5);
1807 item->add_ra(6);
1808 item = msg1.add_item();
1809 item->add_ra(1);
1810 item->add_ra(3);
1811 item = msg1.add_item();
1812 item->add_ra(6);
1813 item->add_ra(7);
1814 item->add_ra(8);
1815
1816 item = msg2.add_item();
1817 item->add_ra(6);
1818 item->add_ra(5);
1819 item = msg2.add_item();
1820 item->add_ra(6);
1821 item->add_ra(8);
1822 item->add_ra(7);
1823 item = msg2.add_item();
1824 item->add_ra(1);
1825 item->add_ra(3);
1826 item = msg2.add_item();
1827 item->add_ra(3);
1828 item->add_ra(2);
1829 item->add_ra(1);
1830
1831 // Compare
1832 util::MessageDifferencer differencer;
1833 differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1834 EXPECT_TRUE(differencer.Compare(msg1, msg2));
1835 }
1836
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Combination)1837 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Combination) {
1838 // Create the testing protos
1839 protobuf_unittest::TestDiffMessage msg1;
1840 protobuf_unittest::TestDiffMessage msg2;
1841 // Treat "item" as Map, with key = "a"
1842 // Treat "item.ra" also as Set
1843 // Treat "rv" as Set
1844 // Treat "rw" as List
1845 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1846 item->set_a(3);
1847 item->add_ra(1);
1848 item->add_ra(2);
1849 item->add_ra(3);
1850 item = msg1.add_item();
1851 item->set_a(4);
1852 item->add_ra(5);
1853 item->add_ra(6);
1854 item = msg1.add_item();
1855 item->set_a(1);
1856 item->add_ra(1);
1857 item->add_ra(3);
1858 item = msg1.add_item();
1859 item->set_a(2);
1860 item->add_ra(6);
1861 item->add_ra(7);
1862 item->add_ra(8);
1863
1864 item = msg2.add_item();
1865 item->set_a(4);
1866 item->add_ra(6);
1867 item->add_ra(5);
1868 item = msg2.add_item();
1869 item->set_a(2);
1870 item->add_ra(6);
1871 item->add_ra(8);
1872 item->add_ra(7);
1873 item = msg2.add_item();
1874 item->set_a(1);
1875 item->add_ra(1);
1876 item->add_ra(3);
1877 item = msg2.add_item();
1878 item->set_a(3);
1879 item->add_ra(3);
1880 item->add_ra(2);
1881 item->add_ra(1);
1882
1883 msg1.add_rv(3);
1884 msg1.add_rv(4);
1885 msg1.add_rv(7);
1886 msg1.add_rv(0);
1887 msg2.add_rv(4);
1888 msg2.add_rv(3);
1889 msg2.add_rv(0);
1890 msg2.add_rv(7);
1891
1892 msg1.add_rw("nothing");
1893 msg2.add_rw("nothing");
1894 msg1.add_rw("should");
1895 msg2.add_rw("should");
1896 msg1.add_rw("change");
1897 msg2.add_rw("change");
1898
1899 // Compare
1900 util::MessageDifferencer differencer1;
1901 differencer1.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
1902 item->GetDescriptor()->FindFieldByName("a"));
1903 differencer1.TreatAsSet(msg1.GetDescriptor()->FindFieldByName("rv"));
1904 differencer1.TreatAsSet(item->GetDescriptor()->FindFieldByName("ra"));
1905 EXPECT_TRUE(differencer1.Compare(msg1, msg2));
1906
1907 util::MessageDifferencer differencer2;
1908 differencer2.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
1909 item->GetDescriptor()->FindFieldByName("a"));
1910 differencer2.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1911 differencer2.TreatAsList(msg1.GetDescriptor()->FindFieldByName("rw"));
1912 EXPECT_TRUE(differencer2.Compare(msg1, msg2));
1913 }
1914
1915 // This class is a comparator that uses the default comparator, but counts how
1916 // many times it was called.
1917 class CountingComparator : public util::SimpleFieldComparator {
1918 public:
Compare(const Message & message_1,const Message & message_2,const FieldDescriptor * field,int index_1,int index_2,const util::FieldContext * field_context)1919 ComparisonResult Compare(const Message& message_1, const Message& message_2,
1920 const FieldDescriptor* field, int index_1,
1921 int index_2,
1922 const util::FieldContext* field_context) override {
1923 ++compare_count_;
1924 return SimpleCompare(message_1, message_2, field, index_1, index_2,
1925 field_context);
1926 }
1927
compare_count() const1928 int compare_count() const { return compare_count_; }
1929
1930 private:
1931 int compare_count_ = 0;
1932 };
1933
TEST(MessageDifferencerTest,RepeatedFieldSet_RecursivePerformance)1934 TEST(MessageDifferencerTest, RepeatedFieldSet_RecursivePerformance) {
1935 constexpr int kDepth = 20;
1936
1937 protobuf_unittest::TestField left;
1938 protobuf_unittest::TestField* p = &left;
1939 for (int i = 0; i < kDepth; ++i) {
1940 p = p->add_rm();
1941 }
1942
1943 protobuf_unittest::TestField right = left;
1944 util::MessageDifferencer differencer;
1945 differencer.set_repeated_field_comparison(
1946 util::MessageDifferencer::RepeatedFieldComparison::AS_SET);
1947 CountingComparator comparator;
1948 differencer.set_field_comparator(&comparator);
1949 std::string report;
1950 differencer.ReportDifferencesToString(&report);
1951 differencer.Compare(left, right);
1952
1953 EXPECT_LE(comparator.compare_count(), kDepth * kDepth);
1954 }
1955
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_RecursivePerformance)1956 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_RecursivePerformance) {
1957 constexpr int kDepth = 20;
1958
1959 protobuf_unittest::TestField left;
1960 protobuf_unittest::TestField* p = &left;
1961 for (int i = 0; i < kDepth; ++i) {
1962 p = p->add_rm();
1963 }
1964
1965 protobuf_unittest::TestField right = left;
1966 util::MessageDifferencer differencer;
1967 differencer.set_repeated_field_comparison(
1968 util::MessageDifferencer::RepeatedFieldComparison::AS_SMART_SET);
1969 CountingComparator comparator;
1970 differencer.set_field_comparator(&comparator);
1971 std::string report;
1972 differencer.ReportDifferencesToString(&report);
1973 differencer.Compare(left, right);
1974
1975 EXPECT_LE(comparator.compare_count(), kDepth * kDepth);
1976 }
1977
TEST(MessageDifferencerTest,RepeatedFieldSmartList_RecursivePerformance)1978 TEST(MessageDifferencerTest, RepeatedFieldSmartList_RecursivePerformance) {
1979 constexpr int kDepth = 20;
1980
1981 protobuf_unittest::TestField left;
1982 protobuf_unittest::TestField* p = &left;
1983 for (int i = 0; i < kDepth; ++i) {
1984 p = p->add_rm();
1985 }
1986
1987 protobuf_unittest::TestField right = left;
1988 util::MessageDifferencer differencer;
1989 differencer.set_repeated_field_comparison(
1990 util::MessageDifferencer::RepeatedFieldComparison::AS_SMART_LIST);
1991 CountingComparator comparator;
1992 differencer.set_field_comparator(&comparator);
1993 std::string report;
1994 differencer.ReportDifferencesToString(&report);
1995 differencer.Compare(left, right);
1996
1997 EXPECT_LE(comparator.compare_count(), kDepth * kDepth);
1998 }
1999
TEST(MessageDifferencerTest,RepeatedFieldMapTest_Partial)2000 TEST(MessageDifferencerTest, RepeatedFieldMapTest_Partial) {
2001 protobuf_unittest::TestDiffMessage msg1;
2002 // message msg1 {
2003 // item { a: 1; b: "11" }
2004 // }
2005 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2006 item->set_a(1);
2007 item->set_b("11");
2008
2009 protobuf_unittest::TestDiffMessage msg2;
2010 // message msg2 {
2011 // item { a: 2; b: "22" }
2012 // item { a: 1; b: "11" }
2013 // }
2014 item = msg2.add_item();
2015 item->set_a(2);
2016 item->set_b("22");
2017 item = msg2.add_item();
2018 item->set_a(1);
2019 item->set_b("11");
2020
2021 // Compare
2022 util::MessageDifferencer differencer;
2023 differencer.TreatAsMap(GetFieldDescriptor(msg1, "item"),
2024 GetFieldDescriptor(msg1, "item.a"));
2025 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2026 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2027 }
2028
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Duplicates)2029 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Duplicates) {
2030 protobuf_unittest::TestDiffMessage a, b, c;
2031 // message a: {
2032 // rv: 0
2033 // rv: 1
2034 // rv: 0
2035 // }
2036 a.add_rv(0);
2037 a.add_rv(1);
2038 a.add_rv(0);
2039 // message b: {
2040 // rv: 0
2041 // rv: 0
2042 // rv: 1
2043 // }
2044 b.add_rv(0);
2045 b.add_rv(0);
2046 b.add_rv(1);
2047 // message c: {
2048 // rv: 0
2049 // rv: 1
2050 // }
2051 c.add_rv(0);
2052 c.add_rv(1);
2053 util::MessageDifferencer differencer;
2054 differencer.TreatAsSet(GetFieldDescriptor(a, "rv"));
2055 EXPECT_TRUE(differencer.Compare(b, a));
2056 EXPECT_FALSE(differencer.Compare(c, a));
2057
2058 util::MessageDifferencer differencer1;
2059 differencer1.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
2060 EXPECT_TRUE(differencer1.Compare(b, a));
2061 EXPECT_FALSE(differencer1.Compare(c, a));
2062 }
2063
TEST(MessageDifferencerTest,RepeatedFieldSetTest_PartialSimple)2064 TEST(MessageDifferencerTest, RepeatedFieldSetTest_PartialSimple) {
2065 protobuf_unittest::TestDiffMessage a, b, c;
2066 // message a: {
2067 // rm { c: 1 }
2068 // rm { c: 0 }
2069 // }
2070 a.add_rm()->set_c(1);
2071 a.add_rm()->set_c(0);
2072 // message b: {
2073 // rm { c: 1 }
2074 // rm {}
2075 // }
2076 b.add_rm()->set_c(1);
2077 b.add_rm();
2078 // message c: {
2079 // rm {}
2080 // rm { c: 1 }
2081 // }
2082 c.add_rm();
2083 c.add_rm()->set_c(1);
2084 util::MessageDifferencer differencer;
2085 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2086 differencer.TreatAsSet(GetFieldDescriptor(a, "rm"));
2087 EXPECT_TRUE(differencer.Compare(b, a));
2088 EXPECT_TRUE(differencer.Compare(c, a));
2089 }
2090
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Partial)2091 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Partial) {
2092 protobuf_unittest::TestDiffMessage msg1, msg2;
2093 // message msg1: {
2094 // rm { a: 1 }
2095 // rm { b: 2 }
2096 // rm { c: 3 }
2097 // }
2098 msg1.add_rm()->set_a(1);
2099 msg1.add_rm()->set_b(2);
2100 msg1.add_rm()->set_c(3);
2101 // message msg2: {
2102 // rm { a: 1; c: 3 }
2103 // rm { b: 2; c: 3 }
2104 // rm { b: 2 }
2105 // }
2106 protobuf_unittest::TestField* field = msg2.add_rm();
2107 field->set_a(1);
2108 field->set_c(3);
2109 field = msg2.add_rm();
2110 field->set_b(2);
2111 field->set_c(3);
2112 field = msg2.add_rm();
2113 field->set_b(2);
2114
2115 util::MessageDifferencer differencer;
2116 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2117 differencer.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
2118 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2119 }
2120
TEST(MessageDifferencerTest,RepeatedFieldMapTest_MultipleFieldsAsKey)2121 TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldsAsKey) {
2122 protobuf_unittest::TestDiffMessage msg1;
2123 protobuf_unittest::TestDiffMessage msg2;
2124 // Treat "item" as Map, with key = ("a", "ra")
2125 // Treat "item.ra" as Set
2126 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2127 // key => value: (1, {2, 3}) => "a"
2128 item->set_a(1);
2129 item->add_ra(2);
2130 item->add_ra(3);
2131 item->set_b("a");
2132 item = msg1.add_item();
2133 // key => value: (2, {1, 3}) => "b"
2134 item->set_a(2);
2135 item->add_ra(1);
2136 item->add_ra(3);
2137 item->set_b("b");
2138 item = msg1.add_item();
2139 // key => value: (1, {1, 3}) => "c"
2140 item->set_a(1);
2141 item->add_ra(1);
2142 item->add_ra(3);
2143 item->set_b("c");
2144
2145 item = msg2.add_item();
2146 // key => value: (1, {1, 3}) => "c"
2147 item->set_a(1);
2148 item->add_ra(3);
2149 item->add_ra(1);
2150 item->set_b("c");
2151 item = msg2.add_item();
2152 // key => value: (1, {2, 3}) => "a"
2153 item->set_a(1);
2154 item->add_ra(3);
2155 item->add_ra(2);
2156 item->set_b("a");
2157 item = msg2.add_item();
2158 // key => value: (2, {1, 3}) => "b"
2159 item->set_a(2);
2160 item->add_ra(3);
2161 item->add_ra(1);
2162 item->set_b("b");
2163
2164 // Compare
2165 util::MessageDifferencer differencer;
2166 differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.ra"));
2167 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2168 std::vector<const FieldDescriptor*> key_fields;
2169 key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
2170 key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
2171 differencer.TreatAsMapWithMultipleFieldsAsKey(
2172 GetFieldDescriptor(msg1, "item"), key_fields);
2173 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2174
2175 // Introduce some differences.
2176 msg1.clear_item();
2177 msg2.clear_item();
2178 item = msg1.add_item();
2179 item->set_a(4);
2180 item->add_ra(5);
2181 item->add_ra(6);
2182 item->set_b("hello");
2183 item = msg2.add_item();
2184 item->set_a(4);
2185 item->add_ra(6);
2186 item->add_ra(5);
2187 item->set_b("world");
2188 std::string output;
2189 differencer.ReportDifferencesToString(&output);
2190 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2191 EXPECT_EQ(
2192 "moved: item[0].ra[0] -> item[0].ra[1] : 5\n"
2193 "moved: item[0].ra[1] -> item[0].ra[0] : 6\n"
2194 "modified: item[0].b: \"hello\" -> \"world\"\n",
2195 output);
2196 }
2197
TEST(MessageDifferencerTest,RepeatedFieldMapTest_MultipleFieldPathsAsKey)2198 TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldPathsAsKey) {
2199 protobuf_unittest::TestDiffMessage msg1;
2200 protobuf_unittest::TestDiffMessage msg2;
2201 // Treat "item" as Map, with key = ("m.a", "m.rc")
2202 // Treat "item.m.rc" as Set
2203 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2204 // key => value: (1, {2, 3}) => "a"
2205 item->mutable_m()->set_a(1);
2206 item->mutable_m()->add_rc(2);
2207 item->mutable_m()->add_rc(3);
2208 item->set_b("a");
2209 item = msg1.add_item();
2210 // key => value: (2, {1, 3}) => "b"
2211 item->mutable_m()->set_a(2);
2212 item->mutable_m()->add_rc(1);
2213 item->mutable_m()->add_rc(3);
2214 item->set_b("b");
2215 item = msg1.add_item();
2216 // key => value: (1, {1, 3}) => "c"
2217 item->mutable_m()->set_a(1);
2218 item->mutable_m()->add_rc(1);
2219 item->mutable_m()->add_rc(3);
2220 item->set_b("c");
2221
2222 item = msg2.add_item();
2223 // key => value: (1, {1, 3}) => "c"
2224 item->mutable_m()->set_a(1);
2225 item->mutable_m()->add_rc(3);
2226 item->mutable_m()->add_rc(1);
2227 item->set_b("c");
2228 item = msg2.add_item();
2229 // key => value: (1, {2, 3}) => "a"
2230 item->mutable_m()->set_a(1);
2231 item->mutable_m()->add_rc(3);
2232 item->mutable_m()->add_rc(2);
2233 item->set_b("a");
2234 item = msg2.add_item();
2235 // key => value: (2, {1, 3}) => "b"
2236 item->mutable_m()->set_a(2);
2237 item->mutable_m()->add_rc(3);
2238 item->mutable_m()->add_rc(1);
2239 item->set_b("b");
2240
2241 // Compare
2242 util::MessageDifferencer differencer;
2243 differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.m.rc"));
2244 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2245 std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
2246 std::vector<const FieldDescriptor*> key_field_path1;
2247 key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m"));
2248 key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m.a"));
2249 std::vector<const FieldDescriptor*> key_field_path2;
2250 key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m"));
2251 key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m.rc"));
2252 key_field_paths.push_back(key_field_path1);
2253 key_field_paths.push_back(key_field_path2);
2254 differencer.TreatAsMapWithMultipleFieldPathsAsKey(
2255 GetFieldDescriptor(msg1, "item"), key_field_paths);
2256 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2257
2258 // Introduce some differences.
2259 msg1.clear_item();
2260 msg2.clear_item();
2261 item = msg1.add_item();
2262 item->mutable_m()->set_a(4);
2263 item->mutable_m()->add_rc(5);
2264 item->mutable_m()->add_rc(6);
2265 item->set_b("hello");
2266 item = msg2.add_item();
2267 item->mutable_m()->set_a(4);
2268 item->mutable_m()->add_rc(6);
2269 item->mutable_m()->add_rc(5);
2270 item->set_b("world");
2271 std::string output;
2272 differencer.ReportDifferencesToString(&output);
2273 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2274 EXPECT_EQ(
2275 "modified: item[0].b: \"hello\" -> \"world\"\n"
2276 "moved: item[0].m.rc[0] -> item[0].m.rc[1] : 5\n"
2277 "moved: item[0].m.rc[1] -> item[0].m.rc[0] : 6\n",
2278 output);
2279 }
2280
TEST(MessageDifferencerTest,RepeatedFieldMapTest_IgnoredKeyFields)2281 TEST(MessageDifferencerTest, RepeatedFieldMapTest_IgnoredKeyFields) {
2282 protobuf_unittest::TestDiffMessage msg1;
2283 protobuf_unittest::TestDiffMessage msg2;
2284 // Treat "item" as Map, with key = ("a", "ra")
2285 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2286 item->set_a(1);
2287 item->add_ra(2);
2288 item->set_b("hello");
2289 item = msg2.add_item();
2290 item->set_a(1);
2291 item->add_ra(3);
2292 item->set_b("world");
2293 // Compare
2294 util::MessageDifferencer differencer;
2295 std::vector<const FieldDescriptor*> key_fields;
2296 key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
2297 key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
2298 differencer.TreatAsMapWithMultipleFieldsAsKey(
2299 GetFieldDescriptor(msg1, "item"), key_fields);
2300 std::string output;
2301 differencer.ReportDifferencesToString(&output);
2302 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2303 EXPECT_EQ(
2304 "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
2305 "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
2306 output);
2307 // Ignored fields that are listed as parts of the key are still used
2308 // in key comparison, but they're not used in value comparison.
2309 differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
2310 output.clear();
2311 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2312 EXPECT_EQ(
2313 "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
2314 "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
2315 output);
2316 // Ignoring a field in the key is different from treating the left fields
2317 // as key. That is:
2318 // (key = ("a", "ra") && ignore "ra") != (key = ("a") && ignore "ra")
2319 util::MessageDifferencer differencer2;
2320 differencer2.TreatAsMap(GetFieldDescriptor(msg1, "item"),
2321 GetFieldDescriptor(msg1, "item.a"));
2322 differencer2.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
2323 output.clear();
2324 differencer2.ReportDifferencesToString(&output);
2325 EXPECT_FALSE(differencer2.Compare(msg1, msg2));
2326 EXPECT_EQ(
2327 "ignored: item[0].ra\n"
2328 "modified: item[0].b: \"hello\" -> \"world\"\n",
2329 output);
2330 }
2331
TEST(MessageDifferencerTest,PrintMapKeysTest)2332 TEST(MessageDifferencerTest, PrintMapKeysTest) {
2333 // Note that because map is unordered, the comparison
2334 // output string for test evaluation cannot assume order of
2335 // output of fields (IOW if two fields are deleted
2336 // one cannot assume which deleted field log will be printed first).
2337 // Test currently just has a single record per operation to address this.
2338 // This should only be a limitation for EXPECT_EQ evaluation.
2339 protobuf_unittest::TestDiffMessage msg1;
2340 protobuf_unittest::TestDiffMessage msg2;
2341 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2342 item->mutable_mp()->insert({{"key_a", 1}, {"key_b", 2}, {"key_c", 3}});
2343 item = msg2.add_item();
2344 item->mutable_mp()->insert({{"key_a", 1}, {"key_b", 3}, {"key_d", 4}});
2345
2346 util::MessageDifferencer differencer;
2347 std::string diff;
2348 differencer.ReportDifferencesToString(&diff);
2349 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2350 EXPECT_EQ(
2351 "modified: item[0].mp[key_b]: 2 -> 3\n"
2352 "added: item[0].mp[key_d]: 4\n"
2353 "deleted: item[0].mp[key_c]: 3\n",
2354 diff);
2355
2356 google::protobuf::Any any1, any2;
2357 any1.PackFrom(msg1);
2358 any2.PackFrom(msg2);
2359 std::string diff_with_any;
2360 differencer.ReportDifferencesToString(&diff_with_any);
2361 EXPECT_FALSE(differencer.Compare(any1, any2));
2362 EXPECT_EQ(
2363 "modified: item[0].mp[key_b]: 2 -> 3\n"
2364 "added: item[0].mp[key_d]: 4\n"
2365 "deleted: item[0].mp[key_c]: 3\n",
2366 diff_with_any);
2367 }
2368
2369 static constexpr absl::string_view kIgnoredFields[] = {"rm.b", "rm.m.b"};
2370
2371 class TestIgnorer : public util::MessageDifferencer::IgnoreCriteria {
2372 public:
IsIgnored(const Message & message1,const Message & message2,const FieldDescriptor * field,const std::vector<util::MessageDifferencer::SpecificField> & parent_fields)2373 bool IsIgnored(const Message& message1, const Message& message2,
2374 const FieldDescriptor* field,
2375 const std::vector<util::MessageDifferencer::SpecificField>&
2376 parent_fields) override {
2377 std::string name = "";
2378 for (size_t i = 0; i < parent_fields.size(); ++i) {
2379 absl::StrAppend(&name, parent_fields[i].field->name(), ".");
2380 }
2381 absl::StrAppend(&name, field->name());
2382 for (size_t i = 0; i < ABSL_ARRAYSIZE(kIgnoredFields); ++i) {
2383 if (name == kIgnoredFields[i]) {
2384 return true;
2385 }
2386 }
2387 return false;
2388 }
2389 };
2390
TEST(MessageDifferencerTest,TreatRepeatedFieldAsSetWithIgnoredFields)2391 TEST(MessageDifferencerTest, TreatRepeatedFieldAsSetWithIgnoredFields) {
2392 protobuf_unittest::TestDiffMessage msg1;
2393 protobuf_unittest::TestDiffMessage msg2;
2394 TextFormat::MergeFromString("rm { a: 11\n b: 12 }", &msg1);
2395 TextFormat::MergeFromString("rm { a: 11\n b: 13 }", &msg2);
2396 util::MessageDifferencer differ;
2397 differ.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
2398 differ.AddIgnoreCriteria(absl::WrapUnique(new TestIgnorer));
2399 EXPECT_TRUE(differ.Compare(msg1, msg2));
2400 }
2401
TEST(MessageDifferencerTest,TreatRepeatedFieldAsMapWithIgnoredKeyFields)2402 TEST(MessageDifferencerTest, TreatRepeatedFieldAsMapWithIgnoredKeyFields) {
2403 protobuf_unittest::TestDiffMessage msg1;
2404 protobuf_unittest::TestDiffMessage msg2;
2405 TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 13\n } }", &msg1);
2406 TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 14\n } }", &msg2);
2407 util::MessageDifferencer differ;
2408 differ.TreatAsMap(GetFieldDescriptor(msg1, "rm"),
2409 GetFieldDescriptor(msg1, "rm.m"));
2410 differ.AddIgnoreCriteria(absl::WrapUnique(new TestIgnorer));
2411 EXPECT_TRUE(differ.Compare(msg1, msg2));
2412 }
2413
2414 // Takes the product of all elements of item.ra as the key for key comparison.
2415 class ValueProductMapKeyComparator
2416 : public util::MessageDifferencer::MapKeyComparator {
2417 public:
2418 typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,int unpacked_any,const std::vector<SpecificField> & parent_fields) const2419 bool IsMatch(const Message& message1, const Message& message2,
2420 int unpacked_any,
2421 const std::vector<SpecificField>& parent_fields) const override {
2422 const Reflection* reflection1 = message1.GetReflection();
2423 const Reflection* reflection2 = message2.GetReflection();
2424 // FieldDescriptor for item.ra
2425 const FieldDescriptor* ra_field =
2426 message1.GetDescriptor()->FindFieldByName("ra");
2427 // Get the product of all elements in item.ra
2428 int result1 = 1, result2 = 1;
2429 for (int i = 0; i < reflection1->FieldSize(message1, ra_field); ++i) {
2430 result1 *= reflection1->GetRepeatedInt32(message1, ra_field, i);
2431 }
2432 for (int i = 0; i < reflection2->FieldSize(message2, ra_field); ++i) {
2433 result2 *= reflection2->GetRepeatedInt32(message2, ra_field, i);
2434 }
2435 return result1 == result2;
2436 }
2437 };
2438
TEST(MessageDifferencerTest,RepeatedFieldMapTest_CustomMapKeyComparator)2439 TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomMapKeyComparator) {
2440 protobuf_unittest::TestDiffMessage msg1;
2441 protobuf_unittest::TestDiffMessage msg2;
2442 // Treat "item" as Map, using custom key comparator to determine if two
2443 // elements have the same key.
2444 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2445 item->add_ra(6);
2446 item->add_ra(35);
2447 item->set_b("hello");
2448 item = msg2.add_item();
2449 item->add_ra(10);
2450 item->add_ra(21);
2451 item->set_b("hello");
2452 util::MessageDifferencer differencer;
2453 ValueProductMapKeyComparator key_comparator;
2454 differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
2455 &key_comparator);
2456 std::string output;
2457 differencer.ReportDifferencesToString(&output);
2458 // Though the above two messages have different values for item.ra, they
2459 // are regarded as having the same key because 6 * 35 == 10 * 21. That's
2460 // how the key comparator determines if the two have the same key.
2461 // However, in value comparison, all fields of the message are taken into
2462 // consideration, so they are different because their item.ra fields have
2463 // different values using normal value comparison.
2464 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2465 EXPECT_EQ(
2466 "modified: item[0].ra[0]: 6 -> 10\n"
2467 "modified: item[0].ra[1]: 35 -> 21\n",
2468 output);
2469 differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
2470 output.clear();
2471 // item.ra is ignored in value comparison, so the two messages equal.
2472 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2473 EXPECT_EQ("ignored: item[0].ra\n", output);
2474 }
2475
2476 // Compares fields by their index offset by one, so index 0 matches with 1, etc.
2477 class OffsetByOneMapKeyComparator
2478 : public util::MessageDifferencer::MapKeyComparator {
2479 public:
2480 typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,int unpacked_any,const std::vector<SpecificField> & parent_fields) const2481 bool IsMatch(const Message& message1, const Message& message2,
2482 int unpacked_any,
2483 const std::vector<SpecificField>& parent_fields) const override {
2484 return parent_fields.back().index + 1 == parent_fields.back().new_index;
2485 }
2486 };
2487
TEST(MessageDifferencerTest,RepeatedFieldMapTest_CustomIndexMapKeyComparator)2488 TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomIndexMapKeyComparator) {
2489 protobuf_unittest::TestDiffMessage msg1;
2490 protobuf_unittest::TestDiffMessage msg2;
2491 // Treat "item" as Map, using custom key comparator to determine if two
2492 // elements have the same key.
2493 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2494 item->set_b("one");
2495 item = msg2.add_item();
2496 item->set_b("zero");
2497 item = msg2.add_item();
2498 item->set_b("one");
2499 util::MessageDifferencer differencer;
2500 OffsetByOneMapKeyComparator key_comparator;
2501 differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
2502 &key_comparator);
2503 std::string output;
2504 differencer.ReportDifferencesToString(&output);
2505 // With the offset by one comparator msg1.item[0] should be compared to
2506 // msg2.item[1] and thus be moved, msg2.item[0] should be marked as added.
2507 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2508 EXPECT_EQ(
2509 "moved: item[0] -> item[1] : { b: \"one\" }\n"
2510 "added: item[0]: { b: \"zero\" }\n",
2511 output);
2512 }
2513
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Subset)2514 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Subset) {
2515 protobuf_unittest::TestDiffMessage msg1;
2516 protobuf_unittest::TestDiffMessage msg2;
2517
2518 msg1.add_rv(3);
2519 msg1.add_rv(8);
2520 msg1.add_rv(2);
2521 msg2.add_rv(2);
2522 msg2.add_rv(3);
2523 msg2.add_rv(5);
2524 msg2.add_rv(8);
2525
2526 util::MessageDifferencer differencer;
2527
2528 // Fail with only partial scope set.
2529 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2530 differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_LIST);
2531 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2532
2533 // Fail with only set-like comparison set.
2534 differencer.set_scope(util::MessageDifferencer::FULL);
2535 differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
2536 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2537
2538 // Succeed with scope and repeated field comparison set properly.
2539 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2540 differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
2541 EXPECT_TRUE(differencer.Compare(msg1, msg2));
2542 }
2543
TEST(MessageDifferencerTest,IgnoreField_Single)2544 TEST(MessageDifferencerTest, IgnoreField_Single) {
2545 protobuf_unittest::TestField msg1;
2546 protobuf_unittest::TestField msg2;
2547
2548 msg1.set_c(3);
2549 msg1.add_rc(1);
2550
2551 msg2.set_c(5);
2552 msg2.add_rc(1);
2553
2554 util::MessageDifferencer differencer;
2555 differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
2556
2557 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2558 }
2559
TEST(MessageDifferencerTest,IgnoreField_Repeated)2560 TEST(MessageDifferencerTest, IgnoreField_Repeated) {
2561 protobuf_unittest::TestField msg1;
2562 protobuf_unittest::TestField msg2;
2563
2564 msg1.set_c(3);
2565 msg1.add_rc(1);
2566 msg1.add_rc(2);
2567
2568 msg2.set_c(3);
2569 msg2.add_rc(1);
2570 msg2.add_rc(3);
2571
2572 util::MessageDifferencer differencer;
2573 differencer.IgnoreField(GetFieldDescriptor(msg1, "rc"));
2574
2575 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2576 }
2577
TEST(MessageDifferencerTest,IgnoreField_Message)2578 TEST(MessageDifferencerTest, IgnoreField_Message) {
2579 protobuf_unittest::TestDiffMessage msg1;
2580 protobuf_unittest::TestDiffMessage msg2;
2581
2582 protobuf_unittest::TestField* field;
2583
2584 field = msg1.add_rm();
2585 field->set_c(3);
2586
2587 field = msg2.add_rm();
2588 field->set_c(4);
2589
2590 util::MessageDifferencer differencer;
2591 differencer.IgnoreField(GetFieldDescriptor(msg1, "rm"));
2592
2593 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2594 }
2595
TEST(MessageDifferencerTest,IgnoreField_Group)2596 TEST(MessageDifferencerTest, IgnoreField_Group) {
2597 protobuf_unittest::TestDiffMessage msg1;
2598 protobuf_unittest::TestDiffMessage msg2;
2599
2600 protobuf_unittest::TestDiffMessage::Item* item;
2601
2602 item = msg1.add_item();
2603 item->set_a(3);
2604
2605 item = msg2.add_item();
2606 item->set_a(4);
2607
2608 util::MessageDifferencer differencer;
2609 differencer.IgnoreField(GetFieldDescriptor(msg1, "item"));
2610
2611 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2612 }
2613
TEST(MessageDifferencerTest,IgnoreField_Missing)2614 TEST(MessageDifferencerTest, IgnoreField_Missing) {
2615 protobuf_unittest::TestField msg1;
2616 protobuf_unittest::TestField msg2;
2617
2618 msg1.set_c(3);
2619 msg1.add_rc(1);
2620
2621 msg2.add_rc(1);
2622
2623 util::MessageDifferencer differencer;
2624 differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
2625
2626 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2627 ExpectEqualsWithDifferencer(&differencer, msg2, msg1);
2628 }
2629
TEST(MessageDifferencerTest,IgnoreField_Multiple)2630 TEST(MessageDifferencerTest, IgnoreField_Multiple) {
2631 protobuf_unittest::TestField msg1;
2632 protobuf_unittest::TestField msg2;
2633
2634 msg1.set_c(3);
2635 msg1.add_rc(1);
2636 msg1.add_rc(2);
2637
2638 msg2.set_c(5);
2639 msg2.add_rc(1);
2640 msg2.add_rc(3);
2641
2642 const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2643 const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2644
2645 { // Ignore c
2646 util::MessageDifferencer differencer;
2647 differencer.IgnoreField(c);
2648
2649 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2650 }
2651 { // Ignore rc
2652 util::MessageDifferencer differencer;
2653 differencer.IgnoreField(rc);
2654
2655 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2656 }
2657 { // Ignore both
2658 util::MessageDifferencer differencer;
2659 differencer.IgnoreField(c);
2660 differencer.IgnoreField(rc);
2661
2662 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2663 }
2664 }
2665
TEST(MessageDifferencerTest,IgnoreField_NestedMessage)2666 TEST(MessageDifferencerTest, IgnoreField_NestedMessage) {
2667 protobuf_unittest::TestDiffMessage msg1;
2668 protobuf_unittest::TestDiffMessage msg2;
2669
2670 protobuf_unittest::TestField* field;
2671
2672 field = msg1.add_rm();
2673 field->set_c(3);
2674 field->add_rc(1);
2675
2676 field = msg2.add_rm();
2677 field->set_c(4);
2678 field->add_rc(1);
2679
2680 util::MessageDifferencer differencer;
2681 differencer.IgnoreField(GetFieldDescriptor(msg1, "rm.c"));
2682
2683 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2684 }
2685
TEST(MessageDifferencerTest,IgnoreField_NestedGroup)2686 TEST(MessageDifferencerTest, IgnoreField_NestedGroup) {
2687 protobuf_unittest::TestDiffMessage msg1;
2688 protobuf_unittest::TestDiffMessage msg2;
2689
2690 protobuf_unittest::TestDiffMessage::Item* item;
2691
2692 item = msg1.add_item();
2693 item->set_a(3);
2694 item->set_b("foo");
2695
2696 item = msg2.add_item();
2697 item->set_a(4);
2698 item->set_b("foo");
2699
2700 util::MessageDifferencer differencer;
2701 differencer.IgnoreField(GetFieldDescriptor(msg1, "item.a"));
2702
2703 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2704 }
2705
TEST(MessageDifferencerTest,IgnoreField_InsideSet)2706 TEST(MessageDifferencerTest, IgnoreField_InsideSet) {
2707 protobuf_unittest::TestDiffMessage msg1;
2708 protobuf_unittest::TestDiffMessage msg2;
2709
2710 protobuf_unittest::TestDiffMessage::Item* item;
2711
2712 item = msg1.add_item();
2713 item->set_a(1);
2714 item->set_b("foo");
2715 item->add_ra(1);
2716
2717 item = msg1.add_item();
2718 item->set_a(2);
2719 item->set_b("bar");
2720 item->add_ra(2);
2721
2722 item = msg2.add_item();
2723 item->set_a(2);
2724 item->set_b("bar");
2725 item->add_ra(2);
2726
2727 item = msg2.add_item();
2728 item->set_a(1);
2729 item->set_b("baz");
2730 item->add_ra(1);
2731
2732 const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2733 const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
2734
2735 util::MessageDifferencer differencer;
2736 differencer.IgnoreField(b);
2737 differencer.TreatAsSet(item_desc);
2738
2739 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2740 }
2741
TEST(MessageDifferencerTest,IgnoreField_InsideMap)2742 TEST(MessageDifferencerTest, IgnoreField_InsideMap) {
2743 protobuf_unittest::TestDiffMessage msg1;
2744 protobuf_unittest::TestDiffMessage msg2;
2745
2746 protobuf_unittest::TestDiffMessage::Item* item;
2747
2748 item = msg1.add_item();
2749 item->set_a(1);
2750 item->set_b("foo");
2751 item->add_ra(1);
2752
2753 item = msg1.add_item();
2754 item->set_a(2);
2755 item->set_b("bar");
2756 item->add_ra(2);
2757
2758 item = msg2.add_item();
2759 item->set_a(2);
2760 item->set_b("bar");
2761 item->add_ra(2);
2762
2763 item = msg2.add_item();
2764 item->set_a(1);
2765 item->set_b("baz");
2766 item->add_ra(1);
2767
2768 const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2769 const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
2770 const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
2771
2772 util::MessageDifferencer differencer;
2773 differencer.IgnoreField(b);
2774 differencer.TreatAsMap(item_desc, a);
2775
2776 ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2777 }
2778
TEST(MessageDifferencerTest,IgnoreField_DoesNotIgnoreKey)2779 TEST(MessageDifferencerTest, IgnoreField_DoesNotIgnoreKey) {
2780 protobuf_unittest::TestDiffMessage msg1;
2781 protobuf_unittest::TestDiffMessage msg2;
2782
2783 protobuf_unittest::TestDiffMessage::Item* item;
2784
2785 item = msg1.add_item();
2786 item->set_a(1);
2787 item->set_b("foo");
2788 item->add_ra(1);
2789
2790 item = msg2.add_item();
2791 item->set_a(2);
2792 item->set_b("foo");
2793 item->add_ra(1);
2794
2795 const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2796 const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
2797
2798 util::MessageDifferencer differencer;
2799 differencer.IgnoreField(a);
2800 differencer.TreatAsMap(item_desc, a);
2801
2802 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2803 }
2804
TEST(MessageDifferencerTest,IgnoreField_TrumpsCompareWithFields)2805 TEST(MessageDifferencerTest, IgnoreField_TrumpsCompareWithFields) {
2806 protobuf_unittest::TestField msg1;
2807 protobuf_unittest::TestField msg2;
2808
2809 msg1.set_c(3);
2810 msg1.add_rc(1);
2811 msg1.add_rc(2);
2812
2813 msg2.set_c(3);
2814 msg2.add_rc(1);
2815 msg2.add_rc(3);
2816
2817 const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2818 const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2819
2820 std::vector<const FieldDescriptor*> fields;
2821 fields.push_back(c);
2822 fields.push_back(rc);
2823
2824 util::MessageDifferencer differencer;
2825 differencer.IgnoreField(rc);
2826
2827 differencer.set_scope(util::MessageDifferencer::FULL);
2828 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2829
2830 differencer.set_scope(util::MessageDifferencer::PARTIAL);
2831 EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2832 }
2833
TEST(MessageDifferencerTest,IgnoreField_SetReportIgnoresFalse)2834 TEST(MessageDifferencerTest, IgnoreField_SetReportIgnoresFalse) {
2835 protobuf_unittest::TestField msg1;
2836 protobuf_unittest::TestField msg2;
2837
2838 msg1.set_a(1);
2839 msg1.set_b(2);
2840 msg1.set_c(3);
2841 msg1.add_rc(1);
2842 msg1.add_rc(2);
2843
2844 msg2.set_a(1);
2845 msg2.set_b(1);
2846
2847 const FieldDescriptor* a = GetFieldDescriptor(msg1, "a");
2848 const FieldDescriptor* b = GetFieldDescriptor(msg1, "b");
2849 const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2850 const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2851
2852 std::vector<const FieldDescriptor*> fields;
2853 fields.push_back(a);
2854 fields.push_back(b);
2855 fields.push_back(c);
2856 fields.push_back(rc);
2857
2858 std::string diff_report;
2859 util::MessageDifferencer differencer;
2860 differencer.set_report_ignores(false);
2861 differencer.set_report_matches(true);
2862 differencer.ReportDifferencesToString(&diff_report);
2863 differencer.IgnoreField(c);
2864 differencer.IgnoreField(rc);
2865 differencer.set_scope(util::MessageDifferencer::FULL);
2866 EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2867
2868 EXPECT_EQ(diff_report,
2869 "matched: a : 1\n"
2870 "modified: b: 2 -> 1\n");
2871 }
2872
2873
2874 // Test class to save a copy of the last field_context.parent_fields() vector
2875 // passed to the comparison function.
2876 class ParentSavingFieldComparator : public util::FieldComparator {
2877 public:
ParentSavingFieldComparator()2878 ParentSavingFieldComparator() {}
2879
Compare(const Message & message_1,const Message & message_2,const FieldDescriptor * field,int index_1,int index_2,const util::FieldContext * field_context)2880 ComparisonResult Compare(const Message& message_1, const Message& message_2,
2881 const FieldDescriptor* field, int index_1,
2882 int index_2,
2883 const util::FieldContext* field_context) override {
2884 if (field_context) parent_fields_ = *(field_context->parent_fields());
2885 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2886 return RECURSE;
2887 } else {
2888 return SAME;
2889 }
2890 }
2891
parent_fields()2892 std::vector<util::MessageDifferencer::SpecificField> parent_fields() {
2893 return parent_fields_;
2894 }
2895
2896 private:
2897 std::vector<util::MessageDifferencer::SpecificField> parent_fields_;
2898 };
2899
2900 // Tests if MessageDifferencer sends the parent fields in the FieldContext
2901 // parameter.
TEST(MessageDifferencerTest,FieldContextParentFieldsTest)2902 TEST(MessageDifferencerTest, FieldContextParentFieldsTest) {
2903 protobuf_unittest::TestDiffMessage msg1;
2904 msg1.add_rm()->set_c(1);
2905 protobuf_unittest::TestDiffMessage msg2;
2906 msg2.add_rm()->set_c(1);
2907
2908 ParentSavingFieldComparator field_comparator;
2909 util::MessageDifferencer differencer;
2910 differencer.set_field_comparator(&field_comparator);
2911 differencer.Compare(msg1, msg2);
2912
2913 // We want only one parent with the name "rm"
2914 ASSERT_EQ(1, field_comparator.parent_fields().size());
2915 EXPECT_EQ("rm", field_comparator.parent_fields()[0].field->name());
2916 }
2917
2918
2919 class ComparisonTest : public testing::Test {
2920 protected:
ComparisonTest()2921 ComparisonTest() : use_equivalency_(false), repeated_field_as_set_(false) {
2922 // Setup the test.
2923 TestUtil::SetAllFields(&proto1_);
2924 TestUtil::SetAllFields(&proto2_);
2925
2926 TestUtil::SetAllExtensions(&proto1ex_);
2927 TestUtil::SetAllExtensions(&proto2ex_);
2928
2929 TestUtil::SetAllFieldsAndExtensions(&orderings_proto1_);
2930 TestUtil::SetAllFieldsAndExtensions(&orderings_proto2_);
2931
2932 unknown1_ = empty1_.mutable_unknown_fields();
2933 unknown2_ = empty2_.mutable_unknown_fields();
2934 }
2935
~ComparisonTest()2936 ~ComparisonTest() override {}
2937
SetSpecialFieldOption(const Message & message,util::MessageDifferencer * d)2938 void SetSpecialFieldOption(const Message& message,
2939 util::MessageDifferencer* d) {
2940 if (!ignored_field_.empty()) {
2941 d->IgnoreField(GetFieldDescriptor(message, ignored_field_));
2942 }
2943
2944 if (repeated_field_as_set_) {
2945 d->set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
2946 }
2947
2948 if (!set_field_.empty()) {
2949 d->TreatAsSet(GetFieldDescriptor(message, set_field_));
2950 }
2951
2952 if (!map_field_.empty() && !map_key_.empty()) {
2953 d->TreatAsMap(
2954 GetFieldDescriptor(message, map_field_),
2955 GetFieldDescriptor(message, absl::StrCat(map_field_, ".", map_key_)));
2956 }
2957 }
2958
Run(const Message & msg1,const Message & msg2)2959 std::string Run(const Message& msg1, const Message& msg2) {
2960 std::string output;
2961
2962 // Setup the comparison.
2963 util::MessageDifferencer differencer;
2964 differencer.ReportDifferencesToString(&output);
2965
2966 if (use_equivalency_) {
2967 differencer.set_message_field_comparison(
2968 util::MessageDifferencer::EQUIVALENT);
2969 }
2970
2971 SetSpecialFieldOption(msg1, &differencer);
2972
2973 // Conduct the comparison.
2974 EXPECT_FALSE(differencer.Compare(msg1, msg2));
2975
2976 return output;
2977 }
2978
Run()2979 std::string Run() { return Run(proto1_, proto2_); }
2980
RunOrder()2981 std::string RunOrder() { return Run(orderings_proto1_, orderings_proto2_); }
2982
RunEx()2983 std::string RunEx() { return Run(proto1ex_, proto2ex_); }
2984
RunDiff()2985 std::string RunDiff() { return Run(proto1diff_, proto2diff_); }
2986
RunUn()2987 std::string RunUn() { return Run(empty1_, empty2_); }
2988
use_equivalency()2989 void use_equivalency() { use_equivalency_ = true; }
2990
repeated_field_as_set()2991 void repeated_field_as_set() { repeated_field_as_set_ = true; }
2992
field_as_set(const std::string & field)2993 void field_as_set(const std::string& field) { set_field_ = field; }
2994
field_as_map(const std::string & field,const std::string & key)2995 void field_as_map(const std::string& field, const std::string& key) {
2996 map_field_ = field;
2997 map_key_ = key;
2998 }
2999
ignore_field(const std::string & field)3000 void ignore_field(const std::string& field) { ignored_field_ = field; }
3001
3002 unittest::TestAllTypes proto1_;
3003 unittest::TestAllTypes proto2_;
3004
3005 unittest::TestFieldOrderings orderings_proto1_;
3006 unittest::TestFieldOrderings orderings_proto2_;
3007
3008 unittest::TestAllExtensions proto1ex_;
3009 unittest::TestAllExtensions proto2ex_;
3010
3011 unittest::TestDiffMessage proto1diff_;
3012 unittest::TestDiffMessage proto2diff_;
3013
3014 unittest::TestEmptyMessage empty1_;
3015 unittest::TestEmptyMessage empty2_;
3016
3017 unittest::TestMap map_proto1_;
3018 unittest::TestMap map_proto2_;
3019
3020 UnknownFieldSet* unknown1_;
3021 UnknownFieldSet* unknown2_;
3022
3023 bool use_equivalency_;
3024 bool repeated_field_as_set_;
3025
3026 std::string set_field_;
3027 std::string map_field_;
3028 std::string map_key_;
3029 std::string ignored_field_;
3030 };
3031
3032 // Basic tests.
TEST_F(ComparisonTest,AdditionTest)3033 TEST_F(ComparisonTest, AdditionTest) {
3034 proto1_.clear_optional_int32();
3035
3036 EXPECT_EQ("added: optional_int32: 101\n", Run());
3037 }
3038
TEST_F(ComparisonTest,Addition_OrderTest)3039 TEST_F(ComparisonTest, Addition_OrderTest) {
3040 orderings_proto1_.clear_my_int();
3041
3042 EXPECT_EQ("added: my_int: 1\n", RunOrder());
3043 }
3044
TEST_F(ComparisonTest,DeletionTest)3045 TEST_F(ComparisonTest, DeletionTest) {
3046 proto2_.clear_optional_int32();
3047
3048 EXPECT_EQ("deleted: optional_int32: 101\n", Run());
3049 }
3050
TEST_F(ComparisonTest,Deletion_OrderTest)3051 TEST_F(ComparisonTest, Deletion_OrderTest) {
3052 orderings_proto2_.clear_my_string();
3053
3054 EXPECT_EQ("deleted: my_string: \"foo\"\n", RunOrder());
3055 }
3056
TEST_F(ComparisonTest,RepeatedDeletionTest)3057 TEST_F(ComparisonTest, RepeatedDeletionTest) {
3058 proto2_.clear_repeated_int32();
3059
3060 EXPECT_EQ(
3061 "deleted: repeated_int32[0]: 201\n"
3062 "deleted: repeated_int32[1]: 301\n",
3063 Run());
3064 }
3065
TEST_F(ComparisonTest,ModificationTest)3066 TEST_F(ComparisonTest, ModificationTest) {
3067 proto1_.set_optional_int32(-1);
3068
3069 EXPECT_EQ("modified: optional_int32: -1 -> 101\n", Run());
3070 }
3071
3072 // Basic equivalency tests.
TEST_F(ComparisonTest,EquivalencyAdditionTest)3073 TEST_F(ComparisonTest, EquivalencyAdditionTest) {
3074 use_equivalency();
3075
3076 proto1_.clear_optional_int32();
3077
3078 EXPECT_EQ("modified: optional_int32: 0 -> 101\n", Run());
3079 }
3080
TEST_F(ComparisonTest,EquivalencyDeletionTest)3081 TEST_F(ComparisonTest, EquivalencyDeletionTest) {
3082 use_equivalency();
3083
3084 proto2_.clear_optional_int32();
3085
3086 EXPECT_EQ("modified: optional_int32: 101 -> 0\n", Run());
3087 }
3088
3089 // Group tests.
TEST_F(ComparisonTest,GroupAdditionTest)3090 TEST_F(ComparisonTest, GroupAdditionTest) {
3091 proto1_.mutable_optionalgroup()->clear_a();
3092
3093 EXPECT_EQ("added: optionalgroup.a: 117\n", Run());
3094 }
3095
TEST_F(ComparisonTest,GroupDeletionTest)3096 TEST_F(ComparisonTest, GroupDeletionTest) {
3097 proto2_.mutable_optionalgroup()->clear_a();
3098
3099 EXPECT_EQ("deleted: optionalgroup.a: 117\n", Run());
3100 }
3101
TEST_F(ComparisonTest,GroupModificationTest)3102 TEST_F(ComparisonTest, GroupModificationTest) {
3103 proto1_.mutable_optionalgroup()->set_a(2);
3104
3105 EXPECT_EQ("modified: optionalgroup.a: 2 -> 117\n", Run());
3106 }
3107
TEST_F(ComparisonTest,GroupFullAdditionTest)3108 TEST_F(ComparisonTest, GroupFullAdditionTest) {
3109 proto1_.clear_optionalgroup();
3110
3111 // Note the difference in the output between this and GroupAdditionTest.
3112 EXPECT_EQ("added: optionalgroup: { a: 117 }\n", Run());
3113 }
3114
TEST_F(ComparisonTest,GroupFullDeletionTest)3115 TEST_F(ComparisonTest, GroupFullDeletionTest) {
3116 proto2_.clear_optionalgroup();
3117
3118 EXPECT_EQ("deleted: optionalgroup: { a: 117 }\n", Run());
3119 }
3120
TEST_F(ComparisonTest,RepeatedSetOptionTest)3121 TEST_F(ComparisonTest, RepeatedSetOptionTest) {
3122 repeated_field_as_set();
3123
3124 proto2_.clear_repeatedgroup();
3125 proto1_.clear_repeatedgroup();
3126 proto1_.add_repeatedgroup()->set_a(317);
3127 proto2_.add_repeatedgroup()->set_a(909);
3128 proto2_.add_repeatedgroup()->set_a(907);
3129 proto1_.add_repeatedgroup()->set_a(904);
3130 proto1_.add_repeatedgroup()->set_a(907);
3131 proto1_.add_repeatedgroup()->set_a(909);
3132
3133 EXPECT_EQ(
3134 "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
3135 "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
3136 "deleted: repeatedgroup[0]: { a: 317 }\n"
3137 "deleted: repeatedgroup[1]: { a: 904 }\n",
3138 Run());
3139 }
3140
TEST_F(ComparisonTest,RepeatedSetOptionTest_Ex)3141 TEST_F(ComparisonTest, RepeatedSetOptionTest_Ex) {
3142 repeated_field_as_set();
3143
3144 proto1ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
3145 proto2ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
3146 proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
3147 ->set_bb(909);
3148 proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
3149 ->set_bb(907);
3150 proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
3151 ->set_bb(904);
3152 proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
3153 ->set_bb(907);
3154 proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
3155 ->set_bb(909);
3156
3157 EXPECT_EQ(
3158 "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
3159 " (protobuf_unittest.repeated_nested_message_extension)[0] :"
3160 " { bb: 909 }\n"
3161 "deleted: (protobuf_unittest.repeated_nested_message_extension)[0]:"
3162 " { bb: 904 }\n",
3163 RunEx());
3164 }
3165
TEST_F(ComparisonTest,RepeatedMapFieldTest_Group)3166 TEST_F(ComparisonTest, RepeatedMapFieldTest_Group) {
3167 field_as_map("repeatedgroup", "a");
3168 proto1_.clear_repeatedgroup();
3169 proto2_.clear_repeatedgroup();
3170
3171 proto1_.add_repeatedgroup()->set_a(317); // deleted
3172 proto1_.add_repeatedgroup()->set_a(904); // deleted
3173 proto1_.add_repeatedgroup()->set_a(907); // moved from
3174 proto1_.add_repeatedgroup()->set_a(909); // moved from
3175
3176 proto2_.add_repeatedgroup()->set_a(909); // moved to
3177 proto2_.add_repeatedgroup()->set_a(318); // added
3178 proto2_.add_repeatedgroup()->set_a(907); // moved to
3179
3180 EXPECT_EQ(
3181 "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
3182 "added: repeatedgroup[1]: { a: 318 }\n"
3183 "deleted: repeatedgroup[0]: { a: 317 }\n"
3184 "deleted: repeatedgroup[1]: { a: 904 }\n",
3185 Run());
3186 }
3187
TEST_F(ComparisonTest,RepeatedMapFieldTest_MessageKey)3188 TEST_F(ComparisonTest, RepeatedMapFieldTest_MessageKey) {
3189 // Use m as key, but use b as value.
3190 field_as_map("item", "m");
3191
3192 protobuf_unittest::TestDiffMessage msg1;
3193 protobuf_unittest::TestDiffMessage msg2;
3194 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
3195
3196 // The following code creates one deletion, one addition and two moved fields
3197 // on the messages.
3198 item->mutable_m()->set_c(0);
3199 item->set_b("first");
3200 item = msg1.add_item();
3201 item->mutable_m()->set_c(2);
3202 item->set_b("second");
3203 item = msg1.add_item();
3204 item->set_b("null"); // empty key moved
3205 item = msg1.add_item();
3206 item->mutable_m()->set_c(3);
3207 item->set_b("third"); // deletion
3208 item = msg1.add_item();
3209 item->mutable_m()->set_c(2);
3210 item->set_b("second"); // duplicated key ( deletion )
3211 item = msg2.add_item();
3212 item->mutable_m()->set_c(2);
3213 item->set_b("second"); // modification
3214 item = msg2.add_item();
3215 item->mutable_m()->set_c(4);
3216 item->set_b("fourth"); // addition
3217 item = msg2.add_item();
3218 item->mutable_m()->set_c(0);
3219 item->set_b("fist"); // move with change
3220 item = msg2.add_item();
3221 item->set_b("null");
3222
3223 EXPECT_EQ(
3224 "modified: item[0].b -> item[2].b: \"first\" -> \"fist\"\n"
3225 "moved: item[1] -> item[0] : { b: \"second\" m { c: 2 } }\n"
3226 "moved: item[2] -> item[3] : { b: \"null\" }\n"
3227 "added: item[1]: { b: \"fourth\" m { c: 4 } }\n"
3228 "deleted: item[3]: { b: \"third\" m { c: 3 } }\n"
3229 "deleted: item[4]: { b: \"second\" m { c: 2 } }\n",
3230 Run(msg1, msg2));
3231 }
3232
TEST_F(ComparisonTest,RepeatedFieldSetTest_SetOfSet)3233 TEST_F(ComparisonTest, RepeatedFieldSetTest_SetOfSet) {
3234 repeated_field_as_set();
3235 // Create the testing protos
3236 protobuf_unittest::TestDiffMessage msg1;
3237 protobuf_unittest::TestDiffMessage msg2;
3238
3239 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
3240 item->add_ra(1);
3241 item->add_ra(2);
3242 item->add_ra(3);
3243 item = msg1.add_item();
3244 item->add_ra(5);
3245 item->add_ra(6);
3246 item = msg1.add_item();
3247 item->add_ra(1);
3248 item->add_ra(3);
3249 item = msg1.add_item();
3250 item->add_ra(6);
3251 item->add_ra(7);
3252 item->add_ra(8);
3253
3254 item = msg2.add_item();
3255 item->add_ra(6);
3256 item->add_ra(5);
3257 item = msg2.add_item();
3258 item->add_ra(6);
3259 item->add_ra(8);
3260 item = msg2.add_item();
3261 item->add_ra(1);
3262 item->add_ra(3);
3263 item = msg2.add_item();
3264 item->add_ra(3);
3265 item->add_ra(2);
3266 item->add_ra(1);
3267
3268 // Compare
3269 EXPECT_EQ(
3270 "moved: item[0].ra[0] -> item[3].ra[2] : 1\n"
3271 "moved: item[0].ra[2] -> item[3].ra[0] : 3\n"
3272 "moved: item[0] -> item[3] : { ra: 1 ra: 2 ra: 3 }\n"
3273 "moved: item[1].ra[0] -> item[0].ra[1] : 5\n"
3274 "moved: item[1].ra[1] -> item[0].ra[0] : 6\n"
3275 "moved: item[1] -> item[0] : { ra: 5 ra: 6 }\n"
3276 "added: item[1]: { ra: 6 ra: 8 }\n"
3277 "deleted: item[3]: { ra: 6 ra: 7 ra: 8 }\n",
3278 Run(msg1, msg2));
3279 }
3280
TEST_F(ComparisonTest,RepeatedMapFieldTest_RepeatedKey)3281 TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedKey) {
3282 // used rb as a key, but b is the value.
3283 repeated_field_as_set();
3284 field_as_map("item", "rb");
3285
3286 protobuf_unittest::TestDiffMessage msg1;
3287 protobuf_unittest::TestDiffMessage msg2;
3288 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
3289 item->add_rb("a");
3290 item->add_rb("b");
3291 item->set_b("first");
3292
3293 item = msg2.add_item();
3294 item->add_rb("c");
3295 item->set_b("second");
3296
3297 item = msg2.add_item();
3298 item->add_rb("b");
3299 item->add_rb("a");
3300 item->set_b("fist");
3301
3302 EXPECT_EQ(
3303 "modified: item[0].b -> item[1].b: \"first\" -> \"fist\"\n"
3304 "moved: item[0].rb[0] -> item[1].rb[1] : \"a\"\n"
3305 "moved: item[0].rb[1] -> item[1].rb[0] : \"b\"\n"
3306 "added: item[0]: { b: \"second\" rb: \"c\" }\n",
3307 Run(msg1, msg2));
3308 }
3309
TEST_F(ComparisonTest,RepeatedMapFieldTest_RepeatedMessageKey)3310 TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedMessageKey) {
3311 field_as_map("item", "rm");
3312
3313 protobuf_unittest::TestDiffMessage msg1;
3314 protobuf_unittest::TestDiffMessage msg2;
3315 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
3316 protobuf_unittest::TestField* key = item->add_rm();
3317 key->set_c(2);
3318 key->add_rc(10);
3319 key->add_rc(10);
3320 item = msg1.add_item();
3321 key = item->add_rm();
3322 key->set_c(0);
3323 key->add_rc(1);
3324 key->add_rc(2);
3325 key = item->add_rm();
3326 key->set_c(0);
3327 item->add_rb("first");
3328
3329 item = msg2.add_item();
3330 item->CopyFrom(msg1.item(1));
3331 item->add_rb("second");
3332
3333 EXPECT_EQ(
3334 "added: item[0].rb[1]: \"second\"\n"
3335 "deleted: item[0]: { rm { c: 2 rc: 10 rc: 10 } }\n",
3336 Run(msg1, msg2));
3337 }
3338
TEST_F(ComparisonTest,RepeatedSetOptionTest_Unknown)3339 TEST_F(ComparisonTest, RepeatedSetOptionTest_Unknown) {
3340 // Currently, as_set option doesn't have affects on unknown field.
3341 // If needed, this feature will be added by request.
3342 repeated_field_as_set();
3343 unknown1_->AddGroup(245)->AddFixed32(248, 1);
3344 unknown2_->AddGroup(245)->AddFixed32(248, 3);
3345 unknown2_->AddGroup(245)->AddFixed32(248, 1);
3346
3347 // We expect it behaves the same as normal comparison.
3348 EXPECT_EQ(
3349 "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
3350 "added: 245[1]: { ... }\n",
3351 RunUn());
3352 }
3353
TEST_F(ComparisonTest,Matching_Unknown)3354 TEST_F(ComparisonTest, Matching_Unknown) {
3355 unknown1_->AddGroup(245)->AddFixed32(248, 1);
3356 unknown2_->AddGroup(245)->AddFixed32(248, 1);
3357 unknown1_->AddGroup(245)->AddFixed32(248, 3);
3358 unknown2_->AddGroup(245)->AddFixed32(248, 3);
3359 unknown2_->AddLengthDelimited(242, "cat");
3360 unknown2_->AddGroup(246)->AddFixed32(248, 4);
3361
3362 // report_match is false so only added/modified fields are expected.
3363 EXPECT_EQ(
3364 "added: 242[0]: \"cat\"\n"
3365 "added: 246[0]: { ... }\n",
3366 RunUn());
3367 }
3368
TEST_F(ComparisonTest,RepeatedSetFieldTest)3369 TEST_F(ComparisonTest, RepeatedSetFieldTest) {
3370 field_as_set("repeatedgroup");
3371
3372 proto1_.clear_repeatedgroup();
3373 proto2_.clear_repeatedgroup();
3374 proto2_.add_repeatedgroup()->set_a(909);
3375 proto2_.add_repeatedgroup()->set_a(907);
3376 proto1_.add_repeatedgroup()->set_a(317);
3377 proto1_.add_repeatedgroup()->set_a(904);
3378 proto1_.add_repeatedgroup()->set_a(907);
3379 proto1_.add_repeatedgroup()->set_a(909);
3380
3381 EXPECT_EQ(
3382 "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
3383 "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
3384 "deleted: repeatedgroup[0]: { a: 317 }\n"
3385 "deleted: repeatedgroup[1]: { a: 904 }\n",
3386 Run());
3387 }
3388
3389 // Embedded message tests.
TEST_F(ComparisonTest,EmbeddedAdditionTest)3390 TEST_F(ComparisonTest, EmbeddedAdditionTest) {
3391 proto1_.mutable_optional_nested_message()->clear_bb();
3392
3393 EXPECT_EQ("added: optional_nested_message.bb: 118\n", Run());
3394 }
3395
TEST_F(ComparisonTest,EmbeddedDeletionTest)3396 TEST_F(ComparisonTest, EmbeddedDeletionTest) {
3397 proto2_.mutable_optional_nested_message()->clear_bb();
3398
3399 EXPECT_EQ("deleted: optional_nested_message.bb: 118\n", Run());
3400 }
3401
TEST_F(ComparisonTest,EmbeddedModificationTest)3402 TEST_F(ComparisonTest, EmbeddedModificationTest) {
3403 proto1_.mutable_optional_nested_message()->set_bb(2);
3404
3405 EXPECT_EQ("modified: optional_nested_message.bb: 2 -> 118\n", Run());
3406 }
3407
TEST_F(ComparisonTest,EmbeddedFullAdditionTest)3408 TEST_F(ComparisonTest, EmbeddedFullAdditionTest) {
3409 proto1_.clear_optional_nested_message();
3410
3411 EXPECT_EQ("added: optional_nested_message: { bb: 118 }\n", Run());
3412 }
3413
TEST_F(ComparisonTest,EmbeddedPartialAdditionTest)3414 TEST_F(ComparisonTest, EmbeddedPartialAdditionTest) {
3415 proto1_.clear_optional_nested_message();
3416 proto2_.mutable_optional_nested_message()->clear_bb();
3417
3418 EXPECT_EQ("added: optional_nested_message: { }\n", Run());
3419 }
3420
TEST_F(ComparisonTest,EmbeddedFullDeletionTest)3421 TEST_F(ComparisonTest, EmbeddedFullDeletionTest) {
3422 proto2_.clear_optional_nested_message();
3423
3424 EXPECT_EQ("deleted: optional_nested_message: { bb: 118 }\n", Run());
3425 }
3426
3427 // Repeated element tests.
TEST_F(ComparisonTest,BasicRepeatedTest)3428 TEST_F(ComparisonTest, BasicRepeatedTest) {
3429 proto1_.clear_repeated_int32();
3430 proto2_.clear_repeated_int32();
3431
3432 proto1_.add_repeated_int32(500);
3433 proto1_.add_repeated_int32(501);
3434 proto1_.add_repeated_int32(502);
3435 proto1_.add_repeated_int32(503);
3436 proto1_.add_repeated_int32(500);
3437
3438 proto2_.add_repeated_int32(500);
3439 proto2_.add_repeated_int32(509);
3440 proto2_.add_repeated_int32(502);
3441 proto2_.add_repeated_int32(504);
3442
3443 EXPECT_EQ(
3444 "modified: repeated_int32[1]: 501 -> 509\n"
3445 "modified: repeated_int32[3]: 503 -> 504\n"
3446 "deleted: repeated_int32[4]: 500\n",
3447 Run());
3448 }
3449
TEST_F(ComparisonTest,BasicRepeatedTest_SetOption)3450 TEST_F(ComparisonTest, BasicRepeatedTest_SetOption) {
3451 repeated_field_as_set();
3452 proto1_.clear_repeated_int32();
3453 proto2_.clear_repeated_int32();
3454
3455 proto1_.add_repeated_int32(501);
3456 proto1_.add_repeated_int32(502);
3457 proto1_.add_repeated_int32(503);
3458 proto1_.add_repeated_int32(500);
3459 proto1_.add_repeated_int32(500);
3460
3461 proto2_.add_repeated_int32(500);
3462 proto2_.add_repeated_int32(509);
3463 proto2_.add_repeated_int32(503);
3464 proto2_.add_repeated_int32(502);
3465 proto2_.add_repeated_int32(504);
3466
3467 EXPECT_EQ(
3468 "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
3469 "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
3470 "added: repeated_int32[1]: 509\n"
3471 "added: repeated_int32[4]: 504\n"
3472 "deleted: repeated_int32[0]: 501\n"
3473 "deleted: repeated_int32[4]: 500\n",
3474 Run());
3475 }
3476
TEST_F(ComparisonTest,BasicRepeatedTest_SetField)3477 TEST_F(ComparisonTest, BasicRepeatedTest_SetField) {
3478 field_as_set("repeated_int32");
3479 proto1_.clear_repeated_int32();
3480 proto2_.clear_repeated_int32();
3481
3482 proto1_.add_repeated_int32(501);
3483 proto1_.add_repeated_int32(502);
3484 proto1_.add_repeated_int32(503);
3485 proto1_.add_repeated_int32(500);
3486 proto1_.add_repeated_int32(500);
3487
3488 proto2_.add_repeated_int32(500);
3489 proto2_.add_repeated_int32(509);
3490 proto2_.add_repeated_int32(503);
3491 proto2_.add_repeated_int32(502);
3492 proto2_.add_repeated_int32(504);
3493
3494 EXPECT_EQ(
3495 "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
3496 "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
3497 "added: repeated_int32[1]: 509\n"
3498 "added: repeated_int32[4]: 504\n"
3499 "deleted: repeated_int32[0]: 501\n"
3500 "deleted: repeated_int32[4]: 500\n",
3501 Run());
3502 }
3503
3504 // Multiple action tests.
TEST_F(ComparisonTest,AddDeleteTest)3505 TEST_F(ComparisonTest, AddDeleteTest) {
3506 proto1_.clear_optional_int32();
3507 proto2_.clear_optional_int64();
3508
3509 EXPECT_EQ(
3510 "added: optional_int32: 101\n"
3511 "deleted: optional_int64: 102\n",
3512 Run());
3513 }
3514
TEST_F(ComparisonTest,AddDelete_FieldOrderingTest)3515 TEST_F(ComparisonTest, AddDelete_FieldOrderingTest) {
3516 orderings_proto1_.ClearExtension(unittest::my_extension_string);
3517 orderings_proto2_.clear_my_int();
3518
3519 EXPECT_EQ(
3520 "deleted: my_int: 1\n"
3521 "added: (protobuf_unittest.my_extension_string): \"bar\"\n",
3522 RunOrder());
3523 }
3524
TEST_F(ComparisonTest,AllThreeTest)3525 TEST_F(ComparisonTest, AllThreeTest) {
3526 proto1_.clear_optional_int32();
3527 proto2_.clear_optional_float();
3528 proto2_.set_optional_string("hello world!");
3529
3530 EXPECT_EQ(
3531 "added: optional_int32: 101\n"
3532 "deleted: optional_float: 111\n"
3533 "modified: optional_string: \"115\" -> \"hello world!\"\n",
3534 Run());
3535 }
3536
TEST_F(ComparisonTest,SandwichTest)3537 TEST_F(ComparisonTest, SandwichTest) {
3538 proto1_.clear_optional_int64();
3539 proto1_.clear_optional_uint32();
3540
3541 proto2_.clear_optional_uint64();
3542
3543 EXPECT_EQ(
3544 "added: optional_int64: 102\n"
3545 "added: optional_uint32: 103\n"
3546 "deleted: optional_uint64: 104\n",
3547 Run());
3548 }
3549
TEST_F(ComparisonTest,IgnoredNoChangeTest)3550 TEST_F(ComparisonTest, IgnoredNoChangeTest) {
3551 proto1diff_.set_v(3);
3552 proto2diff_.set_v(3);
3553 proto2diff_.set_w("foo");
3554
3555 ignore_field("v");
3556
3557 EXPECT_EQ(
3558 "ignored: v\n"
3559 "added: w: \"foo\"\n",
3560 RunDiff());
3561 }
3562
TEST_F(ComparisonTest,IgnoredAddTest)3563 TEST_F(ComparisonTest, IgnoredAddTest) {
3564 proto2diff_.set_v(3);
3565 proto2diff_.set_w("foo");
3566
3567 ignore_field("v");
3568
3569 EXPECT_EQ(
3570 "ignored: v\n"
3571 "added: w: \"foo\"\n",
3572 RunDiff());
3573 }
3574
TEST_F(ComparisonTest,IgnoredDeleteTest)3575 TEST_F(ComparisonTest, IgnoredDeleteTest) {
3576 proto1diff_.set_v(3);
3577 proto2diff_.set_w("foo");
3578
3579 ignore_field("v");
3580
3581 EXPECT_EQ(
3582 "ignored: v\n"
3583 "added: w: \"foo\"\n",
3584 RunDiff());
3585 }
3586
TEST_F(ComparisonTest,IgnoredModifyTest)3587 TEST_F(ComparisonTest, IgnoredModifyTest) {
3588 proto1diff_.set_v(3);
3589 proto2diff_.set_v(4);
3590 proto2diff_.set_w("foo");
3591
3592 ignore_field("v");
3593
3594 EXPECT_EQ(
3595 "ignored: v\n"
3596 "added: w: \"foo\"\n",
3597 RunDiff());
3598 }
3599
TEST_F(ComparisonTest,IgnoredRepeatedAddTest)3600 TEST_F(ComparisonTest, IgnoredRepeatedAddTest) {
3601 proto1diff_.add_rv(3);
3602 proto1diff_.add_rv(4);
3603
3604 proto2diff_.add_rv(3);
3605 proto2diff_.add_rv(4);
3606 proto2diff_.add_rv(5);
3607
3608 proto2diff_.set_w("foo");
3609
3610 ignore_field("rv");
3611
3612 EXPECT_EQ(
3613 "ignored: rv\n"
3614 "added: w: \"foo\"\n",
3615 RunDiff());
3616 }
3617
TEST_F(ComparisonTest,IgnoredRepeatedDeleteTest)3618 TEST_F(ComparisonTest, IgnoredRepeatedDeleteTest) {
3619 proto1diff_.add_rv(3);
3620 proto1diff_.add_rv(4);
3621 proto1diff_.add_rv(5);
3622
3623 proto2diff_.add_rv(3);
3624 proto2diff_.add_rv(4);
3625
3626 proto2diff_.set_w("foo");
3627
3628 ignore_field("rv");
3629
3630 EXPECT_EQ(
3631 "ignored: rv\n"
3632 "added: w: \"foo\"\n",
3633 RunDiff());
3634 }
3635
TEST_F(ComparisonTest,IgnoredRepeatedModifyTest)3636 TEST_F(ComparisonTest, IgnoredRepeatedModifyTest) {
3637 proto1diff_.add_rv(3);
3638 proto1diff_.add_rv(4);
3639
3640 proto2diff_.add_rv(3);
3641 proto2diff_.add_rv(5);
3642
3643 proto2diff_.set_w("foo");
3644
3645 ignore_field("rv");
3646
3647 EXPECT_EQ(
3648 "ignored: rv\n"
3649 "added: w: \"foo\"\n",
3650 RunDiff());
3651 }
3652
TEST_F(ComparisonTest,IgnoredWholeNestedMessage)3653 TEST_F(ComparisonTest, IgnoredWholeNestedMessage) {
3654 proto1diff_.mutable_m()->set_c(3);
3655 proto2diff_.mutable_m()->set_c(4);
3656
3657 proto2diff_.set_w("foo");
3658
3659 ignore_field("m");
3660
3661 EXPECT_EQ(
3662 "added: w: \"foo\"\n"
3663 "ignored: m\n",
3664 RunDiff());
3665 }
3666
TEST_F(ComparisonTest,IgnoredNestedField)3667 TEST_F(ComparisonTest, IgnoredNestedField) {
3668 proto1diff_.mutable_m()->set_c(3);
3669 proto2diff_.mutable_m()->set_c(4);
3670
3671 proto2diff_.set_w("foo");
3672
3673 ignore_field("m.c");
3674
3675 EXPECT_EQ(
3676 "added: w: \"foo\"\n"
3677 "ignored: m.c\n",
3678 RunDiff());
3679 }
3680
TEST_F(ComparisonTest,IgnoredRepeatedNested)3681 TEST_F(ComparisonTest, IgnoredRepeatedNested) {
3682 proto1diff_.add_rm()->set_c(0);
3683 proto1diff_.add_rm()->set_c(1);
3684 proto2diff_.add_rm()->set_c(2);
3685 proto2diff_.add_rm()->set_c(3);
3686
3687 proto2diff_.set_w("foo");
3688
3689 ignore_field("rm.c");
3690
3691 EXPECT_EQ(
3692 "ignored: rm[0].c\n"
3693 "ignored: rm[1].c\n"
3694 "added: w: \"foo\"\n",
3695 RunDiff());
3696 }
3697
TEST_F(ComparisonTest,IgnoredNestedRepeated)3698 TEST_F(ComparisonTest, IgnoredNestedRepeated) {
3699 proto1diff_.mutable_m()->add_rc(23);
3700 proto1diff_.mutable_m()->add_rc(24);
3701 proto2diff_.mutable_m()->add_rc(25);
3702
3703 proto2diff_.set_w("foo");
3704
3705 ignore_field("m.rc");
3706
3707 EXPECT_EQ(
3708 "added: w: \"foo\"\n"
3709 "ignored: m.rc\n",
3710 RunDiff());
3711 }
3712
TEST_F(ComparisonTest,ExtensionTest)3713 TEST_F(ComparisonTest, ExtensionTest) {
3714 proto1ex_.SetExtension(unittest::optional_int32_extension, 401);
3715 proto2ex_.SetExtension(unittest::optional_int32_extension, 402);
3716
3717 proto1ex_.ClearExtension(unittest::optional_int64_extension);
3718 proto2ex_.SetExtension(unittest::optional_int64_extension, 403);
3719
3720 EXPECT_EQ(
3721 "modified: (protobuf_unittest.optional_int32_extension): 401 -> 402\n"
3722 "added: (protobuf_unittest.optional_int64_extension): 403\n",
3723 RunEx());
3724 }
3725
TEST_F(ComparisonTest,MatchedUnknownFieldTagTest)3726 TEST_F(ComparisonTest, MatchedUnknownFieldTagTest) {
3727 unknown1_->AddVarint(240, 122);
3728 unknown2_->AddVarint(240, 121);
3729 unknown1_->AddFixed32(241, 1);
3730 unknown2_->AddFixed64(241, 2);
3731 unknown1_->AddLengthDelimited(242, "cat");
3732 unknown2_->AddLengthDelimited(242, "dog");
3733
3734 EXPECT_EQ(
3735 "modified: 240[0]: 122 -> 121\n"
3736 "deleted: 241[0]: 0x00000001\n"
3737 "added: 241[0]: 0x0000000000000002\n"
3738 "modified: 242[0]: \"cat\" -> \"dog\"\n",
3739 RunUn());
3740 }
3741
TEST_F(ComparisonTest,UnmatchedUnknownFieldTagTest)3742 TEST_F(ComparisonTest, UnmatchedUnknownFieldTagTest) {
3743 unknown1_->AddFixed32(243, 1);
3744 unknown2_->AddVarint(244, 2);
3745 unknown2_->AddVarint(244, 4);
3746
3747 EXPECT_EQ(
3748 "deleted: 243[0]: 0x00000001\n"
3749 "added: 244[0]: 2\n"
3750 "added: 244[1]: 4\n",
3751 RunUn());
3752 }
3753
TEST_F(ComparisonTest,DifferentSizedUnknownFieldTest)3754 TEST_F(ComparisonTest, DifferentSizedUnknownFieldTest) {
3755 unknown1_->AddVarint(240, 1);
3756 unknown1_->AddVarint(240, 3);
3757 unknown1_->AddVarint(240, 4);
3758 unknown2_->AddVarint(240, 2);
3759 unknown2_->AddVarint(240, 3);
3760 unknown2_->AddVarint(240, 2);
3761 unknown2_->AddVarint(240, 5);
3762
3763 EXPECT_EQ(
3764 "modified: 240[0]: 1 -> 2\n"
3765 "modified: 240[2]: 4 -> 2\n"
3766 "added: 240[3]: 5\n",
3767 RunUn());
3768 }
3769
TEST_F(ComparisonTest,UnknownFieldsAll)3770 TEST_F(ComparisonTest, UnknownFieldsAll) {
3771 unknown1_->AddVarint(243, 122);
3772 unknown1_->AddFixed64(244, 0x0172356);
3773 unknown1_->AddFixed64(244, 0x098);
3774 unknown1_->AddGroup(245)->AddFixed32(248, 1);
3775 unknown1_->mutable_field(3)->mutable_group()->AddFixed32(248, 2);
3776 unknown1_->AddGroup(249)->AddFixed64(250, 1);
3777
3778 unknown2_->AddVarint(243, 121);
3779 unknown2_->AddLengthDelimited(73882, "test 123");
3780 unknown2_->AddGroup(245)->AddFixed32(248, 3);
3781 unknown2_->AddGroup(247);
3782
3783 EXPECT_EQ(
3784 "modified: 243[0]: 122 -> 121\n"
3785 "deleted: 244[0]: 0x0000000000172356\n"
3786 "deleted: 244[1]: 0x0000000000000098\n"
3787 "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
3788 "deleted: 245[0].248[1]: 0x00000002\n"
3789 "added: 247[0]: { ... }\n"
3790 "deleted: 249[0]: { ... }\n"
3791 "added: 73882[0]: \"test 123\"\n",
3792 RunUn());
3793 }
3794
TEST_F(ComparisonTest,EquivalentIgnoresUnknown)3795 TEST_F(ComparisonTest, EquivalentIgnoresUnknown) {
3796 unittest::ForeignMessage message1, message2;
3797
3798 message1.set_c(5);
3799 message1.mutable_unknown_fields()->AddVarint(123, 456);
3800 message2.set_c(5);
3801 message2.mutable_unknown_fields()->AddVarint(321, 654);
3802
3803 EXPECT_FALSE(util::MessageDifferencer::Equals(message1, message2));
3804 EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2));
3805 }
3806
TEST_F(ComparisonTest,MapTest)3807 TEST_F(ComparisonTest, MapTest) {
3808 Map<std::string, std::string>& map1 =
3809 *map_proto1_.mutable_map_string_string();
3810 map1["key1"] = "1";
3811 map1["key2"] = "2";
3812 map1["key3"] = "3";
3813 Map<std::string, std::string>& map2 =
3814 *map_proto2_.mutable_map_string_string();
3815 map2["key3"] = "0";
3816 map2["key2"] = "2";
3817 map2["key1"] = "1";
3818
3819 EXPECT_EQ("modified: map_string_string[key3]: \"3\" -> \"0\"\n",
3820 Run(map_proto1_, map_proto2_));
3821 }
3822
TEST_F(ComparisonTest,MapIgnoreKeyTest)3823 TEST_F(ComparisonTest, MapIgnoreKeyTest) {
3824 Map<std::string, std::string>& map1 =
3825 *map_proto1_.mutable_map_string_string();
3826 map1["key1"] = "1";
3827 map1["key2"] = "2";
3828 map1["key3"] = "3";
3829 Map<std::string, std::string>& map2 =
3830 *map_proto2_.mutable_map_string_string();
3831 map2["key4"] = "2";
3832 map2["key5"] = "3";
3833 map2["key6"] = "1";
3834
3835 util::MessageDifferencer differencer;
3836 differencer.IgnoreField(
3837 GetFieldDescriptor(map_proto1_, "map_string_string.key"));
3838 EXPECT_TRUE(differencer.Compare(map_proto1_, map_proto2_));
3839 }
3840
TEST_F(ComparisonTest,MapRoundTripSyncTest)3841 TEST_F(ComparisonTest, MapRoundTripSyncTest) {
3842 TextFormat::Parser parser;
3843 unittest::TestMap map_reflection1;
3844
3845 // By setting via reflection, data exists in repeated field.
3846 ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message { key: 1 }",
3847 &map_reflection1));
3848
3849 // During copy, data is synced from repeated field to map.
3850 unittest::TestMap map_reflection2 = map_reflection1;
3851
3852 // During comparison, data is synced from map to repeated field.
3853 EXPECT_TRUE(
3854 util::MessageDifferencer::Equals(map_reflection1, map_reflection2));
3855 }
3856
TEST_F(ComparisonTest,MapEntryPartialTest)3857 TEST_F(ComparisonTest, MapEntryPartialTest) {
3858 TextFormat::Parser parser;
3859 unittest::TestMap map1;
3860 unittest::TestMap map2;
3861
3862 std::string output;
3863 util::MessageDifferencer differencer;
3864 differencer.set_scope(util::MessageDifferencer::PARTIAL);
3865 differencer.ReportDifferencesToString(&output);
3866
3867 ASSERT_TRUE(parser.ParseFromString(
3868 "map_int32_foreign_message { key: 1 value { c: 1 } }", &map1));
3869 ASSERT_TRUE(parser.ParseFromString(
3870 "map_int32_foreign_message { key: 1 value { c: 2 }}", &map2));
3871 EXPECT_FALSE(differencer.Compare(map1, map2));
3872 EXPECT_EQ("modified: map_int32_foreign_message[1].c: 1 -> 2\n", output);
3873
3874 ASSERT_TRUE(
3875 parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map1));
3876 EXPECT_TRUE(differencer.Compare(map1, map2));
3877 }
3878
TEST_F(ComparisonTest,MapEntryPartialEmptyKeyTest)3879 TEST_F(ComparisonTest, MapEntryPartialEmptyKeyTest) {
3880 TextFormat::Parser parser;
3881 unittest::TestMap map1;
3882 unittest::TestMap map2;
3883 ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message {}", &map1));
3884 ASSERT_TRUE(
3885 parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map2));
3886
3887 util::MessageDifferencer differencer;
3888 differencer.set_scope(util::MessageDifferencer::PARTIAL);
3889 // TODO: Remove the round trip
3890 std::string serialized_value;
3891 map1.SerializeToString(&serialized_value);
3892 map1.ParseFromString(serialized_value);
3893 EXPECT_FALSE(differencer.Compare(map1, map2));
3894 }
3895
TEST_F(ComparisonTest,MapEntryMissingEmptyFieldIsOkTest)3896 TEST_F(ComparisonTest, MapEntryMissingEmptyFieldIsOkTest) {
3897 TextFormat::Parser parser;
3898 protobuf_unittest::TestMap msg1;
3899 protobuf_unittest::TestMap msg2;
3900
3901 ASSERT_TRUE(parser.ParseFromString(
3902 "map_string_foreign_message { key: 'key1' value {}}", &msg1));
3903 ASSERT_TRUE(parser.ParseFromString(
3904 "map_string_foreign_message { key: 'key1' }", &msg2));
3905
3906 util::MessageDifferencer differencer;
3907 differencer.set_scope(util::MessageDifferencer::PARTIAL);
3908
3909 ASSERT_TRUE(differencer.Compare(msg1, msg2));
3910 }
3911
3912 // Considers strings keys as equal if they have equal lengths.
3913 class LengthMapKeyComparator
3914 : public util::MessageDifferencer::MapKeyComparator {
3915 public:
3916 typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,int unpacked_any,const std::vector<SpecificField> & parent_fields) const3917 bool IsMatch(const Message& message1, const Message& message2,
3918 int unpacked_any,
3919 const std::vector<SpecificField>& parent_fields) const override {
3920 const Reflection* reflection1 = message1.GetReflection();
3921 const Reflection* reflection2 = message2.GetReflection();
3922 const FieldDescriptor* key_field = message1.GetDescriptor()->map_key();
3923 return reflection1->GetString(message1, key_field).size() ==
3924 reflection2->GetString(message2, key_field).size();
3925 }
3926 };
3927
TEST_F(ComparisonTest,MapEntryCustomMapKeyComparator)3928 TEST_F(ComparisonTest, MapEntryCustomMapKeyComparator) {
3929 TextFormat::Parser parser;
3930 protobuf_unittest::TestMap msg1;
3931 protobuf_unittest::TestMap msg2;
3932
3933 ASSERT_TRUE(parser.ParseFromString(
3934 "map_string_foreign_message { key: 'key1' value { c: 1 }}", &msg1));
3935 ASSERT_TRUE(parser.ParseFromString(
3936 "map_string_foreign_message { key: 'key2' value { c: 1 }}", &msg2));
3937
3938 util::MessageDifferencer differencer;
3939 LengthMapKeyComparator key_comparator;
3940 differencer.TreatAsMapUsingKeyComparator(
3941 GetFieldDescriptor(msg1, "map_string_foreign_message"), &key_comparator);
3942 std::string output;
3943 differencer.ReportDifferencesToString(&output);
3944 // Though the above two messages have different keys for their map entries,
3945 // they are considered the same by key_comparator because their lengths are
3946 // equal. However, in value comparison, all fields of the message are taken
3947 // into consideration, so they are reported as different.
3948 EXPECT_FALSE(differencer.Compare(msg1, msg2));
3949 EXPECT_EQ(
3950 "modified: map_string_foreign_message[key1].key: \"key1\" -> \"key2\"\n",
3951 output);
3952 differencer.IgnoreField(
3953 GetFieldDescriptor(msg1, "map_string_foreign_message.key"));
3954 output.clear();
3955 EXPECT_TRUE(differencer.Compare(msg1, msg2));
3956 EXPECT_EQ("ignored: map_string_foreign_message[key1].key\n", output);
3957 }
3958
3959 class MatchingTest : public testing::Test {
3960 public:
3961 typedef util::MessageDifferencer MessageDifferencer;
3962
3963 protected:
MatchingTest()3964 MatchingTest() {}
3965
~MatchingTest()3966 ~MatchingTest() override {}
3967
RunWithResult(MessageDifferencer * differencer,const Message & msg1,const Message & msg2,bool result)3968 std::string RunWithResult(MessageDifferencer* differencer,
3969 const Message& msg1, const Message& msg2,
3970 bool result) {
3971 std::string output;
3972 {
3973 // Before we return the "output" string, we must make sure the
3974 // StreamReporter is destructored because its destructor will
3975 // flush the stream.
3976 io::StringOutputStream output_stream(&output);
3977 MessageDifferencer::StreamReporter reporter(&output_stream);
3978 reporter.set_report_modified_aggregates(true);
3979 differencer->set_report_matches(true);
3980 differencer->ReportDifferencesTo(&reporter);
3981 if (result) {
3982 EXPECT_TRUE(differencer->Compare(msg1, msg2));
3983 } else {
3984 EXPECT_FALSE(differencer->Compare(msg1, msg2));
3985 }
3986 }
3987 return output;
3988 }
3989 };
3990
TEST_F(MatchingTest,StreamReporterMatching)3991 TEST_F(MatchingTest, StreamReporterMatching) {
3992 protobuf_unittest::TestField msg1, msg2;
3993 msg1.set_c(72);
3994 msg2.set_c(72);
3995 msg1.add_rc(13);
3996 msg2.add_rc(13);
3997 msg1.add_rc(17);
3998 msg2.add_rc(17);
3999 std::string output;
4000 MessageDifferencer differencer;
4001 differencer.set_report_matches(true);
4002 differencer.ReportDifferencesToString(&output);
4003 EXPECT_TRUE(differencer.Compare(msg1, msg2));
4004 EXPECT_EQ(
4005 "matched: c : 72\n"
4006 "matched: rc[0] : 13\n"
4007 "matched: rc[1] : 17\n",
4008 output);
4009 }
4010
TEST_F(MatchingTest,DontReportMatchedWhenIgnoring)4011 TEST_F(MatchingTest, DontReportMatchedWhenIgnoring) {
4012 protobuf_unittest::TestField msg1, msg2;
4013 msg1.set_c(72);
4014 msg2.set_c(72);
4015 msg1.add_rc(13);
4016 msg2.add_rc(13);
4017 msg1.add_rc(17);
4018 msg2.add_rc(17);
4019 std::string output;
4020 MessageDifferencer differencer;
4021 differencer.set_report_matches(true);
4022 differencer.ReportDifferencesToString(&output);
4023
4024 differencer.IgnoreField(msg1.GetDescriptor()->FindFieldByName("c"));
4025
4026 EXPECT_TRUE(differencer.Compare(msg1, msg2));
4027 EXPECT_EQ(
4028 "ignored: c\n"
4029 "matched: rc[0] : 13\n"
4030 "matched: rc[1] : 17\n",
4031 output);
4032 }
4033
TEST_F(MatchingTest,ReportMatchedForMovedFields)4034 TEST_F(MatchingTest, ReportMatchedForMovedFields) {
4035 protobuf_unittest::TestDiffMessage msg1, msg2;
4036 protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
4037 item->set_a(53);
4038 item->set_b("hello");
4039 item = msg2.add_item();
4040 item->set_a(27);
4041 item = msg2.add_item();
4042 item->set_a(53);
4043 item->set_b("hello");
4044 item = msg1.add_item();
4045 item->set_a(27);
4046 MessageDifferencer differencer;
4047 const FieldDescriptor* desc;
4048 desc = msg1.GetDescriptor()->FindFieldByName("item");
4049 differencer.TreatAsSet(desc);
4050
4051 EXPECT_EQ(
4052 "matched: item[0].a -> item[1].a : 53\n"
4053 "matched: item[0].b -> item[1].b : \"hello\"\n"
4054 "moved: item[0] -> item[1] : { a: 53 b: \"hello\" }\n"
4055 "matched: item[1].a -> item[0].a : 27\n"
4056 "moved: item[1] -> item[0] : { a: 27 }\n",
4057 RunWithResult(&differencer, msg1, msg2, true));
4058 }
4059
4060
TEST_F(MatchingTest,MatchesAppearInPostTraversalOrderForMovedFields)4061 TEST_F(MatchingTest, MatchesAppearInPostTraversalOrderForMovedFields) {
4062 protobuf_unittest::TestDiffMessage msg1, msg2;
4063 protobuf_unittest::TestDiffMessage::Item* item;
4064 protobuf_unittest::TestField* field;
4065
4066 const FieldDescriptor* desc;
4067 const FieldDescriptor* nested_desc;
4068 const FieldDescriptor* double_nested_desc;
4069 desc = msg1.GetDescriptor()->FindFieldByName("item");
4070 nested_desc = desc->message_type()->FindFieldByName("rm");
4071 double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
4072 MessageDifferencer differencer;
4073 differencer.TreatAsSet(desc);
4074 differencer.TreatAsSet(nested_desc);
4075 differencer.TreatAsSet(double_nested_desc);
4076
4077 item = msg1.add_item();
4078 field = item->add_rm();
4079 field->set_c(1);
4080 field->add_rc(2);
4081 field->add_rc(3);
4082 field = item->add_rm();
4083 field->set_c(4);
4084 field->add_rc(5);
4085 field->add_rc(6);
4086 field->add_rc(7);
4087 item = msg2.add_item();
4088 field = item->add_rm();
4089 field->set_c(4);
4090 field->add_rc(7);
4091 field->add_rc(6);
4092 field->add_rc(5);
4093 field = item->add_rm();
4094 field->set_c(1);
4095 field->add_rc(3);
4096 field->add_rc(2);
4097 item = msg1.add_item();
4098 field = item->add_rm();
4099 field->set_c(8);
4100 field->add_rc(10);
4101 field->add_rc(11);
4102 field->add_rc(9);
4103 item = msg2.add_item();
4104 field = item->add_rm();
4105 field->set_c(8);
4106 field->add_rc(9);
4107 field->add_rc(10);
4108 field->add_rc(11);
4109
4110 EXPECT_EQ(
4111 "matched: item[0].rm[0].c -> item[0].rm[1].c : 1\n"
4112 "moved: item[0].rm[0].rc[0] -> item[0].rm[1].rc[1] : 2\n"
4113 "moved: item[0].rm[0].rc[1] -> item[0].rm[1].rc[0] : 3\n"
4114 "moved: item[0].rm[0] -> item[0].rm[1] : { c: 1 rc: 2 rc: 3 }\n"
4115 "matched: item[0].rm[1].c -> item[0].rm[0].c : 4\n"
4116 "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 5\n"
4117 "matched: item[0].rm[1].rc[1] -> item[0].rm[0].rc[1] : 6\n"
4118 "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 7\n"
4119 "moved: item[0].rm[1] -> item[0].rm[0] : { c: 4 rc: 5 rc: 6 rc: 7 }\n"
4120 "matched: item[0] : { rm { c: 1 rc: 2 rc: 3 }"
4121 " rm { c: 4 rc: 5 rc: 6 rc: 7 } }\n"
4122 "matched: item[1].rm[0].c : 8\n"
4123 "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 10\n"
4124 "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[2] : 11\n"
4125 "moved: item[1].rm[0].rc[2] -> item[1].rm[0].rc[0] : 9\n"
4126 "matched: item[1].rm[0] : { c: 8 rc: 10 rc: 11 rc: 9 }\n"
4127 "matched: item[1] : { rm { c: 8 rc: 10 rc: 11 rc: 9 } }\n",
4128 RunWithResult(&differencer, msg1, msg2, true));
4129 }
4130
TEST_F(MatchingTest,MatchAndModifiedInterleaveProperly)4131 TEST_F(MatchingTest, MatchAndModifiedInterleaveProperly) {
4132 protobuf_unittest::TestDiffMessage msg1, msg2;
4133 protobuf_unittest::TestDiffMessage::Item* item;
4134 protobuf_unittest::TestField* field;
4135
4136 const FieldDescriptor* desc;
4137 const FieldDescriptor* nested_key;
4138 const FieldDescriptor* nested_desc;
4139 const FieldDescriptor* double_nested_key;
4140 const FieldDescriptor* double_nested_desc;
4141 desc = msg1.GetDescriptor()->FindFieldByName("item");
4142 nested_key = desc->message_type()->FindFieldByName("a");
4143 nested_desc = desc->message_type()->FindFieldByName("rm");
4144 double_nested_key = nested_desc->message_type()->FindFieldByName("c");
4145 double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
4146
4147 MessageDifferencer differencer;
4148 differencer.TreatAsMap(desc, nested_key);
4149 differencer.TreatAsMap(nested_desc, double_nested_key);
4150 differencer.TreatAsSet(double_nested_desc);
4151
4152 item = msg1.add_item();
4153 item->set_a(1);
4154 field = item->add_rm();
4155 field->set_c(2);
4156 field->add_rc(3);
4157 field->add_rc(4);
4158 field = item->add_rm();
4159 field->set_c(5);
4160 field->add_rc(6);
4161 field->add_rc(7);
4162 field->add_rc(8);
4163 item = msg1.add_item();
4164 item->set_a(9);
4165 field = item->add_rm();
4166 field->set_c(10);
4167 field->add_rc(11);
4168 field->add_rc(12);
4169 field = item->add_rm();
4170 field->set_c(13);
4171
4172 item = msg2.add_item();
4173 item->set_a(1);
4174 field = item->add_rm();
4175 field->set_c(5);
4176 field->add_rc(8);
4177 field->add_rc(8);
4178 field->add_rc(6);
4179 field = item->add_rm();
4180 field->set_c(3);
4181 field->add_rc(2);
4182 field->add_rc(4);
4183 item = msg2.add_item();
4184 item->set_a(9);
4185 field = item->add_rm();
4186 field->set_c(10);
4187 field->add_rc(12);
4188 field->add_rc(11);
4189 field = item->add_rm();
4190 field->set_c(13);
4191
4192 EXPECT_EQ(
4193 "matched: item[0].a : 1\n"
4194 "matched: item[0].rm[1].c -> item[0].rm[0].c : 5\n"
4195 "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 6\n"
4196 "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 8\n"
4197 "added: item[0].rm[0].rc[1]: 8\n"
4198 "deleted: item[0].rm[1].rc[1]: 7\n"
4199 "modified: item[0].rm[1] -> item[0].rm[0]: { c: 5 rc: 6 rc: 7 rc: 8 } ->"
4200 " { c: 5 rc: 8 rc: 8 rc: 6 }\n"
4201 "added: item[0].rm[1]: { c: 3 rc: 2 rc: 4 }\n"
4202 "deleted: item[0].rm[0]: { c: 2 rc: 3 rc: 4 }\n"
4203 "modified: item[0]: { a: 1 rm { c: 2 rc: 3 rc: 4 }"
4204 " rm { c: 5 rc: 6 rc: 7 rc: 8 } } ->"
4205 " { a: 1 rm { c: 5 rc: 8 rc: 8 rc: 6 }"
4206 " rm { c: 3 rc: 2 rc: 4 } }\n"
4207 "matched: item[1].a : 9\n"
4208 "matched: item[1].rm[0].c : 10\n"
4209 "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 11\n"
4210 "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[0] : 12\n"
4211 "matched: item[1].rm[0] : { c: 10 rc: 11 rc: 12 }\n"
4212 "matched: item[1].rm[1].c : 13\n"
4213 "matched: item[1].rm[1] : { c: 13 }\n"
4214 "matched: item[1] : { a: 9 rm { c: 10 rc: 11 rc: 12 } rm { c: 13 } }\n",
4215 RunWithResult(&differencer, msg1, msg2, false));
4216 }
4217
TEST_F(MatchingTest,MatchingWorksWithExtensions)4218 TEST_F(MatchingTest, MatchingWorksWithExtensions) {
4219 protobuf_unittest::TestAllExtensions msg1, msg2;
4220 protobuf_unittest::TestAllTypes::NestedMessage* nested;
4221 using protobuf_unittest::repeated_nested_message_extension;
4222
4223 const FileDescriptor* descriptor;
4224 const FieldDescriptor* desc;
4225 const FieldDescriptor* nested_key;
4226 descriptor = msg1.GetDescriptor()->file();
4227 desc = descriptor->FindExtensionByName("repeated_nested_message_extension");
4228 ASSERT_FALSE(desc == nullptr);
4229 nested_key = desc->message_type()->FindFieldByName("bb");
4230
4231 MessageDifferencer differencer;
4232 differencer.TreatAsMap(desc, nested_key);
4233
4234 nested = msg1.AddExtension(repeated_nested_message_extension);
4235 nested->set_bb(7);
4236 nested = msg1.AddExtension(repeated_nested_message_extension);
4237 nested->set_bb(13);
4238 nested = msg1.AddExtension(repeated_nested_message_extension);
4239 nested->set_bb(11);
4240 nested = msg2.AddExtension(repeated_nested_message_extension);
4241 nested->set_bb(11);
4242 nested = msg2.AddExtension(repeated_nested_message_extension);
4243 nested->set_bb(13);
4244 nested = msg2.AddExtension(repeated_nested_message_extension);
4245 nested->set_bb(7);
4246
4247 EXPECT_EQ(
4248 "matched: (protobuf_unittest.repeated_nested_message_extension)[0].bb ->"
4249 " (protobuf_unittest.repeated_nested_message_extension)[2].bb : 7\n"
4250 "moved: (protobuf_unittest.repeated_nested_message_extension)[0] ->"
4251 " (protobuf_unittest.repeated_nested_message_extension)[2] :"
4252 " { bb: 7 }\n"
4253 "matched: (protobuf_unittest.repeated_nested_message_extension)[1].bb :"
4254 " 13\n"
4255 "matched: (protobuf_unittest.repeated_nested_message_extension)[1] :"
4256 " { bb: 13 }\n"
4257 "matched: (protobuf_unittest.repeated_nested_message_extension)[2].bb ->"
4258 " (protobuf_unittest.repeated_nested_message_extension)[0].bb :"
4259 " 11\n"
4260 "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
4261 " (protobuf_unittest.repeated_nested_message_extension)[0] :"
4262 " { bb: 11 }\n",
4263 RunWithResult(&differencer, msg1, msg2, true));
4264 }
4265
TEST(AnyTest,Simple)4266 TEST(AnyTest, Simple) {
4267 protobuf_unittest::TestField value1, value2;
4268 value1.set_a(20);
4269 value2.set_a(21);
4270
4271 protobuf_unittest::TestAny m1, m2;
4272 m1.mutable_any_value()->PackFrom(value1);
4273 m2.mutable_any_value()->PackFrom(value2);
4274 util::MessageDifferencer message_differencer;
4275 std::string difference_string;
4276 message_differencer.ReportDifferencesToString(&difference_string);
4277 EXPECT_FALSE(message_differencer.Compare(m1, m2));
4278 EXPECT_EQ("modified: any_value.a: 20 -> 21\n", difference_string);
4279 }
4280
TEST(AnyTest,DifferentTypes)4281 TEST(AnyTest, DifferentTypes) {
4282 protobuf_unittest::TestField value1;
4283 value1.set_a(20);
4284 protobuf_unittest::ForeignMessage value2;
4285 value2.set_c(30);
4286
4287 protobuf_unittest::TestAny m1, m2;
4288 m1.mutable_any_value()->PackFrom(value1);
4289 m2.mutable_any_value()->PackFrom(value2);
4290 util::MessageDifferencer message_differencer;
4291 std::string difference_string;
4292 message_differencer.ReportDifferencesToString(&difference_string);
4293 EXPECT_FALSE(message_differencer.Compare(m1, m2));
4294 // Any should be treated as a regular proto when the payload types differ.
4295 EXPECT_THAT(
4296 difference_string,
4297 testing::ContainsRegex(
4298 R"(type_url: ".+/protobuf_unittest.TestField\" -> ".+/protobuf_unittest.ForeignMessage")"));
4299 }
4300
TEST(Anytest,TreatAsSet)4301 TEST(Anytest, TreatAsSet) {
4302 protobuf_unittest::TestField value1, value2;
4303 value1.set_a(20);
4304 value1.set_b(30);
4305 value2.set_a(20);
4306 value2.set_b(31);
4307
4308 protobuf_unittest::TestAny m1, m2;
4309 m1.add_repeated_any_value()->PackFrom(value1);
4310 m1.add_repeated_any_value()->PackFrom(value2);
4311 m2.add_repeated_any_value()->PackFrom(value2);
4312 m2.add_repeated_any_value()->PackFrom(value1);
4313
4314 util::MessageDifferencer message_differencer;
4315 message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
4316 EXPECT_TRUE(message_differencer.Compare(m1, m2));
4317 }
4318
TEST(Anytest,TreatAsSet_DifferentType)4319 TEST(Anytest, TreatAsSet_DifferentType) {
4320 protobuf_unittest::TestField value1;
4321 value1.set_a(20);
4322 value1.set_b(30);
4323 protobuf_unittest::TestDiffMessage value2;
4324 value2.add_rv(40);
4325
4326 protobuf_unittest::TestAny m1, m2;
4327 m1.add_repeated_any_value()->PackFrom(value1);
4328 m1.add_repeated_any_value()->PackFrom(value2);
4329 m2.add_repeated_any_value()->PackFrom(value2);
4330 m2.add_repeated_any_value()->PackFrom(value1);
4331
4332 util::MessageDifferencer message_differencer;
4333 message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
4334 EXPECT_TRUE(message_differencer.Compare(m1, m2));
4335 }
4336
4337
4338 } // namespace
4339 } // namespace protobuf
4340 } // namespace google
4341