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