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