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