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