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