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