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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:26