• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/strutil.h>
43 
44 #include <google/protobuf/any_test.pb.h>
45 #include <google/protobuf/map_test_util.h>
46 #include <google/protobuf/map_unittest.pb.h>
47 #include <google/protobuf/test_util.h>
48 #include <google/protobuf/unittest.pb.h>
49 #include <google/protobuf/io/coded_stream.h>
50 #include <google/protobuf/io/zero_copy_stream_impl.h>
51 #include <google/protobuf/text_format.h>
52 #include <google/protobuf/wire_format.h>
53 #include <google/protobuf/util/message_differencer_unittest.pb.h>
54 #include <google/protobuf/util/field_comparator.h>
55 #include <google/protobuf/util/message_differencer.h>
56 
57 #include <google/protobuf/stubs/logging.h>
58 #include <google/protobuf/stubs/common.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 
GetFieldDescriptor(const Message & message,const std::string & field_name)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]);
76     descriptor = field->message_type();
77   }
78   return field;
79 }
80 
ExpectEqualsWithDifferencer(util::MessageDifferencer * differencer,const Message & msg1,const Message & msg2)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 
TEST(MessageDifferencerTest,BasicEqualityTest)90 TEST(MessageDifferencerTest, BasicEqualityTest) {
91   // Create the testing protos
92   unittest::TestAllTypes msg1;
93   unittest::TestAllTypes msg2;
94 
95   TestUtil::SetAllFields(&msg1);
96   TestUtil::SetAllFields(&msg2);
97 
98   // Compare
99   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
100 }
101 
TEST(MessageDifferencerTest,BasicInequalityTest)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
113   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
114 }
115 
TEST(MessageDifferencerTest,RepeatedFieldInequalityTest)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
127   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
128 }
129 
TEST(MessageDifferencerTest,RepeatedFieldSetOptimizationTest)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 
TEST(MessageDifferencerTest,MapFieldEqualityTest)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
162   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
163 
164   // Get map entries by index will sync map to repeated field
165   MapTestUtil::GetMapEntries(msg1, 0);
166   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
167 
168   // Compare values not match
169   (*msg1.mutable_map_int32_int32())[1] = 2;
170   (*msg2.mutable_map_int32_int32())[1] = 3;
171   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
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"] = "";
178   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
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);
185   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
186 }
187 
TEST(MessageDifferencerTest,BasicPartialEqualityTest)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 
TEST(MessageDifferencerTest,PartialEqualityTestExtraField)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 
TEST(MessageDifferencerTest,PartialEqualityTestSkipRequiredField)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 
TEST(MessageDifferencerTest,BasicPartialInequalityTest)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 
TEST(MessageDifferencerTest,PartialInequalityMissingFieldTest)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 
TEST(MessageDifferencerTest,RepeatedFieldPartialInequalityTest)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 
TEST(MessageDifferencerTest,BasicEquivalencyTest)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
290   EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
291 }
292 
TEST(MessageDifferencerTest,EquivalencyNotEqualTest)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
305   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
306   EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
307 }
308 
TEST(MessageDifferencerTest,BasicInequivalencyTest)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
320   EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
321 }
322 
TEST(MessageDifferencerTest,BasicEquivalencyNonSetTest)323 TEST(MessageDifferencerTest, BasicEquivalencyNonSetTest) {
324   // Create the testing protos
325   unittest::TestAllTypes msg1;
326   unittest::TestAllTypes msg2;
327 
328   // Compare
329   EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
330 }
331 
TEST(MessageDifferencerTest,BasicInequivalencyNonSetTest)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
340   EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
341 }
342 
TEST(MessageDifferencerTest,BasicPartialEquivalencyTest)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(
354       util::MessageDifferencer::EQUIVALENT);
355   differencer.set_scope(util::MessageDifferencer::PARTIAL);
356   EXPECT_TRUE(differencer.Compare(msg1, msg2));
357 }
358 
TEST(MessageDifferencerTest,PartialEquivalencyNotEqualTest)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
371   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
372   util::MessageDifferencer differencer;
373   differencer.set_message_field_comparison(
374       util::MessageDifferencer::EQUIVALENT);
375   differencer.set_scope(util::MessageDifferencer::PARTIAL);
376   EXPECT_TRUE(differencer.Compare(msg1, msg2));
377 }
378 
TEST(MessageDifferencerTest,PartialEquivalencyTestExtraField)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(
392       util::MessageDifferencer::EQUIVALENT);
393   differencer.set_scope(util::MessageDifferencer::PARTIAL);
394   EXPECT_TRUE(differencer.Compare(msg1, msg2));
395 }
396 
TEST(MessageDifferencerTest,PartialEquivalencyTestSkipRequiredField)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(
409       util::MessageDifferencer::EQUIVALENT);
410   differencer.set_scope(util::MessageDifferencer::PARTIAL);
411   EXPECT_TRUE(differencer.Compare(msg1, msg2));
412 }
413 
TEST(MessageDifferencerTest,BasicPartialInequivalencyTest)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(
427       util::MessageDifferencer::EQUIVALENT);
428   differencer.set_scope(util::MessageDifferencer::PARTIAL);
429   EXPECT_FALSE(differencer.Compare(msg1, msg2));
430 }
431 
TEST(MessageDifferencerTest,BasicPartialEquivalencyNonSetTest)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(
440       util::MessageDifferencer::EQUIVALENT);
441   differencer.set_scope(util::MessageDifferencer::PARTIAL);
442   EXPECT_TRUE(differencer.Compare(msg1, msg2));
443 }
444 
TEST(MessageDifferencerTest,BasicPartialInequivalencyNonSetTest)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(
455       util::MessageDifferencer::EQUIVALENT);
456   differencer.set_scope(util::MessageDifferencer::PARTIAL);
457   EXPECT_FALSE(differencer.Compare(msg1, msg2));
458 }
459 
TEST(MessageDifferencerTest,ApproximateEqualityTest)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
469   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
470 }
471 
TEST(MessageDifferencerTest,ApproximateModifiedEqualityTest)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;
488   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
489   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
490 }
491 
TEST(MessageDifferencerTest,ApproximateEquivalencyTest)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
501   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
502 }
503 
TEST(MessageDifferencerTest,ApproximateModifiedEquivalencyTest)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;
521   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
522   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
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
529   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
530   EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
531   EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
532   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
533 }
534 
TEST(MessageDifferencerTest,ApproximateInequivalencyTest)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);
545   EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
546 
547   // Make these fields the same again.
548   msg1.set_optional_int32(0);
549   msg2.set_optional_int32(0);
550   EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
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);
557   EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
558 }
559 
TEST(MessageDifferencerTest,WithinFractionOrMarginFloatTest)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 
TEST(MessageDifferencerTest,WithinFractionOrMarginDoubleTest)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 
TEST(MessageDifferencerTest,WithinDefaultFractionOrMarginDoubleTest)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(
698       util::DefaultFieldComparator::APPROXIMATE);
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 
TEST(MessageDifferencerTest,BasicFieldOrderingsTest)719 TEST(MessageDifferencerTest, BasicFieldOrderingsTest) {
720   // Create the testing protos
721   unittest::TestFieldOrderings msg1;
722   unittest::TestFieldOrderings msg2;
723 
724   TestUtil::SetAllFieldsAndExtensions(&msg1);
725   TestUtil::SetAllFieldsAndExtensions(&msg2);
726 
727   // Compare
728   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
729 }
730 
TEST(MessageDifferencerTest,BasicFieldOrderingInequalityTest)731 TEST(MessageDifferencerTest, BasicFieldOrderingInequalityTest) {
732   // Create the testing protos
733   unittest::TestFieldOrderings msg1;
734   unittest::TestFieldOrderings msg2;
735 
736   TestUtil::SetAllFieldsAndExtensions(&msg1);
737   TestUtil::SetAllFieldsAndExtensions(&msg2);
738 
739   msg1.set_my_float(15.00);
740   msg2.set_my_float(16.00);
741 
742   // Compare
743   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
744 }
745 
TEST(MessageDifferencerTest,BasicExtensionTest)746 TEST(MessageDifferencerTest, BasicExtensionTest) {
747   // Create the testing protos
748   unittest::TestAllExtensions msg1;
749   unittest::TestAllExtensions msg2;
750 
751   TestUtil::SetAllExtensions(&msg1);
752   TestUtil::SetAllExtensions(&msg2);
753 
754   // Compare
755   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
756 }
757 
TEST(MessageDifferencerTest,BasicExtensionInequalityTest)758 TEST(MessageDifferencerTest, BasicExtensionInequalityTest) {
759   // Create the testing protos
760   unittest::TestAllExtensions msg1;
761   unittest::TestAllExtensions msg2;
762 
763   TestUtil::SetAllExtensions(&msg1);
764   TestUtil::SetAllExtensions(&msg2);
765 
766   msg1.SetExtension(unittest::optional_int32_extension, 101);
767   msg2.SetExtension(unittest::optional_int32_extension, 102);
768 
769   // Compare
770   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
771 }
772 
TEST(MessageDifferencerTest,OneofTest)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
782   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
783 }
784 
TEST(MessageDifferencerTest,OneofInequalityTest)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
794   EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
795 }
796 
TEST(MessageDifferencerTest,UnknownFieldPartialEqualTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsEqualityAllTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsInequalityAllTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsEmptyListAlwaysSucceeds)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 
TEST(MessageDifferencerTest,SpecifiedFieldsCompareWithSelf)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 
TEST(MessageDifferencerTest,SpecifiedFieldsEqualityAllShuffledTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsSubsetEqualityTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsSubsetIgnoresOtherFieldDifferencesTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsDetectsDifferencesTest)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 
TEST(MessageDifferencerTest,SpecifiedFieldsEquivalenceAllTest)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(
1021       util::MessageDifferencer::EQUIVALENT);
1022   EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1023 }
1024 
TEST(MessageDifferencerTest,SpecifiedFieldsEquivalenceIgnoresOtherFieldDifferencesTest)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(
1058       util::MessageDifferencer::EQUIVALENT);
1059   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1060   EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
1061 }
1062 
TEST(MessageDifferencerTest,RepeatedFieldSmartListTest)1063 TEST(MessageDifferencerTest, RepeatedFieldSmartListTest) {
1064   // Create the testing protos
1065   protobuf_unittest::TestDiffMessage msg1;
1066   protobuf_unittest::TestDiffMessage msg2;
1067 
1068   msg1.add_rv(1);
1069   msg1.add_rv(2);
1070   msg1.add_rv(3);
1071   msg1.add_rv(9);
1072   msg1.add_rv(4);
1073   msg1.add_rv(5);
1074   msg1.add_rv(7);
1075   msg1.add_rv(2);
1076   msg2.add_rv(9);
1077   msg2.add_rv(0);
1078   msg2.add_rv(2);
1079   msg2.add_rv(7);
1080   msg2.add_rv(3);
1081   msg2.add_rv(4);
1082   msg2.add_rv(5);
1083   msg2.add_rv(6);
1084   msg2.add_rv(2);
1085   // Compare
1086   // a: 1,      2,    3, 9, 4, 5, 7,   2
1087   // b:   9, 0, 2, 7, 3,    4, 5,   6, 2
1088   std::string diff_report;
1089   util::MessageDifferencer differencer;
1090   differencer.ReportDifferencesToString(&diff_report);
1091   differencer.set_repeated_field_comparison(
1092       util::MessageDifferencer::AS_SMART_LIST);
1093   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1094   EXPECT_EQ(
1095       "deleted: rv[0]: 1\n"
1096       "added: rv[0]: 9\n"
1097       "added: rv[1]: 0\n"
1098       "moved: rv[1] -> rv[2] : 2\n"
1099       "added: rv[3]: 7\n"
1100       "moved: rv[2] -> rv[4] : 3\n"
1101       "deleted: rv[3]: 9\n"
1102       "moved: rv[4] -> rv[5] : 4\n"
1103       "moved: rv[5] -> rv[6] : 5\n"
1104       "deleted: rv[6]: 7\n"
1105       "added: rv[7]: 6\n"
1106       "moved: rv[7] -> rv[8] : 2\n",
1107       diff_report);
1108 
1109   // Compare two sub messages
1110   // a: 1, 2, 3,    4, 5
1111   // b:    2,    6, 4,
1112   msg1.Clear();
1113   msg2.Clear();
1114   msg1.add_rm()->set_a(1);
1115   msg1.add_rm()->set_a(2);
1116   msg1.add_rm()->set_a(3);
1117   msg1.add_rm()->set_a(4);
1118   msg1.add_rm()->set_a(5);
1119   msg2.add_rm()->set_a(2);
1120   msg2.add_rm()->set_a(6);
1121   msg2.add_rm()->set_a(4);
1122   differencer.ReportDifferencesToString(&diff_report);
1123   differencer.set_repeated_field_comparison(
1124       util::MessageDifferencer::AS_SMART_LIST);
1125   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1126   EXPECT_EQ(
1127       "deleted: rm[0]: { a: 1 }\n"
1128       "moved: rm[1] -> rm[0] : { a: 2 }\n"
1129       "deleted: rm[2]: { a: 3 }\n"
1130       "added: rm[1]: { a: 6 }\n"
1131       "moved: rm[3] -> rm[2] : { a: 4 }\n"
1132       "deleted: rm[4]: { a: 5 }\n",
1133       diff_report);
1134 }
1135 
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest)1136 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest) {
1137   // Create the testing protos
1138   protobuf_unittest::TestDiffMessage msg1;
1139   protobuf_unittest::TestDiffMessage msg2;
1140   protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
1141   protobuf_unittest::TestField elem1_2, elem2_2, elem3_2;
1142 
1143   // Only one field is different for each pair of elememts
1144   elem1_1.set_a(1);
1145   elem1_2.set_a(0);
1146   elem1_1.set_b(1);
1147   elem1_2.set_b(1);
1148   elem1_1.set_c(1);
1149   elem1_2.set_c(1);
1150   elem2_1.set_a(2);
1151   elem2_2.set_a(2);
1152   elem2_1.set_b(2);
1153   elem2_2.set_b(0);
1154   elem2_1.set_c(2);
1155   elem2_2.set_c(2);
1156   elem3_1.set_a(3);
1157   elem3_2.set_a(3);
1158   elem3_1.set_b(3);
1159   elem3_2.set_b(0);
1160   elem3_1.set_c(3);
1161   elem3_2.set_c(3);
1162 
1163   *msg1.add_rm() = elem1_1;
1164   *msg1.add_rm() = elem2_1;
1165   *msg1.add_rm() = elem3_1;
1166   // Change the order of those elements for the second message.
1167   *msg2.add_rm() = elem3_2;
1168   *msg2.add_rm() = elem1_2;
1169   *msg2.add_rm() = elem2_2;
1170 
1171   std::string diff_report;
1172   util::MessageDifferencer differencer;
1173   differencer.ReportDifferencesToString(&diff_report);
1174   differencer.set_repeated_field_comparison(
1175       util::MessageDifferencer::AS_SMART_SET);
1176   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1177   EXPECT_EQ(
1178       "modified: rm[0].a -> rm[1].a: 1 -> 0\n"
1179       "modified: rm[1].b -> rm[2].b: 2 -> 0\n"
1180       "modified: rm[2].b -> rm[0].b: 3 -> 0\n",
1181       diff_report);
1182 }
1183 
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest_IdenticalElements)1184 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_IdenticalElements) {
1185   // Create the testing protos
1186   protobuf_unittest::TestDiffMessage msg1;
1187   protobuf_unittest::TestDiffMessage msg2;
1188   protobuf_unittest::TestField elem;
1189 
1190   elem.set_a(1);
1191   elem.set_b(1);
1192   elem.set_c(1);
1193 
1194   *msg1.add_rm() = elem;
1195   *msg1.add_rm() = elem;
1196   *msg2.add_rm() = elem;
1197   *msg2.add_rm() = elem;
1198 
1199   util::MessageDifferencer differencer;
1200   differencer.set_repeated_field_comparison(
1201       util::MessageDifferencer::AS_SMART_SET);
1202   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1203 }
1204 
TEST(MessageDifferencerTest,RepeatedFieldSmartSetTest_PreviouslyMatch)1205 TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_PreviouslyMatch) {
1206   // Create the testing protos
1207   protobuf_unittest::TestDiffMessage msg1;
1208   protobuf_unittest::TestDiffMessage msg2;
1209   protobuf_unittest::TestField elem1_1, elem1_2;
1210   protobuf_unittest::TestField elem2_1, elem2_2;
1211 
1212   elem1_1.set_a(1);
1213   elem1_1.set_b(1);
1214   elem1_1.set_c(1);
1215   elem1_2.set_a(1);
1216   elem1_2.set_b(1);
1217   elem1_2.set_c(0);
1218 
1219   elem2_1.set_a(1);
1220   elem2_1.set_b(1);
1221   elem2_1.set_c(1);
1222   elem2_2.set_a(1);
1223   elem2_2.set_b(0);
1224   elem2_2.set_c(1);
1225 
1226   *msg1.add_rm() = elem1_1;
1227   *msg1.add_rm() = elem2_1;
1228   *msg2.add_rm() = elem1_2;
1229   *msg2.add_rm() = elem2_2;
1230 
1231   std::string diff_report;
1232   util::MessageDifferencer differencer;
1233   differencer.ReportDifferencesToString(&diff_report);
1234   differencer.set_repeated_field_comparison(
1235       util::MessageDifferencer::AS_SMART_SET);
1236   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1237   EXPECT_EQ(
1238       "modified: rm[0].c: 1 -> 0\n"
1239       "modified: rm[1].b: 1 -> 0\n",
1240       diff_report);
1241 }
1242 
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_MultipleMatches)1243 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatches) {
1244   // Create the testing protos
1245   protobuf_unittest::TestDiffMessage msg1;
1246   protobuf_unittest::TestDiffMessage msg2;
1247   protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
1248   protobuf_unittest::TestField elem2_2, elem3_2;
1249 
1250   // Only one field is different for each pair of elememts
1251   elem1_1.set_a(1);
1252   elem1_1.set_b(1);
1253   elem1_1.set_c(1);
1254   elem2_1.set_a(2);
1255   elem2_2.set_a(2);
1256   elem2_1.set_b(2);
1257   elem2_2.set_b(0);
1258   elem2_1.set_c(2);
1259   elem2_2.set_c(2);
1260   elem3_1.set_a(3);
1261   elem3_2.set_a(3);
1262   elem3_1.set_b(3);
1263   elem3_2.set_b(0);
1264   elem3_1.set_c(3);
1265   elem3_2.set_c(3);
1266 
1267   // In this testcase, elem1_1 will match with elem2_2 first and then get
1268   // reverted because elem2_1 matches with elem2_2 later.
1269   *msg1.add_rm() = elem1_1;
1270   *msg1.add_rm() = elem2_1;
1271   *msg1.add_rm() = elem3_1;
1272   *msg2.add_rm() = elem2_2;
1273   *msg2.add_rm() = elem3_2;
1274 
1275   std::string diff_report;
1276   util::MessageDifferencer differencer;
1277   differencer.ReportDifferencesToString(&diff_report);
1278   differencer.set_repeated_field_comparison(
1279       util::MessageDifferencer::AS_SMART_SET);
1280   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1281   EXPECT_EQ(
1282       "modified: rm[1].b -> rm[0].b: 2 -> 0\n"
1283       "modified: rm[2].b -> rm[1].b: 3 -> 0\n"
1284       "deleted: rm[0]: { c: 1 a: 1 b: 1 }\n",
1285       diff_report);
1286 }
1287 
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_MultipleMatchesNoReporter)1288 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatchesNoReporter) {
1289   protobuf_unittest::TestDiffMessage msg1;
1290   protobuf_unittest::TestDiffMessage msg2;
1291   protobuf_unittest::TestField elem1, elem2, elem3, elem4;
1292   elem1.set_a(1);
1293   elem2.set_a(2);
1294   elem3.set_a(3);
1295   elem4.set_a(4);
1296 
1297   *msg1.add_rm() = elem1;
1298   *msg1.add_rm() = elem2;
1299   *msg1.add_rm() = elem3;
1300   *msg2.add_rm() = elem2;
1301   *msg2.add_rm() = elem3;
1302   *msg2.add_rm() = elem4;
1303 
1304   util::MessageDifferencer differencer;
1305   differencer.set_repeated_field_comparison(
1306       util::MessageDifferencer::AS_SMART_SET);
1307   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1308 }
1309 
TEST(MessageDifferencerTest,RepeatedFieldSmartSet_NonMessageTypeTest)1310 TEST(MessageDifferencerTest, RepeatedFieldSmartSet_NonMessageTypeTest) {
1311   // Create the testing protos
1312   protobuf_unittest::TestDiffMessage msg1;
1313   protobuf_unittest::TestDiffMessage msg2;
1314 
1315   // Create 3 elements, but in different order.
1316   msg1.add_rw("b");
1317   msg2.add_rw("a");
1318   msg1.add_rw("x");
1319   msg2.add_rw("x");
1320   msg1.add_rw("a");
1321   msg2.add_rw("b");
1322 
1323   std::string diff_report;
1324   util::MessageDifferencer differencer;
1325   differencer.ReportDifferencesToString(&diff_report);
1326   differencer.set_repeated_field_comparison(
1327       util::MessageDifferencer::AS_SMART_SET);
1328   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1329   EXPECT_EQ(
1330       "moved: rw[0] -> rw[2] : \"b\"\n"
1331       "moved: rw[2] -> rw[0] : \"a\"\n",
1332       diff_report);
1333 }
1334 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_SetOfSet)1335 TEST(MessageDifferencerTest, RepeatedFieldSetTest_SetOfSet) {
1336   // Create the testing protos
1337   protobuf_unittest::TestDiffMessage msg1;
1338   protobuf_unittest::TestDiffMessage msg2;
1339 
1340   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1341   item->add_ra(1);
1342   item->add_ra(2);
1343   item->add_ra(3);
1344   item = msg1.add_item();
1345   item->add_ra(5);
1346   item->add_ra(6);
1347   item = msg1.add_item();
1348   item->add_ra(1);
1349   item->add_ra(3);
1350   item = msg1.add_item();
1351   item->add_ra(6);
1352   item->add_ra(7);
1353   item->add_ra(8);
1354 
1355   item = msg2.add_item();
1356   item->add_ra(6);
1357   item->add_ra(5);
1358   item = msg2.add_item();
1359   item->add_ra(6);
1360   item->add_ra(8);
1361   item->add_ra(7);
1362   item = msg2.add_item();
1363   item->add_ra(1);
1364   item->add_ra(3);
1365   item = msg2.add_item();
1366   item->add_ra(3);
1367   item->add_ra(2);
1368   item->add_ra(1);
1369 
1370   // Compare
1371   util::MessageDifferencer differencer;
1372   differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1373   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1374 }
1375 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Combination)1376 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Combination) {
1377   // Create the testing protos
1378   protobuf_unittest::TestDiffMessage msg1;
1379   protobuf_unittest::TestDiffMessage msg2;
1380   // Treat "item" as Map, with key = "a"
1381   // Treat "item.ra" also as Set
1382   // Treat "rv" as Set
1383   // Treat "rw" as List
1384   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1385   item->set_a(3);
1386   item->add_ra(1);
1387   item->add_ra(2);
1388   item->add_ra(3);
1389   item = msg1.add_item();
1390   item->set_a(4);
1391   item->add_ra(5);
1392   item->add_ra(6);
1393   item = msg1.add_item();
1394   item->set_a(1);
1395   item->add_ra(1);
1396   item->add_ra(3);
1397   item = msg1.add_item();
1398   item->set_a(2);
1399   item->add_ra(6);
1400   item->add_ra(7);
1401   item->add_ra(8);
1402 
1403   item = msg2.add_item();
1404   item->set_a(4);
1405   item->add_ra(6);
1406   item->add_ra(5);
1407   item = msg2.add_item();
1408   item->set_a(2);
1409   item->add_ra(6);
1410   item->add_ra(8);
1411   item->add_ra(7);
1412   item = msg2.add_item();
1413   item->set_a(1);
1414   item->add_ra(1);
1415   item->add_ra(3);
1416   item = msg2.add_item();
1417   item->set_a(3);
1418   item->add_ra(3);
1419   item->add_ra(2);
1420   item->add_ra(1);
1421 
1422   msg1.add_rv(3);
1423   msg1.add_rv(4);
1424   msg1.add_rv(7);
1425   msg1.add_rv(0);
1426   msg2.add_rv(4);
1427   msg2.add_rv(3);
1428   msg2.add_rv(0);
1429   msg2.add_rv(7);
1430 
1431   msg1.add_rw("nothing");
1432   msg2.add_rw("nothing");
1433   msg1.add_rw("should");
1434   msg2.add_rw("should");
1435   msg1.add_rw("change");
1436   msg2.add_rw("change");
1437 
1438   // Compare
1439   util::MessageDifferencer differencer1;
1440   differencer1.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
1441                           item->GetDescriptor()->FindFieldByName("a"));
1442   differencer1.TreatAsSet(msg1.GetDescriptor()->FindFieldByName("rv"));
1443   differencer1.TreatAsSet(item->GetDescriptor()->FindFieldByName("ra"));
1444   EXPECT_TRUE(differencer1.Compare(msg1, msg2));
1445 
1446   util::MessageDifferencer differencer2;
1447   differencer2.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
1448                           item->GetDescriptor()->FindFieldByName("a"));
1449   differencer2.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1450   differencer2.TreatAsList(msg1.GetDescriptor()->FindFieldByName("rw"));
1451   EXPECT_TRUE(differencer2.Compare(msg1, msg2));
1452 }
1453 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_Partial)1454 TEST(MessageDifferencerTest, RepeatedFieldMapTest_Partial) {
1455   protobuf_unittest::TestDiffMessage msg1;
1456   // message msg1 {
1457   //   item { a: 1; b: "11" }
1458   // }
1459   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1460   item->set_a(1);
1461   item->set_b("11");
1462 
1463   protobuf_unittest::TestDiffMessage msg2;
1464   // message msg2 {
1465   //   item { a: 2; b: "22" }
1466   //   item { a: 1; b: "11" }
1467   // }
1468   item = msg2.add_item();
1469   item->set_a(2);
1470   item->set_b("22");
1471   item = msg2.add_item();
1472   item->set_a(1);
1473   item->set_b("11");
1474 
1475   // Compare
1476   util::MessageDifferencer differencer;
1477   differencer.TreatAsMap(GetFieldDescriptor(msg1, "item"),
1478                          GetFieldDescriptor(msg1, "item.a"));
1479   differencer.set_scope(util::MessageDifferencer::PARTIAL);
1480   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1481 }
1482 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Duplicates)1483 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Duplicates) {
1484   protobuf_unittest::TestDiffMessage a, b, c;
1485   // message a: {
1486   //   rv: 0
1487   //   rv: 1
1488   //   rv: 0
1489   // }
1490   a.add_rv(0);
1491   a.add_rv(1);
1492   a.add_rv(0);
1493   // message b: {
1494   //   rv: 0
1495   //   rv: 0
1496   //   rv: 1
1497   // }
1498   b.add_rv(0);
1499   b.add_rv(0);
1500   b.add_rv(1);
1501   // message c: {
1502   //   rv: 0
1503   //   rv: 1
1504   // }
1505   c.add_rv(0);
1506   c.add_rv(1);
1507   util::MessageDifferencer differencer;
1508   differencer.TreatAsSet(GetFieldDescriptor(a, "rv"));
1509   EXPECT_TRUE(differencer.Compare(b, a));
1510   EXPECT_FALSE(differencer.Compare(c, a));
1511 
1512   util::MessageDifferencer differencer1;
1513   differencer1.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1514   EXPECT_TRUE(differencer1.Compare(b, a));
1515   EXPECT_FALSE(differencer1.Compare(c, a));
1516 }
1517 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_PartialSimple)1518 TEST(MessageDifferencerTest, RepeatedFieldSetTest_PartialSimple) {
1519   protobuf_unittest::TestDiffMessage a, b, c;
1520   // message a: {
1521   //   rm { c: 1 }
1522   //   rm { c: 0 }
1523   // }
1524   a.add_rm()->set_c(1);
1525   a.add_rm()->set_c(0);
1526   // message b: {
1527   //   rm { c: 1 }
1528   //   rm {}
1529   // }
1530   b.add_rm()->set_c(1);
1531   b.add_rm();
1532   // message c: {
1533   //   rm {}
1534   //   rm { c: 1 }
1535   // }
1536   c.add_rm();
1537   c.add_rm()->set_c(1);
1538   util::MessageDifferencer differencer;
1539   differencer.set_scope(util::MessageDifferencer::PARTIAL);
1540   differencer.TreatAsSet(GetFieldDescriptor(a, "rm"));
1541   EXPECT_TRUE(differencer.Compare(b, a));
1542   EXPECT_TRUE(differencer.Compare(c, a));
1543 }
1544 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Partial)1545 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Partial) {
1546   protobuf_unittest::TestDiffMessage msg1, msg2;
1547   // message msg1: {
1548   //   rm { a: 1 }
1549   //   rm { b: 2 }
1550   //   rm { c: 3 }
1551   // }
1552   msg1.add_rm()->set_a(1);
1553   msg1.add_rm()->set_b(2);
1554   msg1.add_rm()->set_c(3);
1555   // message msg2: {
1556   //   rm { a: 1; c: 3 }
1557   //   rm { b: 2; c: 3 }
1558   //   rm { b: 2 }
1559   // }
1560   protobuf_unittest::TestField* field = msg2.add_rm();
1561   field->set_a(1);
1562   field->set_c(3);
1563   field = msg2.add_rm();
1564   field->set_b(2);
1565   field->set_c(3);
1566   field = msg2.add_rm();
1567   field->set_b(2);
1568 
1569   util::MessageDifferencer differencer;
1570   differencer.set_scope(util::MessageDifferencer::PARTIAL);
1571   differencer.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
1572   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1573 }
1574 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_MultipleFieldsAsKey)1575 TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldsAsKey) {
1576   protobuf_unittest::TestDiffMessage msg1;
1577   protobuf_unittest::TestDiffMessage msg2;
1578   // Treat "item" as Map, with key = ("a", "ra")
1579   // Treat "item.ra" as Set
1580   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1581   // key => value: (1, {2, 3}) => "a"
1582   item->set_a(1);
1583   item->add_ra(2);
1584   item->add_ra(3);
1585   item->set_b("a");
1586   item = msg1.add_item();
1587   // key => value: (2, {1, 3}) => "b"
1588   item->set_a(2);
1589   item->add_ra(1);
1590   item->add_ra(3);
1591   item->set_b("b");
1592   item = msg1.add_item();
1593   // key => value: (1, {1, 3}) => "c"
1594   item->set_a(1);
1595   item->add_ra(1);
1596   item->add_ra(3);
1597   item->set_b("c");
1598 
1599   item = msg2.add_item();
1600   // key => value: (1, {1, 3}) => "c"
1601   item->set_a(1);
1602   item->add_ra(3);
1603   item->add_ra(1);
1604   item->set_b("c");
1605   item = msg2.add_item();
1606   // key => value: (1, {2, 3}) => "a"
1607   item->set_a(1);
1608   item->add_ra(3);
1609   item->add_ra(2);
1610   item->set_b("a");
1611   item = msg2.add_item();
1612   // key => value: (2, {1, 3}) => "b"
1613   item->set_a(2);
1614   item->add_ra(3);
1615   item->add_ra(1);
1616   item->set_b("b");
1617 
1618   // Compare
1619   util::MessageDifferencer differencer;
1620   differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.ra"));
1621   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1622   std::vector<const FieldDescriptor*> key_fields;
1623   key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
1624   key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
1625   differencer.TreatAsMapWithMultipleFieldsAsKey(
1626       GetFieldDescriptor(msg1, "item"), key_fields);
1627   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1628 
1629   // Introduce some differences.
1630   msg1.clear_item();
1631   msg2.clear_item();
1632   item = msg1.add_item();
1633   item->set_a(4);
1634   item->add_ra(5);
1635   item->add_ra(6);
1636   item->set_b("hello");
1637   item = msg2.add_item();
1638   item->set_a(4);
1639   item->add_ra(6);
1640   item->add_ra(5);
1641   item->set_b("world");
1642   std::string output;
1643   differencer.ReportDifferencesToString(&output);
1644   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1645   EXPECT_EQ(
1646       "moved: item[0].ra[0] -> item[0].ra[1] : 5\n"
1647       "moved: item[0].ra[1] -> item[0].ra[0] : 6\n"
1648       "modified: item[0].b: \"hello\" -> \"world\"\n",
1649       output);
1650 }
1651 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_MultipleFieldPathsAsKey)1652 TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldPathsAsKey) {
1653   protobuf_unittest::TestDiffMessage msg1;
1654   protobuf_unittest::TestDiffMessage msg2;
1655   // Treat "item" as Map, with key = ("m.a", "m.rc")
1656   // Treat "item.m.rc" as Set
1657   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1658   // key => value: (1, {2, 3}) => "a"
1659   item->mutable_m()->set_a(1);
1660   item->mutable_m()->add_rc(2);
1661   item->mutable_m()->add_rc(3);
1662   item->set_b("a");
1663   item = msg1.add_item();
1664   // key => value: (2, {1, 3}) => "b"
1665   item->mutable_m()->set_a(2);
1666   item->mutable_m()->add_rc(1);
1667   item->mutable_m()->add_rc(3);
1668   item->set_b("b");
1669   item = msg1.add_item();
1670   // key => value: (1, {1, 3}) => "c"
1671   item->mutable_m()->set_a(1);
1672   item->mutable_m()->add_rc(1);
1673   item->mutable_m()->add_rc(3);
1674   item->set_b("c");
1675 
1676   item = msg2.add_item();
1677   // key => value: (1, {1, 3}) => "c"
1678   item->mutable_m()->set_a(1);
1679   item->mutable_m()->add_rc(3);
1680   item->mutable_m()->add_rc(1);
1681   item->set_b("c");
1682   item = msg2.add_item();
1683   // key => value: (1, {2, 3}) => "a"
1684   item->mutable_m()->set_a(1);
1685   item->mutable_m()->add_rc(3);
1686   item->mutable_m()->add_rc(2);
1687   item->set_b("a");
1688   item = msg2.add_item();
1689   // key => value: (2, {1, 3}) => "b"
1690   item->mutable_m()->set_a(2);
1691   item->mutable_m()->add_rc(3);
1692   item->mutable_m()->add_rc(1);
1693   item->set_b("b");
1694 
1695   // Compare
1696   util::MessageDifferencer differencer;
1697   differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.m.rc"));
1698   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1699   std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
1700   std::vector<const FieldDescriptor*> key_field_path1;
1701   key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m"));
1702   key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m.a"));
1703   std::vector<const FieldDescriptor*> key_field_path2;
1704   key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m"));
1705   key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m.rc"));
1706   key_field_paths.push_back(key_field_path1);
1707   key_field_paths.push_back(key_field_path2);
1708   differencer.TreatAsMapWithMultipleFieldPathsAsKey(
1709       GetFieldDescriptor(msg1, "item"), key_field_paths);
1710   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1711 
1712   // Introduce some differences.
1713   msg1.clear_item();
1714   msg2.clear_item();
1715   item = msg1.add_item();
1716   item->mutable_m()->set_a(4);
1717   item->mutable_m()->add_rc(5);
1718   item->mutable_m()->add_rc(6);
1719   item->set_b("hello");
1720   item = msg2.add_item();
1721   item->mutable_m()->set_a(4);
1722   item->mutable_m()->add_rc(6);
1723   item->mutable_m()->add_rc(5);
1724   item->set_b("world");
1725   std::string output;
1726   differencer.ReportDifferencesToString(&output);
1727   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1728   EXPECT_EQ(
1729       "modified: item[0].b: \"hello\" -> \"world\"\n"
1730       "moved: item[0].m.rc[0] -> item[0].m.rc[1] : 5\n"
1731       "moved: item[0].m.rc[1] -> item[0].m.rc[0] : 6\n",
1732       output);
1733 }
1734 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_IgnoredKeyFields)1735 TEST(MessageDifferencerTest, RepeatedFieldMapTest_IgnoredKeyFields) {
1736   protobuf_unittest::TestDiffMessage msg1;
1737   protobuf_unittest::TestDiffMessage msg2;
1738   // Treat "item" as Map, with key = ("a", "ra")
1739   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1740   item->set_a(1);
1741   item->add_ra(2);
1742   item->set_b("hello");
1743   item = msg2.add_item();
1744   item->set_a(1);
1745   item->add_ra(3);
1746   item->set_b("world");
1747   // Compare
1748   util::MessageDifferencer differencer;
1749   std::vector<const FieldDescriptor*> key_fields;
1750   key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
1751   key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
1752   differencer.TreatAsMapWithMultipleFieldsAsKey(
1753       GetFieldDescriptor(msg1, "item"), key_fields);
1754   std::string output;
1755   differencer.ReportDifferencesToString(&output);
1756   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1757   EXPECT_EQ(
1758       "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
1759       "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
1760       output);
1761   // Ignored fields that are listed as parts of the key are still used
1762   // in key comparison, but they're not used in value comparison.
1763   differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
1764   output.clear();
1765   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1766   EXPECT_EQ(
1767       "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
1768       "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
1769       output);
1770   // Ignoring a field in the key is different from treating the left fields
1771   // as key. That is:
1772   //   (key = ("a", "ra") && ignore "ra") != (key = ("a") && ignore "ra")
1773   util::MessageDifferencer differencer2;
1774   differencer2.TreatAsMap(GetFieldDescriptor(msg1, "item"),
1775                           GetFieldDescriptor(msg1, "item.a"));
1776   differencer2.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
1777   output.clear();
1778   differencer2.ReportDifferencesToString(&output);
1779   EXPECT_FALSE(differencer2.Compare(msg1, msg2));
1780   EXPECT_EQ(
1781       "ignored: item[0].ra\n"
1782       "modified: item[0].b: \"hello\" -> \"world\"\n",
1783       output);
1784 }
1785 
1786 static const char* const kIgnoredFields[] = {"rm.b", "rm.m.b"};
1787 
1788 class TestIgnorer : public util::MessageDifferencer::IgnoreCriteria {
1789  public:
IsIgnored(const Message & message1,const Message & message2,const FieldDescriptor * field,const std::vector<util::MessageDifferencer::SpecificField> & parent_fields)1790   virtual bool IsIgnored(
1791       const Message& message1, const Message& message2,
1792       const FieldDescriptor* field,
1793       const std::vector<util::MessageDifferencer::SpecificField>&
1794           parent_fields) {
1795     std::string name = "";
1796     for (int i = 0; i < parent_fields.size(); ++i) {
1797       name += parent_fields[i].field->name() + ".";
1798     }
1799     name += field->name();
1800     for (int i = 0; i < GOOGLE_ARRAYSIZE(kIgnoredFields); ++i) {
1801       if (name.compare(kIgnoredFields[i]) == 0) {
1802         return true;
1803       }
1804     }
1805     return false;
1806   }
1807 };
1808 
TEST(MessageDifferencerTest,TreatRepeatedFieldAsSetWithIgnoredFields)1809 TEST(MessageDifferencerTest, TreatRepeatedFieldAsSetWithIgnoredFields) {
1810   protobuf_unittest::TestDiffMessage msg1;
1811   protobuf_unittest::TestDiffMessage msg2;
1812   TextFormat::MergeFromString("rm { a: 11\n b: 12 }", &msg1);
1813   TextFormat::MergeFromString("rm { a: 11\n b: 13 }", &msg2);
1814   util::MessageDifferencer differ;
1815   differ.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
1816   differ.AddIgnoreCriteria(new TestIgnorer);
1817   EXPECT_TRUE(differ.Compare(msg1, msg2));
1818 }
1819 
TEST(MessageDifferencerTest,TreatRepeatedFieldAsMapWithIgnoredKeyFields)1820 TEST(MessageDifferencerTest, TreatRepeatedFieldAsMapWithIgnoredKeyFields) {
1821   protobuf_unittest::TestDiffMessage msg1;
1822   protobuf_unittest::TestDiffMessage msg2;
1823   TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 13\n } }", &msg1);
1824   TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 14\n } }", &msg2);
1825   util::MessageDifferencer differ;
1826   differ.TreatAsMap(GetFieldDescriptor(msg1, "rm"),
1827                     GetFieldDescriptor(msg1, "rm.m"));
1828   differ.AddIgnoreCriteria(new TestIgnorer);
1829   EXPECT_TRUE(differ.Compare(msg1, msg2));
1830 }
1831 
1832 // Takes the product of all elements of item.ra as the key for key comparison.
1833 class ValueProductMapKeyComparator
1834     : public util::MessageDifferencer::MapKeyComparator {
1835  public:
1836   typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,const std::vector<SpecificField> & parent_fields) const1837   virtual bool IsMatch(const Message& message1, const Message& message2,
1838                        const std::vector<SpecificField>& parent_fields) const {
1839     const Reflection* reflection1 = message1.GetReflection();
1840     const Reflection* reflection2 = message2.GetReflection();
1841     // FieldDescriptor for item.ra
1842     const FieldDescriptor* ra_field =
1843         message1.GetDescriptor()->FindFieldByName("ra");
1844     // Get the product of all elements in item.ra
1845     int result1 = 1, result2 = 1;
1846     for (int i = 0; i < reflection1->FieldSize(message1, ra_field); ++i) {
1847       result1 *= reflection1->GetRepeatedInt32(message1, ra_field, i);
1848     }
1849     for (int i = 0; i < reflection2->FieldSize(message2, ra_field); ++i) {
1850       result2 *= reflection2->GetRepeatedInt32(message2, ra_field, i);
1851     }
1852     return result1 == result2;
1853   }
1854 };
1855 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_CustomMapKeyComparator)1856 TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomMapKeyComparator) {
1857   protobuf_unittest::TestDiffMessage msg1;
1858   protobuf_unittest::TestDiffMessage msg2;
1859   // Treat "item" as Map, using custom key comparator to determine if two
1860   // elements have the same key.
1861   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1862   item->add_ra(6);
1863   item->add_ra(35);
1864   item->set_b("hello");
1865   item = msg2.add_item();
1866   item->add_ra(10);
1867   item->add_ra(21);
1868   item->set_b("hello");
1869   util::MessageDifferencer differencer;
1870   ValueProductMapKeyComparator key_comparator;
1871   differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
1872                                            &key_comparator);
1873   std::string output;
1874   differencer.ReportDifferencesToString(&output);
1875   // Though the above two messages have different values for item.ra, they
1876   // are regarded as having the same key because 6 * 35 == 10 * 21. That's
1877   // how the key comparator determines if the two have the same key.
1878   // However, in value comparison, all fields of the message are taken into
1879   // consideration, so they are different because their item.ra fields have
1880   // different values using normal value comparison.
1881   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1882   EXPECT_EQ(
1883       "modified: item[0].ra[0]: 6 -> 10\n"
1884       "modified: item[0].ra[1]: 35 -> 21\n",
1885       output);
1886   differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
1887   output.clear();
1888   // item.ra is ignored in value comparison, so the two messages equal.
1889   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1890   EXPECT_EQ("ignored: item[0].ra\n", output);
1891 }
1892 
1893 // Compares fields by their index offset by one, so index 0 matches with 1, etc.
1894 class OffsetByOneMapKeyComparator
1895     : public util::MessageDifferencer::MapKeyComparator {
1896  public:
1897   typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,const std::vector<SpecificField> & parent_fields) const1898   virtual bool IsMatch(const Message& message1, const Message& message2,
1899                        const std::vector<SpecificField>& parent_fields) const {
1900     return parent_fields.back().index + 1 == parent_fields.back().new_index;
1901   }
1902 };
1903 
TEST(MessageDifferencerTest,RepeatedFieldMapTest_CustomIndexMapKeyComparator)1904 TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomIndexMapKeyComparator) {
1905   protobuf_unittest::TestDiffMessage msg1;
1906   protobuf_unittest::TestDiffMessage msg2;
1907   // Treat "item" as Map, using custom key comparator to determine if two
1908   // elements have the same key.
1909   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
1910   item->set_b("one");
1911   item = msg2.add_item();
1912   item->set_b("zero");
1913   item = msg2.add_item();
1914   item->set_b("one");
1915   util::MessageDifferencer differencer;
1916   OffsetByOneMapKeyComparator key_comparator;
1917   differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
1918                                            &key_comparator);
1919   std::string output;
1920   differencer.ReportDifferencesToString(&output);
1921   // With the offset by one comparator msg1.item[0] should be compared to
1922   // msg2.item[1] and thus be moved, msg2.item[0] should be marked as added.
1923   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1924   EXPECT_EQ(
1925       "moved: item[0] -> item[1] : { b: \"one\" }\n"
1926       "added: item[0]: { b: \"zero\" }\n",
1927       output);
1928 }
1929 
TEST(MessageDifferencerTest,RepeatedFieldSetTest_Subset)1930 TEST(MessageDifferencerTest, RepeatedFieldSetTest_Subset) {
1931   protobuf_unittest::TestDiffMessage msg1;
1932   protobuf_unittest::TestDiffMessage msg2;
1933 
1934   msg1.add_rv(3);
1935   msg1.add_rv(8);
1936   msg1.add_rv(2);
1937   msg2.add_rv(2);
1938   msg2.add_rv(3);
1939   msg2.add_rv(5);
1940   msg2.add_rv(8);
1941 
1942   util::MessageDifferencer differencer;
1943 
1944   // Fail with only partial scope set.
1945   differencer.set_scope(util::MessageDifferencer::PARTIAL);
1946   differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_LIST);
1947   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1948 
1949   // Fail with only set-like comparison set.
1950   differencer.set_scope(util::MessageDifferencer::FULL);
1951   differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1952   EXPECT_FALSE(differencer.Compare(msg1, msg2));
1953 
1954   // Succeed with scope and repeated field comparison set properly.
1955   differencer.set_scope(util::MessageDifferencer::PARTIAL);
1956   differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
1957   EXPECT_TRUE(differencer.Compare(msg1, msg2));
1958 }
1959 
TEST(MessageDifferencerTest,IgnoreField_Single)1960 TEST(MessageDifferencerTest, IgnoreField_Single) {
1961   protobuf_unittest::TestField msg1;
1962   protobuf_unittest::TestField msg2;
1963 
1964   msg1.set_c(3);
1965   msg1.add_rc(1);
1966 
1967   msg2.set_c(5);
1968   msg2.add_rc(1);
1969 
1970   util::MessageDifferencer differencer;
1971   differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
1972 
1973   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
1974 }
1975 
TEST(MessageDifferencerTest,IgnoreField_Repeated)1976 TEST(MessageDifferencerTest, IgnoreField_Repeated) {
1977   protobuf_unittest::TestField msg1;
1978   protobuf_unittest::TestField msg2;
1979 
1980   msg1.set_c(3);
1981   msg1.add_rc(1);
1982   msg1.add_rc(2);
1983 
1984   msg2.set_c(3);
1985   msg2.add_rc(1);
1986   msg2.add_rc(3);
1987 
1988   util::MessageDifferencer differencer;
1989   differencer.IgnoreField(GetFieldDescriptor(msg1, "rc"));
1990 
1991   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
1992 }
1993 
TEST(MessageDifferencerTest,IgnoreField_Message)1994 TEST(MessageDifferencerTest, IgnoreField_Message) {
1995   protobuf_unittest::TestDiffMessage msg1;
1996   protobuf_unittest::TestDiffMessage msg2;
1997 
1998   protobuf_unittest::TestField* field;
1999 
2000   field = msg1.add_rm();
2001   field->set_c(3);
2002 
2003   field = msg2.add_rm();
2004   field->set_c(4);
2005 
2006   util::MessageDifferencer differencer;
2007   differencer.IgnoreField(GetFieldDescriptor(msg1, "rm"));
2008 
2009   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2010 }
2011 
TEST(MessageDifferencerTest,IgnoreField_Group)2012 TEST(MessageDifferencerTest, IgnoreField_Group) {
2013   protobuf_unittest::TestDiffMessage msg1;
2014   protobuf_unittest::TestDiffMessage msg2;
2015 
2016   protobuf_unittest::TestDiffMessage::Item* item;
2017 
2018   item = msg1.add_item();
2019   item->set_a(3);
2020 
2021   item = msg2.add_item();
2022   item->set_a(4);
2023 
2024   util::MessageDifferencer differencer;
2025   differencer.IgnoreField(GetFieldDescriptor(msg1, "item"));
2026 
2027   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2028 }
2029 
TEST(MessageDifferencerTest,IgnoreField_Missing)2030 TEST(MessageDifferencerTest, IgnoreField_Missing) {
2031   protobuf_unittest::TestField msg1;
2032   protobuf_unittest::TestField msg2;
2033 
2034   msg1.set_c(3);
2035   msg1.add_rc(1);
2036 
2037   msg2.add_rc(1);
2038 
2039   util::MessageDifferencer differencer;
2040   differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
2041 
2042   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2043   ExpectEqualsWithDifferencer(&differencer, msg2, msg1);
2044 }
2045 
TEST(MessageDifferencerTest,IgnoreField_Multiple)2046 TEST(MessageDifferencerTest, IgnoreField_Multiple) {
2047   protobuf_unittest::TestField msg1;
2048   protobuf_unittest::TestField msg2;
2049 
2050   msg1.set_c(3);
2051   msg1.add_rc(1);
2052   msg1.add_rc(2);
2053 
2054   msg2.set_c(5);
2055   msg2.add_rc(1);
2056   msg2.add_rc(3);
2057 
2058   const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2059   const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2060 
2061   {  // Ignore c
2062     util::MessageDifferencer differencer;
2063     differencer.IgnoreField(c);
2064 
2065     EXPECT_FALSE(differencer.Compare(msg1, msg2));
2066   }
2067   {  // Ignore rc
2068     util::MessageDifferencer differencer;
2069     differencer.IgnoreField(rc);
2070 
2071     EXPECT_FALSE(differencer.Compare(msg1, msg2));
2072   }
2073   {  // Ignore both
2074     util::MessageDifferencer differencer;
2075     differencer.IgnoreField(c);
2076     differencer.IgnoreField(rc);
2077 
2078     ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2079   }
2080 }
2081 
TEST(MessageDifferencerTest,IgnoreField_NestedMessage)2082 TEST(MessageDifferencerTest, IgnoreField_NestedMessage) {
2083   protobuf_unittest::TestDiffMessage msg1;
2084   protobuf_unittest::TestDiffMessage msg2;
2085 
2086   protobuf_unittest::TestField* field;
2087 
2088   field = msg1.add_rm();
2089   field->set_c(3);
2090   field->add_rc(1);
2091 
2092   field = msg2.add_rm();
2093   field->set_c(4);
2094   field->add_rc(1);
2095 
2096   util::MessageDifferencer differencer;
2097   differencer.IgnoreField(GetFieldDescriptor(msg1, "rm.c"));
2098 
2099   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2100 }
2101 
TEST(MessageDifferencerTest,IgnoreField_NestedGroup)2102 TEST(MessageDifferencerTest, IgnoreField_NestedGroup) {
2103   protobuf_unittest::TestDiffMessage msg1;
2104   protobuf_unittest::TestDiffMessage msg2;
2105 
2106   protobuf_unittest::TestDiffMessage::Item* item;
2107 
2108   item = msg1.add_item();
2109   item->set_a(3);
2110   item->set_b("foo");
2111 
2112   item = msg2.add_item();
2113   item->set_a(4);
2114   item->set_b("foo");
2115 
2116   util::MessageDifferencer differencer;
2117   differencer.IgnoreField(GetFieldDescriptor(msg1, "item.a"));
2118 
2119   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2120 }
2121 
TEST(MessageDifferencerTest,IgnoreField_InsideSet)2122 TEST(MessageDifferencerTest, IgnoreField_InsideSet) {
2123   protobuf_unittest::TestDiffMessage msg1;
2124   protobuf_unittest::TestDiffMessage msg2;
2125 
2126   protobuf_unittest::TestDiffMessage::Item* item;
2127 
2128   item = msg1.add_item();
2129   item->set_a(1);
2130   item->set_b("foo");
2131   item->add_ra(1);
2132 
2133   item = msg1.add_item();
2134   item->set_a(2);
2135   item->set_b("bar");
2136   item->add_ra(2);
2137 
2138   item = msg2.add_item();
2139   item->set_a(2);
2140   item->set_b("bar");
2141   item->add_ra(2);
2142 
2143   item = msg2.add_item();
2144   item->set_a(1);
2145   item->set_b("baz");
2146   item->add_ra(1);
2147 
2148   const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2149   const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
2150 
2151   util::MessageDifferencer differencer;
2152   differencer.IgnoreField(b);
2153   differencer.TreatAsSet(item_desc);
2154 
2155   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2156 }
2157 
TEST(MessageDifferencerTest,IgnoreField_InsideMap)2158 TEST(MessageDifferencerTest, IgnoreField_InsideMap) {
2159   protobuf_unittest::TestDiffMessage msg1;
2160   protobuf_unittest::TestDiffMessage msg2;
2161 
2162   protobuf_unittest::TestDiffMessage::Item* item;
2163 
2164   item = msg1.add_item();
2165   item->set_a(1);
2166   item->set_b("foo");
2167   item->add_ra(1);
2168 
2169   item = msg1.add_item();
2170   item->set_a(2);
2171   item->set_b("bar");
2172   item->add_ra(2);
2173 
2174   item = msg2.add_item();
2175   item->set_a(2);
2176   item->set_b("bar");
2177   item->add_ra(2);
2178 
2179   item = msg2.add_item();
2180   item->set_a(1);
2181   item->set_b("baz");
2182   item->add_ra(1);
2183 
2184   const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2185   const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
2186   const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
2187 
2188   util::MessageDifferencer differencer;
2189   differencer.IgnoreField(b);
2190   differencer.TreatAsMap(item_desc, a);
2191 
2192   ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
2193 }
2194 
TEST(MessageDifferencerTest,IgnoreField_DoesNotIgnoreKey)2195 TEST(MessageDifferencerTest, IgnoreField_DoesNotIgnoreKey) {
2196   protobuf_unittest::TestDiffMessage msg1;
2197   protobuf_unittest::TestDiffMessage msg2;
2198 
2199   protobuf_unittest::TestDiffMessage::Item* item;
2200 
2201   item = msg1.add_item();
2202   item->set_a(1);
2203   item->set_b("foo");
2204   item->add_ra(1);
2205 
2206   item = msg2.add_item();
2207   item->set_a(2);
2208   item->set_b("foo");
2209   item->add_ra(1);
2210 
2211   const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
2212   const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
2213 
2214   util::MessageDifferencer differencer;
2215   differencer.IgnoreField(a);
2216   differencer.TreatAsMap(item_desc, a);
2217 
2218   EXPECT_FALSE(differencer.Compare(msg1, msg2));
2219 }
2220 
TEST(MessageDifferencerTest,IgnoreField_TrumpsCompareWithFields)2221 TEST(MessageDifferencerTest, IgnoreField_TrumpsCompareWithFields) {
2222   protobuf_unittest::TestField msg1;
2223   protobuf_unittest::TestField msg2;
2224 
2225   msg1.set_c(3);
2226   msg1.add_rc(1);
2227   msg1.add_rc(2);
2228 
2229   msg2.set_c(3);
2230   msg2.add_rc(1);
2231   msg2.add_rc(3);
2232 
2233   const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2234   const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2235 
2236   std::vector<const FieldDescriptor*> fields;
2237   fields.push_back(c);
2238   fields.push_back(rc);
2239 
2240   util::MessageDifferencer differencer;
2241   differencer.IgnoreField(rc);
2242 
2243   differencer.set_scope(util::MessageDifferencer::FULL);
2244   EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2245 
2246   differencer.set_scope(util::MessageDifferencer::PARTIAL);
2247   EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2248 }
2249 
TEST(MessageDifferencerTest,IgnoreField_SetReportIgnoresFalse)2250 TEST(MessageDifferencerTest, IgnoreField_SetReportIgnoresFalse) {
2251   protobuf_unittest::TestField msg1;
2252   protobuf_unittest::TestField msg2;
2253 
2254   msg1.set_a(1);
2255   msg1.set_b(2);
2256   msg1.set_c(3);
2257   msg1.add_rc(1);
2258   msg1.add_rc(2);
2259 
2260   msg2.set_a(1);
2261   msg2.set_b(1);
2262 
2263   const FieldDescriptor* a = GetFieldDescriptor(msg1, "a");
2264   const FieldDescriptor* b = GetFieldDescriptor(msg1, "b");
2265   const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
2266   const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
2267 
2268   std::vector<const FieldDescriptor*> fields;
2269   fields.push_back(a);
2270   fields.push_back(b);
2271   fields.push_back(c);
2272   fields.push_back(rc);
2273 
2274   std::string diff_report;
2275   util::MessageDifferencer differencer;
2276   differencer.set_report_ignores(false);
2277   differencer.set_report_matches(true);
2278   differencer.ReportDifferencesToString(&diff_report);
2279   differencer.IgnoreField(c);
2280   differencer.IgnoreField(rc);
2281   differencer.set_scope(util::MessageDifferencer::FULL);
2282   EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields, fields));
2283 
2284   EXPECT_EQ(diff_report,
2285             "matched: a : 1\n"
2286             "modified: b: 2 -> 1\n");
2287 }
2288 
2289 
2290 // Test class to save a copy of the last field_context.parent_fields() vector
2291 // passed to the comparison function.
2292 class ParentSavingFieldComparator : public util::FieldComparator {
2293  public:
ParentSavingFieldComparator()2294   ParentSavingFieldComparator() {}
2295 
Compare(const Message & message_1,const Message & message_2,const FieldDescriptor * field,int index_1,int index_2,const util::FieldContext * field_context)2296   virtual ComparisonResult Compare(const Message& message_1,
2297                                    const Message& message_2,
2298                                    const FieldDescriptor* field, int index_1,
2299                                    int index_2,
2300                                    const util::FieldContext* field_context) {
2301     if (field_context) parent_fields_ = *(field_context->parent_fields());
2302     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2303       return RECURSE;
2304     } else {
2305       return SAME;
2306     }
2307   }
2308 
parent_fields()2309   std::vector<util::MessageDifferencer::SpecificField> parent_fields() {
2310     return parent_fields_;
2311   }
2312 
2313  private:
2314   std::vector<util::MessageDifferencer::SpecificField> parent_fields_;
2315 };
2316 
2317 // Tests if MessageDifferencer sends the parent fields in the FieldContext
2318 // parameter.
TEST(MessageDifferencerTest,FieldContextParentFieldsTest)2319 TEST(MessageDifferencerTest, FieldContextParentFieldsTest) {
2320   protobuf_unittest::TestDiffMessage msg1;
2321   msg1.add_rm()->set_c(1);
2322   protobuf_unittest::TestDiffMessage msg2;
2323   msg2.add_rm()->set_c(1);
2324 
2325   ParentSavingFieldComparator field_comparator;
2326   util::MessageDifferencer differencer;
2327   differencer.set_field_comparator(&field_comparator);
2328   differencer.Compare(msg1, msg2);
2329 
2330   // We want only one parent with the name "rm"
2331   ASSERT_EQ(1, field_comparator.parent_fields().size());
2332   EXPECT_EQ("rm", field_comparator.parent_fields()[0].field->name());
2333 }
2334 
2335 
2336 class ComparisonTest : public testing::Test {
2337  protected:
ComparisonTest()2338   ComparisonTest() : use_equivalency_(false), repeated_field_as_set_(false) {
2339     // Setup the test.
2340     TestUtil::SetAllFields(&proto1_);
2341     TestUtil::SetAllFields(&proto2_);
2342 
2343     TestUtil::SetAllExtensions(&proto1ex_);
2344     TestUtil::SetAllExtensions(&proto2ex_);
2345 
2346     TestUtil::SetAllFieldsAndExtensions(&orderings_proto1_);
2347     TestUtil::SetAllFieldsAndExtensions(&orderings_proto2_);
2348 
2349     unknown1_ = empty1_.mutable_unknown_fields();
2350     unknown2_ = empty2_.mutable_unknown_fields();
2351   }
2352 
~ComparisonTest()2353   ~ComparisonTest() {}
2354 
SetSpecialFieldOption(const Message & message,util::MessageDifferencer * d)2355   void SetSpecialFieldOption(const Message& message,
2356                              util::MessageDifferencer* d) {
2357     if (!ignored_field_.empty()) {
2358       d->IgnoreField(GetFieldDescriptor(message, ignored_field_));
2359     }
2360 
2361     if (repeated_field_as_set_) {
2362       d->set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
2363     }
2364 
2365     if (!set_field_.empty()) {
2366       d->TreatAsSet(GetFieldDescriptor(message, set_field_));
2367     }
2368 
2369     if (!map_field_.empty() && !map_key_.empty()) {
2370       d->TreatAsMap(GetFieldDescriptor(message, map_field_),
2371                     GetFieldDescriptor(message, map_field_ + "." + map_key_));
2372     }
2373   }
2374 
Run(const Message & msg1,const Message & msg2)2375   std::string Run(const Message& msg1, const Message& msg2) {
2376     std::string output;
2377 
2378     // Setup the comparison.
2379     util::MessageDifferencer differencer;
2380     differencer.ReportDifferencesToString(&output);
2381 
2382     if (use_equivalency_) {
2383       differencer.set_message_field_comparison(
2384           util::MessageDifferencer::EQUIVALENT);
2385     }
2386 
2387     SetSpecialFieldOption(msg1, &differencer);
2388 
2389     // Conduct the comparison.
2390     EXPECT_FALSE(differencer.Compare(msg1, msg2));
2391 
2392     return output;
2393   }
2394 
Run()2395   std::string Run() { return Run(proto1_, proto2_); }
2396 
RunOrder()2397   std::string RunOrder() { return Run(orderings_proto1_, orderings_proto2_); }
2398 
RunEx()2399   std::string RunEx() { return Run(proto1ex_, proto2ex_); }
2400 
RunDiff()2401   std::string RunDiff() { return Run(proto1diff_, proto2diff_); }
2402 
RunUn()2403   std::string RunUn() { return Run(empty1_, empty2_); }
2404 
use_equivalency()2405   void use_equivalency() { use_equivalency_ = true; }
2406 
repeated_field_as_set()2407   void repeated_field_as_set() { repeated_field_as_set_ = true; }
2408 
field_as_set(const std::string & field)2409   void field_as_set(const std::string& field) { set_field_ = field; }
2410 
field_as_map(const std::string & field,const std::string & key)2411   void field_as_map(const std::string& field, const std::string& key) {
2412     map_field_ = field;
2413     map_key_ = key;
2414   }
2415 
ignore_field(const std::string & field)2416   void ignore_field(const std::string& field) { ignored_field_ = field; }
2417 
2418   unittest::TestAllTypes proto1_;
2419   unittest::TestAllTypes proto2_;
2420 
2421   unittest::TestFieldOrderings orderings_proto1_;
2422   unittest::TestFieldOrderings orderings_proto2_;
2423 
2424   unittest::TestAllExtensions proto1ex_;
2425   unittest::TestAllExtensions proto2ex_;
2426 
2427   unittest::TestDiffMessage proto1diff_;
2428   unittest::TestDiffMessage proto2diff_;
2429 
2430   unittest::TestEmptyMessage empty1_;
2431   unittest::TestEmptyMessage empty2_;
2432 
2433   unittest::TestMap map_proto1_;
2434   unittest::TestMap map_proto2_;
2435 
2436   UnknownFieldSet* unknown1_;
2437   UnknownFieldSet* unknown2_;
2438 
2439   bool use_equivalency_;
2440   bool repeated_field_as_set_;
2441 
2442   std::string set_field_;
2443   std::string map_field_;
2444   std::string map_key_;
2445   std::string ignored_field_;
2446 };
2447 
2448 // Basic tests.
TEST_F(ComparisonTest,AdditionTest)2449 TEST_F(ComparisonTest, AdditionTest) {
2450   proto1_.clear_optional_int32();
2451 
2452   EXPECT_EQ("added: optional_int32: 101\n", Run());
2453 }
2454 
TEST_F(ComparisonTest,Addition_OrderTest)2455 TEST_F(ComparisonTest, Addition_OrderTest) {
2456   orderings_proto1_.clear_my_int();
2457 
2458   EXPECT_EQ("added: my_int: 1\n", RunOrder());
2459 }
2460 
TEST_F(ComparisonTest,DeletionTest)2461 TEST_F(ComparisonTest, DeletionTest) {
2462   proto2_.clear_optional_int32();
2463 
2464   EXPECT_EQ("deleted: optional_int32: 101\n", Run());
2465 }
2466 
TEST_F(ComparisonTest,Deletion_OrderTest)2467 TEST_F(ComparisonTest, Deletion_OrderTest) {
2468   orderings_proto2_.clear_my_string();
2469 
2470   EXPECT_EQ("deleted: my_string: \"foo\"\n", RunOrder());
2471 }
2472 
TEST_F(ComparisonTest,RepeatedDeletionTest)2473 TEST_F(ComparisonTest, RepeatedDeletionTest) {
2474   proto2_.clear_repeated_int32();
2475 
2476   EXPECT_EQ(
2477       "deleted: repeated_int32[0]: 201\n"
2478       "deleted: repeated_int32[1]: 301\n",
2479       Run());
2480 }
2481 
TEST_F(ComparisonTest,ModificationTest)2482 TEST_F(ComparisonTest, ModificationTest) {
2483   proto1_.set_optional_int32(-1);
2484 
2485   EXPECT_EQ("modified: optional_int32: -1 -> 101\n", Run());
2486 }
2487 
2488 // Basic equivalency tests.
TEST_F(ComparisonTest,EquivalencyAdditionTest)2489 TEST_F(ComparisonTest, EquivalencyAdditionTest) {
2490   use_equivalency();
2491 
2492   proto1_.clear_optional_int32();
2493 
2494   EXPECT_EQ("modified: optional_int32: 0 -> 101\n", Run());
2495 }
2496 
TEST_F(ComparisonTest,EquivalencyDeletionTest)2497 TEST_F(ComparisonTest, EquivalencyDeletionTest) {
2498   use_equivalency();
2499 
2500   proto2_.clear_optional_int32();
2501 
2502   EXPECT_EQ("modified: optional_int32: 101 -> 0\n", Run());
2503 }
2504 
2505 // Group tests.
TEST_F(ComparisonTest,GroupAdditionTest)2506 TEST_F(ComparisonTest, GroupAdditionTest) {
2507   proto1_.mutable_optionalgroup()->clear_a();
2508 
2509   EXPECT_EQ("added: optionalgroup.a: 117\n", Run());
2510 }
2511 
TEST_F(ComparisonTest,GroupDeletionTest)2512 TEST_F(ComparisonTest, GroupDeletionTest) {
2513   proto2_.mutable_optionalgroup()->clear_a();
2514 
2515   EXPECT_EQ("deleted: optionalgroup.a: 117\n", Run());
2516 }
2517 
TEST_F(ComparisonTest,GroupModificationTest)2518 TEST_F(ComparisonTest, GroupModificationTest) {
2519   proto1_.mutable_optionalgroup()->set_a(2);
2520 
2521   EXPECT_EQ("modified: optionalgroup.a: 2 -> 117\n", Run());
2522 }
2523 
TEST_F(ComparisonTest,GroupFullAdditionTest)2524 TEST_F(ComparisonTest, GroupFullAdditionTest) {
2525   proto1_.clear_optionalgroup();
2526 
2527   // Note the difference in the output between this and GroupAdditionTest.
2528   EXPECT_EQ("added: optionalgroup: { a: 117 }\n", Run());
2529 }
2530 
TEST_F(ComparisonTest,GroupFullDeletionTest)2531 TEST_F(ComparisonTest, GroupFullDeletionTest) {
2532   proto2_.clear_optionalgroup();
2533 
2534   EXPECT_EQ("deleted: optionalgroup: { a: 117 }\n", Run());
2535 }
2536 
TEST_F(ComparisonTest,RepeatedSetOptionTest)2537 TEST_F(ComparisonTest, RepeatedSetOptionTest) {
2538   repeated_field_as_set();
2539 
2540   proto2_.clear_repeatedgroup();
2541   proto1_.clear_repeatedgroup();
2542   proto1_.add_repeatedgroup()->set_a(317);
2543   proto2_.add_repeatedgroup()->set_a(909);
2544   proto2_.add_repeatedgroup()->set_a(907);
2545   proto1_.add_repeatedgroup()->set_a(904);
2546   proto1_.add_repeatedgroup()->set_a(907);
2547   proto1_.add_repeatedgroup()->set_a(909);
2548 
2549   EXPECT_EQ(
2550       "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
2551       "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
2552       "deleted: repeatedgroup[0]: { a: 317 }\n"
2553       "deleted: repeatedgroup[1]: { a: 904 }\n",
2554       Run());
2555 }
2556 
TEST_F(ComparisonTest,RepeatedSetOptionTest_Ex)2557 TEST_F(ComparisonTest, RepeatedSetOptionTest_Ex) {
2558   repeated_field_as_set();
2559 
2560   proto1ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
2561   proto2ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
2562   proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
2563       ->set_bb(909);
2564   proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
2565       ->set_bb(907);
2566   proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
2567       ->set_bb(904);
2568   proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
2569       ->set_bb(907);
2570   proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
2571       ->set_bb(909);
2572 
2573   EXPECT_EQ(
2574       "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
2575       " (protobuf_unittest.repeated_nested_message_extension)[0] :"
2576       " { bb: 909 }\n"
2577       "deleted: (protobuf_unittest.repeated_nested_message_extension)[0]:"
2578       " { bb: 904 }\n",
2579       RunEx());
2580 }
2581 
TEST_F(ComparisonTest,RepeatedMapFieldTest_Group)2582 TEST_F(ComparisonTest, RepeatedMapFieldTest_Group) {
2583   field_as_map("repeatedgroup", "a");
2584   proto1_.clear_repeatedgroup();
2585   proto2_.clear_repeatedgroup();
2586 
2587   proto1_.add_repeatedgroup()->set_a(317);  // deleted
2588   proto1_.add_repeatedgroup()->set_a(904);  // deleted
2589   proto1_.add_repeatedgroup()->set_a(907);  // moved from
2590   proto1_.add_repeatedgroup()->set_a(909);  // moved from
2591 
2592   proto2_.add_repeatedgroup()->set_a(909);  // moved to
2593   proto2_.add_repeatedgroup()->set_a(318);  // added
2594   proto2_.add_repeatedgroup()->set_a(907);  // moved to
2595 
2596   EXPECT_EQ(
2597       "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
2598       "added: repeatedgroup[1]: { a: 318 }\n"
2599       "deleted: repeatedgroup[0]: { a: 317 }\n"
2600       "deleted: repeatedgroup[1]: { a: 904 }\n",
2601       Run());
2602 }
2603 
TEST_F(ComparisonTest,RepeatedMapFieldTest_MessageKey)2604 TEST_F(ComparisonTest, RepeatedMapFieldTest_MessageKey) {
2605   // Use m as key, but use b as value.
2606   field_as_map("item", "m");
2607 
2608   protobuf_unittest::TestDiffMessage msg1;
2609   protobuf_unittest::TestDiffMessage msg2;
2610   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2611 
2612   // The following code creates one deletion, one addition and two moved fields
2613   // on the messages.
2614   item->mutable_m()->set_c(0);
2615   item->set_b("first");
2616   item = msg1.add_item();
2617   item->mutable_m()->set_c(2);
2618   item->set_b("second");
2619   item = msg1.add_item();
2620   item->set_b("null");  // empty key moved
2621   item = msg1.add_item();
2622   item->mutable_m()->set_c(3);
2623   item->set_b("third");  // deletion
2624   item = msg1.add_item();
2625   item->mutable_m()->set_c(2);
2626   item->set_b("second");  // duplicated key ( deletion )
2627   item = msg2.add_item();
2628   item->mutable_m()->set_c(2);
2629   item->set_b("second");  // modification
2630   item = msg2.add_item();
2631   item->mutable_m()->set_c(4);
2632   item->set_b("fourth");  // addition
2633   item = msg2.add_item();
2634   item->mutable_m()->set_c(0);
2635   item->set_b("fist");  // move with change
2636   item = msg2.add_item();
2637   item->set_b("null");
2638 
2639   EXPECT_EQ(
2640       "modified: item[0].b -> item[2].b: \"first\" -> \"fist\"\n"
2641       "moved: item[1] -> item[0] : { b: \"second\" m { c: 2 } }\n"
2642       "moved: item[2] -> item[3] : { b: \"null\" }\n"
2643       "added: item[1]: { b: \"fourth\" m { c: 4 } }\n"
2644       "deleted: item[3]: { b: \"third\" m { c: 3 } }\n"
2645       "deleted: item[4]: { b: \"second\" m { c: 2 } }\n",
2646       Run(msg1, msg2));
2647 }
2648 
TEST_F(ComparisonTest,RepeatedFieldSetTest_SetOfSet)2649 TEST_F(ComparisonTest, RepeatedFieldSetTest_SetOfSet) {
2650   repeated_field_as_set();
2651   // Create the testing protos
2652   protobuf_unittest::TestDiffMessage msg1;
2653   protobuf_unittest::TestDiffMessage msg2;
2654 
2655   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2656   item->add_ra(1);
2657   item->add_ra(2);
2658   item->add_ra(3);
2659   item = msg1.add_item();
2660   item->add_ra(5);
2661   item->add_ra(6);
2662   item = msg1.add_item();
2663   item->add_ra(1);
2664   item->add_ra(3);
2665   item = msg1.add_item();
2666   item->add_ra(6);
2667   item->add_ra(7);
2668   item->add_ra(8);
2669 
2670   item = msg2.add_item();
2671   item->add_ra(6);
2672   item->add_ra(5);
2673   item = msg2.add_item();
2674   item->add_ra(6);
2675   item->add_ra(8);
2676   item = msg2.add_item();
2677   item->add_ra(1);
2678   item->add_ra(3);
2679   item = msg2.add_item();
2680   item->add_ra(3);
2681   item->add_ra(2);
2682   item->add_ra(1);
2683 
2684   // Compare
2685   EXPECT_EQ(
2686       "moved: item[0].ra[0] -> item[3].ra[2] : 1\n"
2687       "moved: item[0].ra[2] -> item[3].ra[0] : 3\n"
2688       "moved: item[0] -> item[3] : { ra: 1 ra: 2 ra: 3 }\n"
2689       "moved: item[1].ra[0] -> item[0].ra[1] : 5\n"
2690       "moved: item[1].ra[1] -> item[0].ra[0] : 6\n"
2691       "moved: item[1] -> item[0] : { ra: 5 ra: 6 }\n"
2692       "added: item[1]: { ra: 6 ra: 8 }\n"
2693       "deleted: item[3]: { ra: 6 ra: 7 ra: 8 }\n",
2694       Run(msg1, msg2));
2695 }
2696 
TEST_F(ComparisonTest,RepeatedMapFieldTest_RepeatedKey)2697 TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedKey) {
2698   // used rb as a key, but b is the value.
2699   repeated_field_as_set();
2700   field_as_map("item", "rb");
2701 
2702   protobuf_unittest::TestDiffMessage msg1;
2703   protobuf_unittest::TestDiffMessage msg2;
2704   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2705   item->add_rb("a");
2706   item->add_rb("b");
2707   item->set_b("first");
2708 
2709   item = msg2.add_item();
2710   item->add_rb("c");
2711   item->set_b("second");
2712 
2713   item = msg2.add_item();
2714   item->add_rb("b");
2715   item->add_rb("a");
2716   item->set_b("fist");
2717 
2718   EXPECT_EQ(
2719       "modified: item[0].b -> item[1].b: \"first\" -> \"fist\"\n"
2720       "moved: item[0].rb[0] -> item[1].rb[1] : \"a\"\n"
2721       "moved: item[0].rb[1] -> item[1].rb[0] : \"b\"\n"
2722       "added: item[0]: { b: \"second\" rb: \"c\" }\n",
2723       Run(msg1, msg2));
2724 }
2725 
TEST_F(ComparisonTest,RepeatedMapFieldTest_RepeatedMessageKey)2726 TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedMessageKey) {
2727   field_as_map("item", "rm");
2728 
2729   protobuf_unittest::TestDiffMessage msg1;
2730   protobuf_unittest::TestDiffMessage msg2;
2731   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
2732   protobuf_unittest::TestField* key = item->add_rm();
2733   key->set_c(2);
2734   key->add_rc(10);
2735   key->add_rc(10);
2736   item = msg1.add_item();
2737   key = item->add_rm();
2738   key->set_c(0);
2739   key->add_rc(1);
2740   key->add_rc(2);
2741   key = item->add_rm();
2742   key->set_c(0);
2743   item->add_rb("first");
2744 
2745   item = msg2.add_item();
2746   item->CopyFrom(msg1.item(1));
2747   item->add_rb("second");
2748 
2749   EXPECT_EQ(
2750       "added: item[0].rb[1]: \"second\"\n"
2751       "deleted: item[0]: { rm { c: 2 rc: 10 rc: 10 } }\n",
2752       Run(msg1, msg2));
2753 }
2754 
TEST_F(ComparisonTest,RepeatedSetOptionTest_Unknown)2755 TEST_F(ComparisonTest, RepeatedSetOptionTest_Unknown) {
2756   // Currently, as_set option doesn't have affects on unknown field.
2757   // If needed, this feature will be added by request.
2758   repeated_field_as_set();
2759   unknown1_->AddGroup(245)->AddFixed32(248, 1);
2760   unknown2_->AddGroup(245)->AddFixed32(248, 3);
2761   unknown2_->AddGroup(245)->AddFixed32(248, 1);
2762 
2763   // We expect it behaves the same as normal comparison.
2764   EXPECT_EQ(
2765       "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
2766       "added: 245[1]: { ... }\n",
2767       RunUn());
2768 }
2769 
TEST_F(ComparisonTest,Matching_Unknown)2770 TEST_F(ComparisonTest, Matching_Unknown) {
2771   unknown1_->AddGroup(245)->AddFixed32(248, 1);
2772   unknown2_->AddGroup(245)->AddFixed32(248, 1);
2773   unknown1_->AddGroup(245)->AddFixed32(248, 3);
2774   unknown2_->AddGroup(245)->AddFixed32(248, 3);
2775   unknown2_->AddLengthDelimited(242, "cat");
2776   unknown2_->AddGroup(246)->AddFixed32(248, 4);
2777 
2778   // report_match is false so only added/modified fields are expected.
2779   EXPECT_EQ(
2780       "added: 242[0]: \"cat\"\n"
2781       "added: 246[0]: { ... }\n",
2782       RunUn());
2783 }
2784 
TEST_F(ComparisonTest,RepeatedSetFieldTest)2785 TEST_F(ComparisonTest, RepeatedSetFieldTest) {
2786   field_as_set("repeatedgroup");
2787 
2788   proto1_.clear_repeatedgroup();
2789   proto2_.clear_repeatedgroup();
2790   proto2_.add_repeatedgroup()->set_a(909);
2791   proto2_.add_repeatedgroup()->set_a(907);
2792   proto1_.add_repeatedgroup()->set_a(317);
2793   proto1_.add_repeatedgroup()->set_a(904);
2794   proto1_.add_repeatedgroup()->set_a(907);
2795   proto1_.add_repeatedgroup()->set_a(909);
2796 
2797   EXPECT_EQ(
2798       "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
2799       "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
2800       "deleted: repeatedgroup[0]: { a: 317 }\n"
2801       "deleted: repeatedgroup[1]: { a: 904 }\n",
2802       Run());
2803 }
2804 
2805 // Embedded message tests.
TEST_F(ComparisonTest,EmbeddedAdditionTest)2806 TEST_F(ComparisonTest, EmbeddedAdditionTest) {
2807   proto1_.mutable_optional_nested_message()->clear_bb();
2808 
2809   EXPECT_EQ("added: optional_nested_message.bb: 118\n", Run());
2810 }
2811 
TEST_F(ComparisonTest,EmbeddedDeletionTest)2812 TEST_F(ComparisonTest, EmbeddedDeletionTest) {
2813   proto2_.mutable_optional_nested_message()->clear_bb();
2814 
2815   EXPECT_EQ("deleted: optional_nested_message.bb: 118\n", Run());
2816 }
2817 
TEST_F(ComparisonTest,EmbeddedModificationTest)2818 TEST_F(ComparisonTest, EmbeddedModificationTest) {
2819   proto1_.mutable_optional_nested_message()->set_bb(2);
2820 
2821   EXPECT_EQ("modified: optional_nested_message.bb: 2 -> 118\n", Run());
2822 }
2823 
TEST_F(ComparisonTest,EmbeddedFullAdditionTest)2824 TEST_F(ComparisonTest, EmbeddedFullAdditionTest) {
2825   proto1_.clear_optional_nested_message();
2826 
2827   EXPECT_EQ("added: optional_nested_message: { bb: 118 }\n", Run());
2828 }
2829 
TEST_F(ComparisonTest,EmbeddedPartialAdditionTest)2830 TEST_F(ComparisonTest, EmbeddedPartialAdditionTest) {
2831   proto1_.clear_optional_nested_message();
2832   proto2_.mutable_optional_nested_message()->clear_bb();
2833 
2834   EXPECT_EQ("added: optional_nested_message: { }\n", Run());
2835 }
2836 
TEST_F(ComparisonTest,EmbeddedFullDeletionTest)2837 TEST_F(ComparisonTest, EmbeddedFullDeletionTest) {
2838   proto2_.clear_optional_nested_message();
2839 
2840   EXPECT_EQ("deleted: optional_nested_message: { bb: 118 }\n", Run());
2841 }
2842 
2843 // Repeated element tests.
TEST_F(ComparisonTest,BasicRepeatedTest)2844 TEST_F(ComparisonTest, BasicRepeatedTest) {
2845   proto1_.clear_repeated_int32();
2846   proto2_.clear_repeated_int32();
2847 
2848   proto1_.add_repeated_int32(500);
2849   proto1_.add_repeated_int32(501);
2850   proto1_.add_repeated_int32(502);
2851   proto1_.add_repeated_int32(503);
2852   proto1_.add_repeated_int32(500);
2853 
2854   proto2_.add_repeated_int32(500);
2855   proto2_.add_repeated_int32(509);
2856   proto2_.add_repeated_int32(502);
2857   proto2_.add_repeated_int32(504);
2858 
2859   EXPECT_EQ(
2860       "modified: repeated_int32[1]: 501 -> 509\n"
2861       "modified: repeated_int32[3]: 503 -> 504\n"
2862       "deleted: repeated_int32[4]: 500\n",
2863       Run());
2864 }
2865 
TEST_F(ComparisonTest,BasicRepeatedTest_SetOption)2866 TEST_F(ComparisonTest, BasicRepeatedTest_SetOption) {
2867   repeated_field_as_set();
2868   proto1_.clear_repeated_int32();
2869   proto2_.clear_repeated_int32();
2870 
2871   proto1_.add_repeated_int32(501);
2872   proto1_.add_repeated_int32(502);
2873   proto1_.add_repeated_int32(503);
2874   proto1_.add_repeated_int32(500);
2875   proto1_.add_repeated_int32(500);
2876 
2877   proto2_.add_repeated_int32(500);
2878   proto2_.add_repeated_int32(509);
2879   proto2_.add_repeated_int32(503);
2880   proto2_.add_repeated_int32(502);
2881   proto2_.add_repeated_int32(504);
2882 
2883   EXPECT_EQ(
2884       "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
2885       "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
2886       "added: repeated_int32[1]: 509\n"
2887       "added: repeated_int32[4]: 504\n"
2888       "deleted: repeated_int32[0]: 501\n"
2889       "deleted: repeated_int32[4]: 500\n",
2890       Run());
2891 }
2892 
TEST_F(ComparisonTest,BasicRepeatedTest_SetField)2893 TEST_F(ComparisonTest, BasicRepeatedTest_SetField) {
2894   field_as_set("repeated_int32");
2895   proto1_.clear_repeated_int32();
2896   proto2_.clear_repeated_int32();
2897 
2898   proto1_.add_repeated_int32(501);
2899   proto1_.add_repeated_int32(502);
2900   proto1_.add_repeated_int32(503);
2901   proto1_.add_repeated_int32(500);
2902   proto1_.add_repeated_int32(500);
2903 
2904   proto2_.add_repeated_int32(500);
2905   proto2_.add_repeated_int32(509);
2906   proto2_.add_repeated_int32(503);
2907   proto2_.add_repeated_int32(502);
2908   proto2_.add_repeated_int32(504);
2909 
2910   EXPECT_EQ(
2911       "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
2912       "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
2913       "added: repeated_int32[1]: 509\n"
2914       "added: repeated_int32[4]: 504\n"
2915       "deleted: repeated_int32[0]: 501\n"
2916       "deleted: repeated_int32[4]: 500\n",
2917       Run());
2918 }
2919 
2920 // Multiple action tests.
TEST_F(ComparisonTest,AddDeleteTest)2921 TEST_F(ComparisonTest, AddDeleteTest) {
2922   proto1_.clear_optional_int32();
2923   proto2_.clear_optional_int64();
2924 
2925   EXPECT_EQ(
2926       "added: optional_int32: 101\n"
2927       "deleted: optional_int64: 102\n",
2928       Run());
2929 }
2930 
TEST_F(ComparisonTest,AddDelete_FieldOrderingTest)2931 TEST_F(ComparisonTest, AddDelete_FieldOrderingTest) {
2932   orderings_proto1_.ClearExtension(unittest::my_extension_string);
2933   orderings_proto2_.clear_my_int();
2934 
2935   EXPECT_EQ(
2936       "deleted: my_int: 1\n"
2937       "added: (protobuf_unittest.my_extension_string): \"bar\"\n",
2938       RunOrder());
2939 }
2940 
TEST_F(ComparisonTest,AllThreeTest)2941 TEST_F(ComparisonTest, AllThreeTest) {
2942   proto1_.clear_optional_int32();
2943   proto2_.clear_optional_float();
2944   proto2_.set_optional_string("hello world!");
2945 
2946   EXPECT_EQ(
2947       "added: optional_int32: 101\n"
2948       "deleted: optional_float: 111\n"
2949       "modified: optional_string: \"115\" -> \"hello world!\"\n",
2950       Run());
2951 }
2952 
TEST_F(ComparisonTest,SandwhichTest)2953 TEST_F(ComparisonTest, SandwhichTest) {
2954   proto1_.clear_optional_int64();
2955   proto1_.clear_optional_uint32();
2956 
2957   proto2_.clear_optional_uint64();
2958 
2959   EXPECT_EQ(
2960       "added: optional_int64: 102\n"
2961       "added: optional_uint32: 103\n"
2962       "deleted: optional_uint64: 104\n",
2963       Run());
2964 }
2965 
TEST_F(ComparisonTest,IgnoredNoChangeTest)2966 TEST_F(ComparisonTest, IgnoredNoChangeTest) {
2967   proto1diff_.set_v(3);
2968   proto2diff_.set_v(3);
2969   proto2diff_.set_w("foo");
2970 
2971   ignore_field("v");
2972 
2973   EXPECT_EQ(
2974       "ignored: v\n"
2975       "added: w: \"foo\"\n",
2976       RunDiff());
2977 }
2978 
TEST_F(ComparisonTest,IgnoredAddTest)2979 TEST_F(ComparisonTest, IgnoredAddTest) {
2980   proto2diff_.set_v(3);
2981   proto2diff_.set_w("foo");
2982 
2983   ignore_field("v");
2984 
2985   EXPECT_EQ(
2986       "ignored: v\n"
2987       "added: w: \"foo\"\n",
2988       RunDiff());
2989 }
2990 
TEST_F(ComparisonTest,IgnoredDeleteTest)2991 TEST_F(ComparisonTest, IgnoredDeleteTest) {
2992   proto1diff_.set_v(3);
2993   proto2diff_.set_w("foo");
2994 
2995   ignore_field("v");
2996 
2997   EXPECT_EQ(
2998       "ignored: v\n"
2999       "added: w: \"foo\"\n",
3000       RunDiff());
3001 }
3002 
TEST_F(ComparisonTest,IgnoredModifyTest)3003 TEST_F(ComparisonTest, IgnoredModifyTest) {
3004   proto1diff_.set_v(3);
3005   proto2diff_.set_v(4);
3006   proto2diff_.set_w("foo");
3007 
3008   ignore_field("v");
3009 
3010   EXPECT_EQ(
3011       "ignored: v\n"
3012       "added: w: \"foo\"\n",
3013       RunDiff());
3014 }
3015 
TEST_F(ComparisonTest,IgnoredRepeatedAddTest)3016 TEST_F(ComparisonTest, IgnoredRepeatedAddTest) {
3017   proto1diff_.add_rv(3);
3018   proto1diff_.add_rv(4);
3019 
3020   proto2diff_.add_rv(3);
3021   proto2diff_.add_rv(4);
3022   proto2diff_.add_rv(5);
3023 
3024   proto2diff_.set_w("foo");
3025 
3026   ignore_field("rv");
3027 
3028   EXPECT_EQ(
3029       "ignored: rv\n"
3030       "added: w: \"foo\"\n",
3031       RunDiff());
3032 }
3033 
TEST_F(ComparisonTest,IgnoredRepeatedDeleteTest)3034 TEST_F(ComparisonTest, IgnoredRepeatedDeleteTest) {
3035   proto1diff_.add_rv(3);
3036   proto1diff_.add_rv(4);
3037   proto1diff_.add_rv(5);
3038 
3039   proto2diff_.add_rv(3);
3040   proto2diff_.add_rv(4);
3041 
3042   proto2diff_.set_w("foo");
3043 
3044   ignore_field("rv");
3045 
3046   EXPECT_EQ(
3047       "ignored: rv\n"
3048       "added: w: \"foo\"\n",
3049       RunDiff());
3050 }
3051 
TEST_F(ComparisonTest,IgnoredRepeatedModifyTest)3052 TEST_F(ComparisonTest, IgnoredRepeatedModifyTest) {
3053   proto1diff_.add_rv(3);
3054   proto1diff_.add_rv(4);
3055 
3056   proto2diff_.add_rv(3);
3057   proto2diff_.add_rv(5);
3058 
3059   proto2diff_.set_w("foo");
3060 
3061   ignore_field("rv");
3062 
3063   EXPECT_EQ(
3064       "ignored: rv\n"
3065       "added: w: \"foo\"\n",
3066       RunDiff());
3067 }
3068 
TEST_F(ComparisonTest,IgnoredWholeNestedMessage)3069 TEST_F(ComparisonTest, IgnoredWholeNestedMessage) {
3070   proto1diff_.mutable_m()->set_c(3);
3071   proto2diff_.mutable_m()->set_c(4);
3072 
3073   proto2diff_.set_w("foo");
3074 
3075   ignore_field("m");
3076 
3077   EXPECT_EQ(
3078       "added: w: \"foo\"\n"
3079       "ignored: m\n",
3080       RunDiff());
3081 }
3082 
TEST_F(ComparisonTest,IgnoredNestedField)3083 TEST_F(ComparisonTest, IgnoredNestedField) {
3084   proto1diff_.mutable_m()->set_c(3);
3085   proto2diff_.mutable_m()->set_c(4);
3086 
3087   proto2diff_.set_w("foo");
3088 
3089   ignore_field("m.c");
3090 
3091   EXPECT_EQ(
3092       "added: w: \"foo\"\n"
3093       "ignored: m.c\n",
3094       RunDiff());
3095 }
3096 
TEST_F(ComparisonTest,IgnoredRepeatedNested)3097 TEST_F(ComparisonTest, IgnoredRepeatedNested) {
3098   proto1diff_.add_rm()->set_c(0);
3099   proto1diff_.add_rm()->set_c(1);
3100   proto2diff_.add_rm()->set_c(2);
3101   proto2diff_.add_rm()->set_c(3);
3102 
3103   proto2diff_.set_w("foo");
3104 
3105   ignore_field("rm.c");
3106 
3107   EXPECT_EQ(
3108       "ignored: rm[0].c\n"
3109       "ignored: rm[1].c\n"
3110       "added: w: \"foo\"\n",
3111       RunDiff());
3112 }
3113 
TEST_F(ComparisonTest,IgnoredNestedRepeated)3114 TEST_F(ComparisonTest, IgnoredNestedRepeated) {
3115   proto1diff_.mutable_m()->add_rc(23);
3116   proto1diff_.mutable_m()->add_rc(24);
3117   proto2diff_.mutable_m()->add_rc(25);
3118 
3119   proto2diff_.set_w("foo");
3120 
3121   ignore_field("m.rc");
3122 
3123   EXPECT_EQ(
3124       "added: w: \"foo\"\n"
3125       "ignored: m.rc\n",
3126       RunDiff());
3127 }
3128 
TEST_F(ComparisonTest,ExtensionTest)3129 TEST_F(ComparisonTest, ExtensionTest) {
3130   proto1ex_.SetExtension(unittest::optional_int32_extension, 401);
3131   proto2ex_.SetExtension(unittest::optional_int32_extension, 402);
3132 
3133   proto1ex_.ClearExtension(unittest::optional_int64_extension);
3134   proto2ex_.SetExtension(unittest::optional_int64_extension, 403);
3135 
3136   EXPECT_EQ(
3137       "modified: (protobuf_unittest.optional_int32_extension): 401 -> 402\n"
3138       "added: (protobuf_unittest.optional_int64_extension): 403\n",
3139       RunEx());
3140 }
3141 
TEST_F(ComparisonTest,MatchedUnknownFieldTagTest)3142 TEST_F(ComparisonTest, MatchedUnknownFieldTagTest) {
3143   unknown1_->AddVarint(240, 122);
3144   unknown2_->AddVarint(240, 121);
3145   unknown1_->AddFixed32(241, 1);
3146   unknown2_->AddFixed64(241, 2);
3147   unknown1_->AddLengthDelimited(242, "cat");
3148   unknown2_->AddLengthDelimited(242, "dog");
3149 
3150   EXPECT_EQ(
3151       "modified: 240[0]: 122 -> 121\n"
3152       "deleted: 241[0]: 0x00000001\n"
3153       "added: 241[0]: 0x0000000000000002\n"
3154       "modified: 242[0]: \"cat\" -> \"dog\"\n",
3155       RunUn());
3156 }
3157 
TEST_F(ComparisonTest,UnmatchedUnknownFieldTagTest)3158 TEST_F(ComparisonTest, UnmatchedUnknownFieldTagTest) {
3159   unknown1_->AddFixed32(243, 1);
3160   unknown2_->AddVarint(244, 2);
3161   unknown2_->AddVarint(244, 4);
3162 
3163   EXPECT_EQ(
3164       "deleted: 243[0]: 0x00000001\n"
3165       "added: 244[0]: 2\n"
3166       "added: 244[1]: 4\n",
3167       RunUn());
3168 }
3169 
TEST_F(ComparisonTest,DifferentSizedUnknownFieldTest)3170 TEST_F(ComparisonTest, DifferentSizedUnknownFieldTest) {
3171   unknown1_->AddVarint(240, 1);
3172   unknown1_->AddVarint(240, 3);
3173   unknown1_->AddVarint(240, 4);
3174   unknown2_->AddVarint(240, 2);
3175   unknown2_->AddVarint(240, 3);
3176   unknown2_->AddVarint(240, 2);
3177   unknown2_->AddVarint(240, 5);
3178 
3179   EXPECT_EQ(
3180       "modified: 240[0]: 1 -> 2\n"
3181       "modified: 240[2]: 4 -> 2\n"
3182       "added: 240[3]: 5\n",
3183       RunUn());
3184 }
3185 
TEST_F(ComparisonTest,UnknownFieldsAll)3186 TEST_F(ComparisonTest, UnknownFieldsAll) {
3187   unknown1_->AddVarint(243, 122);
3188   unknown1_->AddFixed64(244, 0x0172356);
3189   unknown1_->AddFixed64(244, 0x098);
3190   unknown1_->AddGroup(245)->AddFixed32(248, 1);
3191   unknown1_->mutable_field(3)->mutable_group()->AddFixed32(248, 2);
3192   unknown1_->AddGroup(249)->AddFixed64(250, 1);
3193 
3194   unknown2_->AddVarint(243, 121);
3195   unknown2_->AddLengthDelimited(73882, "test 123");
3196   unknown2_->AddGroup(245)->AddFixed32(248, 3);
3197   unknown2_->AddGroup(247);
3198 
3199   EXPECT_EQ(
3200       "modified: 243[0]: 122 -> 121\n"
3201       "deleted: 244[0]: 0x0000000000172356\n"
3202       "deleted: 244[1]: 0x0000000000000098\n"
3203       "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
3204       "deleted: 245[0].248[1]: 0x00000002\n"
3205       "added: 247[0]: { ... }\n"
3206       "deleted: 249[0]: { ... }\n"
3207       "added: 73882[0]: \"test 123\"\n",
3208       RunUn());
3209 }
3210 
TEST_F(ComparisonTest,EquivalentIgnoresUnknown)3211 TEST_F(ComparisonTest, EquivalentIgnoresUnknown) {
3212   unittest::ForeignMessage message1, message2;
3213 
3214   message1.set_c(5);
3215   message1.mutable_unknown_fields()->AddVarint(123, 456);
3216   message2.set_c(5);
3217   message2.mutable_unknown_fields()->AddVarint(321, 654);
3218 
3219   EXPECT_FALSE(util::MessageDifferencer::Equals(message1, message2));
3220   EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2));
3221 }
3222 
TEST_F(ComparisonTest,MapTest)3223 TEST_F(ComparisonTest, MapTest) {
3224   Map<std::string, std::string>& map1 =
3225       *map_proto1_.mutable_map_string_string();
3226   map1["key1"] = "1";
3227   map1["key2"] = "2";
3228   map1["key3"] = "3";
3229   Map<std::string, std::string>& map2 =
3230       *map_proto2_.mutable_map_string_string();
3231   map2["key3"] = "0";
3232   map2["key2"] = "2";
3233   map2["key1"] = "1";
3234 
3235   EXPECT_EQ("modified: map_string_string.value: \"3\" -> \"0\"\n",
3236             Run(map_proto1_, map_proto2_));
3237 }
3238 
TEST_F(ComparisonTest,MapIgnoreKeyTest)3239 TEST_F(ComparisonTest, MapIgnoreKeyTest) {
3240   Map<std::string, std::string>& map1 =
3241       *map_proto1_.mutable_map_string_string();
3242   map1["key1"] = "1";
3243   map1["key2"] = "2";
3244   map1["key3"] = "3";
3245   Map<std::string, std::string>& map2 =
3246       *map_proto2_.mutable_map_string_string();
3247   map2["key4"] = "2";
3248   map2["key5"] = "3";
3249   map2["key6"] = "1";
3250 
3251   util::MessageDifferencer differencer;
3252   differencer.IgnoreField(
3253       GetFieldDescriptor(map_proto1_, "map_string_string.key"));
3254   EXPECT_TRUE(differencer.Compare(map_proto1_, map_proto2_));
3255 }
3256 
TEST_F(ComparisonTest,MapRoundTripSyncTest)3257 TEST_F(ComparisonTest, MapRoundTripSyncTest) {
3258   TextFormat::Parser parser;
3259   unittest::TestMap map_reflection1;
3260 
3261   // By setting via reflection, data exists in repeated field.
3262   ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message { key: 1 }",
3263                                      &map_reflection1));
3264 
3265   // During copy, data is synced from repeated field to map.
3266   unittest::TestMap map_reflection2 = map_reflection1;
3267 
3268   // During comparison, data is synced from map to repeated field.
3269   EXPECT_TRUE(
3270       util::MessageDifferencer::Equals(map_reflection1, map_reflection2));
3271 }
3272 
TEST_F(ComparisonTest,MapEntryPartialTest)3273 TEST_F(ComparisonTest, MapEntryPartialTest) {
3274   TextFormat::Parser parser;
3275   unittest::TestMap map1;
3276   unittest::TestMap map2;
3277 
3278   std::string output;
3279   util::MessageDifferencer differencer;
3280   differencer.set_scope(util::MessageDifferencer::PARTIAL);
3281   differencer.ReportDifferencesToString(&output);
3282 
3283   ASSERT_TRUE(parser.ParseFromString(
3284       "map_int32_foreign_message { key: 1 value { c: 1 } }", &map1));
3285   ASSERT_TRUE(parser.ParseFromString(
3286       "map_int32_foreign_message { key: 1 value { c: 2 }}", &map2));
3287   EXPECT_FALSE(differencer.Compare(map1, map2));
3288   EXPECT_EQ("modified: map_int32_foreign_message.value.c: 1 -> 2\n", output);
3289 
3290   ASSERT_TRUE(
3291       parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map1));
3292   EXPECT_TRUE(differencer.Compare(map1, map2));
3293 }
3294 
TEST_F(ComparisonTest,MapEntryPartialEmptyKeyTest)3295 TEST_F(ComparisonTest, MapEntryPartialEmptyKeyTest) {
3296   TextFormat::Parser parser;
3297   unittest::TestMap map1;
3298   unittest::TestMap map2;
3299   ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message {}", &map1));
3300   ASSERT_TRUE(
3301       parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map2));
3302 
3303   util::MessageDifferencer differencer;
3304   differencer.set_scope(util::MessageDifferencer::PARTIAL);
3305   EXPECT_TRUE(differencer.Compare(map1, map2));
3306 }
3307 
TEST_F(ComparisonTest,MapEntryMissingEmptyFieldIsOkTest)3308 TEST_F(ComparisonTest, MapEntryMissingEmptyFieldIsOkTest) {
3309   TextFormat::Parser parser;
3310   protobuf_unittest::TestMap msg1;
3311   protobuf_unittest::TestMap msg2;
3312 
3313   ASSERT_TRUE(parser.ParseFromString(
3314       "map_string_foreign_message { key: 'key1' value {}}", &msg1));
3315   ASSERT_TRUE(parser.ParseFromString(
3316       "map_string_foreign_message { key: 'key1' }", &msg2));
3317 
3318   util::MessageDifferencer differencer;
3319   differencer.set_scope(util::MessageDifferencer::PARTIAL);
3320 
3321   ASSERT_TRUE(differencer.Compare(msg1, msg2));
3322 }
3323 
3324 // Considers strings keys as equal if they have equal lengths.
3325 class LengthMapKeyComparator
3326     : public util::MessageDifferencer::MapKeyComparator {
3327  public:
3328   typedef util::MessageDifferencer::SpecificField SpecificField;
IsMatch(const Message & message1,const Message & message2,const std::vector<SpecificField> & parent_fields) const3329   virtual bool IsMatch(const Message& message1, const Message& message2,
3330                        const std::vector<SpecificField>& parent_fields) const {
3331     const Reflection* reflection1 = message1.GetReflection();
3332     const Reflection* reflection2 = message2.GetReflection();
3333     const FieldDescriptor* key_field =
3334         message1.GetDescriptor()->FindFieldByName("key");
3335     return reflection1->GetString(message1, key_field).size() ==
3336            reflection2->GetString(message2, key_field).size();
3337   }
3338 };
3339 
TEST_F(ComparisonTest,MapEntryCustomMapKeyComparator)3340 TEST_F(ComparisonTest, MapEntryCustomMapKeyComparator) {
3341   TextFormat::Parser parser;
3342   protobuf_unittest::TestMap msg1;
3343   protobuf_unittest::TestMap msg2;
3344 
3345   ASSERT_TRUE(parser.ParseFromString(
3346       "map_string_foreign_message { key: 'key1' value { c: 1 }}", &msg1));
3347   ASSERT_TRUE(parser.ParseFromString(
3348       "map_string_foreign_message { key: 'key2' value { c: 1 }}", &msg2));
3349 
3350   util::MessageDifferencer differencer;
3351   LengthMapKeyComparator key_comparator;
3352   differencer.TreatAsMapUsingKeyComparator(
3353       GetFieldDescriptor(msg1, "map_string_foreign_message"), &key_comparator);
3354   std::string output;
3355   differencer.ReportDifferencesToString(&output);
3356   // Though the above two messages have different keys for their map entries,
3357   // they are considered the same by key_comparator because their lengths are
3358   // equal.  However, in value comparison, all fields of the message are taken
3359   // into consideration, so they are reported as different.
3360   EXPECT_FALSE(differencer.Compare(msg1, msg2));
3361   EXPECT_EQ("modified: map_string_foreign_message.key: \"key1\" -> \"key2\"\n",
3362             output);
3363   differencer.IgnoreField(
3364       GetFieldDescriptor(msg1, "map_string_foreign_message.key"));
3365   output.clear();
3366   EXPECT_TRUE(differencer.Compare(msg1, msg2));
3367   EXPECT_EQ("ignored: map_string_foreign_message.key\n", output);
3368 }
3369 
3370 class MatchingTest : public testing::Test {
3371  public:
3372   typedef util::MessageDifferencer MessageDifferencer;
3373 
3374  protected:
MatchingTest()3375   MatchingTest() {}
3376 
~MatchingTest()3377   ~MatchingTest() {}
3378 
RunWithResult(MessageDifferencer * differencer,const Message & msg1,const Message & msg2,bool result)3379   std::string RunWithResult(MessageDifferencer* differencer,
3380                             const Message& msg1, const Message& msg2,
3381                             bool result) {
3382     std::string output;
3383     {
3384       // Before we return the "output" string, we must make sure the
3385       // StreamReporter is destructored because its destructor will
3386       // flush the stream.
3387       io::StringOutputStream output_stream(&output);
3388       MessageDifferencer::StreamReporter reporter(&output_stream);
3389       reporter.set_report_modified_aggregates(true);
3390       differencer->set_report_matches(true);
3391       differencer->ReportDifferencesTo(&reporter);
3392       if (result) {
3393         EXPECT_TRUE(differencer->Compare(msg1, msg2));
3394       } else {
3395         EXPECT_FALSE(differencer->Compare(msg1, msg2));
3396       }
3397     }
3398     return output;
3399   }
3400 
3401  private:
3402   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MatchingTest);
3403 };
3404 
TEST_F(MatchingTest,StreamReporterMatching)3405 TEST_F(MatchingTest, StreamReporterMatching) {
3406   protobuf_unittest::TestField msg1, msg2;
3407   msg1.set_c(72);
3408   msg2.set_c(72);
3409   msg1.add_rc(13);
3410   msg2.add_rc(13);
3411   msg1.add_rc(17);
3412   msg2.add_rc(17);
3413   std::string output;
3414   MessageDifferencer differencer;
3415   differencer.set_report_matches(true);
3416   differencer.ReportDifferencesToString(&output);
3417   EXPECT_TRUE(differencer.Compare(msg1, msg2));
3418   EXPECT_EQ(
3419       "matched: c : 72\n"
3420       "matched: rc[0] : 13\n"
3421       "matched: rc[1] : 17\n",
3422       output);
3423 }
3424 
TEST_F(MatchingTest,DontReportMatchedWhenIgnoring)3425 TEST_F(MatchingTest, DontReportMatchedWhenIgnoring) {
3426   protobuf_unittest::TestField msg1, msg2;
3427   msg1.set_c(72);
3428   msg2.set_c(72);
3429   msg1.add_rc(13);
3430   msg2.add_rc(13);
3431   msg1.add_rc(17);
3432   msg2.add_rc(17);
3433   std::string output;
3434   MessageDifferencer differencer;
3435   differencer.set_report_matches(true);
3436   differencer.ReportDifferencesToString(&output);
3437 
3438   differencer.IgnoreField(msg1.GetDescriptor()->FindFieldByName("c"));
3439 
3440   EXPECT_TRUE(differencer.Compare(msg1, msg2));
3441   EXPECT_EQ(
3442       "ignored: c\n"
3443       "matched: rc[0] : 13\n"
3444       "matched: rc[1] : 17\n",
3445       output);
3446 }
3447 
TEST_F(MatchingTest,ReportMatchedForMovedFields)3448 TEST_F(MatchingTest, ReportMatchedForMovedFields) {
3449   protobuf_unittest::TestDiffMessage msg1, msg2;
3450   protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
3451   item->set_a(53);
3452   item->set_b("hello");
3453   item = msg2.add_item();
3454   item->set_a(27);
3455   item = msg2.add_item();
3456   item->set_a(53);
3457   item->set_b("hello");
3458   item = msg1.add_item();
3459   item->set_a(27);
3460   MessageDifferencer differencer;
3461   const FieldDescriptor* desc;
3462   desc = msg1.GetDescriptor()->FindFieldByName("item");
3463   differencer.TreatAsSet(desc);
3464 
3465   EXPECT_EQ(
3466       "matched: item[0].a -> item[1].a : 53\n"
3467       "matched: item[0].b -> item[1].b : \"hello\"\n"
3468       "moved: item[0] -> item[1] : { a: 53 b: \"hello\" }\n"
3469       "matched: item[1].a -> item[0].a : 27\n"
3470       "moved: item[1] -> item[0] : { a: 27 }\n",
3471       RunWithResult(&differencer, msg1, msg2, true));
3472 }
3473 
3474 
TEST_F(MatchingTest,MatchesAppearInPostTraversalOrderForMovedFields)3475 TEST_F(MatchingTest, MatchesAppearInPostTraversalOrderForMovedFields) {
3476   protobuf_unittest::TestDiffMessage msg1, msg2;
3477   protobuf_unittest::TestDiffMessage::Item* item;
3478   protobuf_unittest::TestField* field;
3479 
3480   const FieldDescriptor* desc;
3481   const FieldDescriptor* nested_desc;
3482   const FieldDescriptor* double_nested_desc;
3483   desc = msg1.GetDescriptor()->FindFieldByName("item");
3484   nested_desc = desc->message_type()->FindFieldByName("rm");
3485   double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
3486   MessageDifferencer differencer;
3487   differencer.TreatAsSet(desc);
3488   differencer.TreatAsSet(nested_desc);
3489   differencer.TreatAsSet(double_nested_desc);
3490 
3491   item = msg1.add_item();
3492   field = item->add_rm();
3493   field->set_c(1);
3494   field->add_rc(2);
3495   field->add_rc(3);
3496   field = item->add_rm();
3497   field->set_c(4);
3498   field->add_rc(5);
3499   field->add_rc(6);
3500   field->add_rc(7);
3501   item = msg2.add_item();
3502   field = item->add_rm();
3503   field->set_c(4);
3504   field->add_rc(7);
3505   field->add_rc(6);
3506   field->add_rc(5);
3507   field = item->add_rm();
3508   field->set_c(1);
3509   field->add_rc(3);
3510   field->add_rc(2);
3511   item = msg1.add_item();
3512   field = item->add_rm();
3513   field->set_c(8);
3514   field->add_rc(10);
3515   field->add_rc(11);
3516   field->add_rc(9);
3517   item = msg2.add_item();
3518   field = item->add_rm();
3519   field->set_c(8);
3520   field->add_rc(9);
3521   field->add_rc(10);
3522   field->add_rc(11);
3523 
3524   EXPECT_EQ(
3525       "matched: item[0].rm[0].c -> item[0].rm[1].c : 1\n"
3526       "moved: item[0].rm[0].rc[0] -> item[0].rm[1].rc[1] : 2\n"
3527       "moved: item[0].rm[0].rc[1] -> item[0].rm[1].rc[0] : 3\n"
3528       "moved: item[0].rm[0] -> item[0].rm[1] : { c: 1 rc: 2 rc: 3 }\n"
3529       "matched: item[0].rm[1].c -> item[0].rm[0].c : 4\n"
3530       "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 5\n"
3531       "matched: item[0].rm[1].rc[1] -> item[0].rm[0].rc[1] : 6\n"
3532       "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 7\n"
3533       "moved: item[0].rm[1] -> item[0].rm[0] : { c: 4 rc: 5 rc: 6 rc: 7 }\n"
3534       "matched: item[0] : { rm { c: 1 rc: 2 rc: 3 }"
3535       " rm { c: 4 rc: 5 rc: 6 rc: 7 } }\n"
3536       "matched: item[1].rm[0].c : 8\n"
3537       "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 10\n"
3538       "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[2] : 11\n"
3539       "moved: item[1].rm[0].rc[2] -> item[1].rm[0].rc[0] : 9\n"
3540       "matched: item[1].rm[0] : { c: 8 rc: 10 rc: 11 rc: 9 }\n"
3541       "matched: item[1] : { rm { c: 8 rc: 10 rc: 11 rc: 9 } }\n",
3542       RunWithResult(&differencer, msg1, msg2, true));
3543 }
3544 
TEST_F(MatchingTest,MatchAndModifiedInterleaveProperly)3545 TEST_F(MatchingTest, MatchAndModifiedInterleaveProperly) {
3546   protobuf_unittest::TestDiffMessage msg1, msg2;
3547   protobuf_unittest::TestDiffMessage::Item* item;
3548   protobuf_unittest::TestField* field;
3549 
3550   const FieldDescriptor* desc;
3551   const FieldDescriptor* nested_key;
3552   const FieldDescriptor* nested_desc;
3553   const FieldDescriptor* double_nested_key;
3554   const FieldDescriptor* double_nested_desc;
3555   desc = msg1.GetDescriptor()->FindFieldByName("item");
3556   nested_key = desc->message_type()->FindFieldByName("a");
3557   nested_desc = desc->message_type()->FindFieldByName("rm");
3558   double_nested_key = nested_desc->message_type()->FindFieldByName("c");
3559   double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
3560 
3561   MessageDifferencer differencer;
3562   differencer.TreatAsMap(desc, nested_key);
3563   differencer.TreatAsMap(nested_desc, double_nested_key);
3564   differencer.TreatAsSet(double_nested_desc);
3565 
3566   item = msg1.add_item();
3567   item->set_a(1);
3568   field = item->add_rm();
3569   field->set_c(2);
3570   field->add_rc(3);
3571   field->add_rc(4);
3572   field = item->add_rm();
3573   field->set_c(5);
3574   field->add_rc(6);
3575   field->add_rc(7);
3576   field->add_rc(8);
3577   item = msg1.add_item();
3578   item->set_a(9);
3579   field = item->add_rm();
3580   field->set_c(10);
3581   field->add_rc(11);
3582   field->add_rc(12);
3583   field = item->add_rm();
3584   field->set_c(13);
3585 
3586   item = msg2.add_item();
3587   item->set_a(1);
3588   field = item->add_rm();
3589   field->set_c(5);
3590   field->add_rc(8);
3591   field->add_rc(8);
3592   field->add_rc(6);
3593   field = item->add_rm();
3594   field->set_c(3);
3595   field->add_rc(2);
3596   field->add_rc(4);
3597   item = msg2.add_item();
3598   item->set_a(9);
3599   field = item->add_rm();
3600   field->set_c(10);
3601   field->add_rc(12);
3602   field->add_rc(11);
3603   field = item->add_rm();
3604   field->set_c(13);
3605 
3606   EXPECT_EQ(
3607       "matched: item[0].a : 1\n"
3608       "matched: item[0].rm[1].c -> item[0].rm[0].c : 5\n"
3609       "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 6\n"
3610       "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 8\n"
3611       "added: item[0].rm[0].rc[1]: 8\n"
3612       "deleted: item[0].rm[1].rc[1]: 7\n"
3613       "modified: item[0].rm[1] -> item[0].rm[0]: { c: 5 rc: 6 rc: 7 rc: 8 } ->"
3614       " { c: 5 rc: 8 rc: 8 rc: 6 }\n"
3615       "added: item[0].rm[1]: { c: 3 rc: 2 rc: 4 }\n"
3616       "deleted: item[0].rm[0]: { c: 2 rc: 3 rc: 4 }\n"
3617       "modified: item[0]: { a: 1 rm { c: 2 rc: 3 rc: 4 }"
3618       " rm { c: 5 rc: 6 rc: 7 rc: 8 } } ->"
3619       " { a: 1 rm { c: 5 rc: 8 rc: 8 rc: 6 }"
3620       " rm { c: 3 rc: 2 rc: 4 } }\n"
3621       "matched: item[1].a : 9\n"
3622       "matched: item[1].rm[0].c : 10\n"
3623       "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 11\n"
3624       "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[0] : 12\n"
3625       "matched: item[1].rm[0] : { c: 10 rc: 11 rc: 12 }\n"
3626       "matched: item[1].rm[1].c : 13\n"
3627       "matched: item[1].rm[1] : { c: 13 }\n"
3628       "matched: item[1] : { a: 9 rm { c: 10 rc: 11 rc: 12 } rm { c: 13 } }\n",
3629       RunWithResult(&differencer, msg1, msg2, false));
3630 }
3631 
TEST_F(MatchingTest,MatchingWorksWithExtensions)3632 TEST_F(MatchingTest, MatchingWorksWithExtensions) {
3633   protobuf_unittest::TestAllExtensions msg1, msg2;
3634   protobuf_unittest::TestAllTypes::NestedMessage* nested;
3635   using protobuf_unittest::repeated_nested_message_extension;
3636 
3637   const FileDescriptor* descriptor;
3638   const FieldDescriptor* desc;
3639   const FieldDescriptor* nested_key;
3640   descriptor = msg1.GetDescriptor()->file();
3641   desc = descriptor->FindExtensionByName("repeated_nested_message_extension");
3642   ASSERT_FALSE(desc == NULL);
3643   nested_key = desc->message_type()->FindFieldByName("bb");
3644 
3645   MessageDifferencer differencer;
3646   differencer.TreatAsMap(desc, nested_key);
3647 
3648   nested = msg1.AddExtension(repeated_nested_message_extension);
3649   nested->set_bb(7);
3650   nested = msg1.AddExtension(repeated_nested_message_extension);
3651   nested->set_bb(13);
3652   nested = msg1.AddExtension(repeated_nested_message_extension);
3653   nested->set_bb(11);
3654   nested = msg2.AddExtension(repeated_nested_message_extension);
3655   nested->set_bb(11);
3656   nested = msg2.AddExtension(repeated_nested_message_extension);
3657   nested->set_bb(13);
3658   nested = msg2.AddExtension(repeated_nested_message_extension);
3659   nested->set_bb(7);
3660 
3661   EXPECT_EQ(
3662       "matched: (protobuf_unittest.repeated_nested_message_extension)[0].bb ->"
3663       " (protobuf_unittest.repeated_nested_message_extension)[2].bb : 7\n"
3664       "moved: (protobuf_unittest.repeated_nested_message_extension)[0] ->"
3665       " (protobuf_unittest.repeated_nested_message_extension)[2] :"
3666       " { bb: 7 }\n"
3667       "matched: (protobuf_unittest.repeated_nested_message_extension)[1].bb :"
3668       " 13\n"
3669       "matched: (protobuf_unittest.repeated_nested_message_extension)[1] :"
3670       " { bb: 13 }\n"
3671       "matched: (protobuf_unittest.repeated_nested_message_extension)[2].bb ->"
3672       " (protobuf_unittest.repeated_nested_message_extension)[0].bb :"
3673       " 11\n"
3674       "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
3675       " (protobuf_unittest.repeated_nested_message_extension)[0] :"
3676       " { bb: 11 }\n",
3677       RunWithResult(&differencer, msg1, msg2, true));
3678 }
3679 
TEST(AnyTest,Simple)3680 TEST(AnyTest, Simple) {
3681   protobuf_unittest::TestField value1, value2;
3682   value1.set_a(20);
3683   value2.set_a(21);
3684 
3685   protobuf_unittest::TestAny m1, m2;
3686   m1.mutable_any_value()->PackFrom(value1);
3687   m2.mutable_any_value()->PackFrom(value2);
3688   util::MessageDifferencer message_differencer;
3689   std::string difference_string;
3690   message_differencer.ReportDifferencesToString(&difference_string);
3691   EXPECT_FALSE(message_differencer.Compare(m1, m2));
3692   EXPECT_EQ("modified: any_value.a: 20 -> 21\n", difference_string);
3693 }
3694 
TEST(Anytest,TreatAsSet)3695 TEST(Anytest, TreatAsSet) {
3696   protobuf_unittest::TestField value1, value2;
3697   value1.set_a(20);
3698   value1.set_b(30);
3699   value2.set_a(20);
3700   value2.set_b(31);
3701 
3702   protobuf_unittest::TestAny m1, m2;
3703   m1.add_repeated_any_value()->PackFrom(value1);
3704   m1.add_repeated_any_value()->PackFrom(value2);
3705   m2.add_repeated_any_value()->PackFrom(value2);
3706   m2.add_repeated_any_value()->PackFrom(value1);
3707 
3708   util::MessageDifferencer message_differencer;
3709   message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
3710   EXPECT_TRUE(message_differencer.Compare(m1, m2));
3711 }
3712 
TEST(Anytest,TreatAsSet_DifferentType)3713 TEST(Anytest, TreatAsSet_DifferentType) {
3714   protobuf_unittest::TestField value1;
3715   value1.set_a(20);
3716   value1.set_b(30);
3717   protobuf_unittest::TestDiffMessage value2;
3718   value2.add_rv(40);
3719 
3720   protobuf_unittest::TestAny m1, m2;
3721   m1.add_repeated_any_value()->PackFrom(value1);
3722   m1.add_repeated_any_value()->PackFrom(value2);
3723   m2.add_repeated_any_value()->PackFrom(value2);
3724   m2.add_repeated_any_value()->PackFrom(value1);
3725 
3726   util::MessageDifferencer message_differencer;
3727   message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
3728   EXPECT_TRUE(message_differencer.Compare(m1, m2));
3729 }
3730 
3731 
3732 }  // namespace
3733 }  // namespace protobuf
3734 }  // namespace google
3735