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