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: ksroka@google.com (Krzysztof Sroka)
32 
33 #include <google/protobuf/util/field_comparator.h>
34 
35 #include <google/protobuf/unittest.pb.h>
36 #include <google/protobuf/descriptor.h>
37 #include <google/protobuf/stubs/mathutil.h>
38 // This gtest header is put after mathutil.h intentionally. We have to do
39 // this because mathutil.h includes mathlimits.h which requires cmath not
40 // being included to compile on some versions of gcc:
41 //   https://github.com/protocolbuffers/protobuf/blob/818c5eee08840355d70d2f3bdf1a2f17986a5e70/src/google/protobuf/stubs/mathlimits.h#L48
42 // and the opensource version gtest.h header includes cmath transitively
43 // somehow.
44 #include <gtest/gtest.h>
45 namespace google {
46 namespace protobuf {
47 namespace util {
48 namespace {
49 
50 using protobuf_unittest::TestAllTypes;
51 
52 class DefaultFieldComparatorTest : public ::testing::Test {
53  protected:
SetUp()54   void SetUp() { descriptor_ = TestAllTypes::descriptor(); }
55 
56   const Descriptor* descriptor_;
57   DefaultFieldComparator comparator_;
58   TestAllTypes message_1_;
59   TestAllTypes message_2_;
60 };
61 
TEST_F(DefaultFieldComparatorTest,RecursesIntoGroup)62 TEST_F(DefaultFieldComparatorTest, RecursesIntoGroup) {
63   const FieldDescriptor* field = descriptor_->FindFieldByName("optionalgroup");
64   EXPECT_EQ(FieldComparator::RECURSE,
65             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
66 }
67 
TEST_F(DefaultFieldComparatorTest,RecursesIntoNestedMessage)68 TEST_F(DefaultFieldComparatorTest, RecursesIntoNestedMessage) {
69   const FieldDescriptor* field =
70       descriptor_->FindFieldByName("optional_nested_message");
71   EXPECT_EQ(FieldComparator::RECURSE,
72             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
73 }
74 
TEST_F(DefaultFieldComparatorTest,RecursesIntoForeignMessage)75 TEST_F(DefaultFieldComparatorTest, RecursesIntoForeignMessage) {
76   const FieldDescriptor* field =
77       descriptor_->FindFieldByName("optional_foreign_message");
78   EXPECT_EQ(FieldComparator::RECURSE,
79             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
80 }
81 
TEST_F(DefaultFieldComparatorTest,Int32Comparison)82 TEST_F(DefaultFieldComparatorTest, Int32Comparison) {
83   const FieldDescriptor* field = descriptor_->FindFieldByName("optional_int32");
84   message_1_.set_optional_int32(1);
85   message_2_.set_optional_int32(1);
86 
87   EXPECT_EQ(FieldComparator::SAME,
88             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
89 
90   message_2_.set_optional_int32(-1);
91   EXPECT_EQ(FieldComparator::DIFFERENT,
92             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
93 }
94 
TEST_F(DefaultFieldComparatorTest,Int64Comparison)95 TEST_F(DefaultFieldComparatorTest, Int64Comparison) {
96   const FieldDescriptor* field = descriptor_->FindFieldByName("optional_int64");
97   message_1_.set_optional_int64(1L);
98   message_2_.set_optional_int64(1L);
99 
100   EXPECT_EQ(FieldComparator::SAME,
101             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
102 
103   message_2_.set_optional_int64(-1L);
104   EXPECT_EQ(FieldComparator::DIFFERENT,
105             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
106 }
107 
TEST_F(DefaultFieldComparatorTest,UInt32Comparison)108 TEST_F(DefaultFieldComparatorTest, UInt32Comparison) {
109   const FieldDescriptor* field =
110       descriptor_->FindFieldByName("optional_uint32");
111   message_1_.set_optional_uint32(1);
112   message_2_.set_optional_uint32(1);
113 
114   EXPECT_EQ(FieldComparator::SAME,
115             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
116 
117   message_2_.set_optional_uint32(2);
118   EXPECT_EQ(FieldComparator::DIFFERENT,
119             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
120 }
121 
TEST_F(DefaultFieldComparatorTest,UInt64Comparison)122 TEST_F(DefaultFieldComparatorTest, UInt64Comparison) {
123   const FieldDescriptor* field =
124       descriptor_->FindFieldByName("optional_uint64");
125   message_1_.set_optional_uint64(1L);
126   message_2_.set_optional_uint64(1L);
127 
128   EXPECT_EQ(FieldComparator::SAME,
129             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
130 
131   message_2_.set_optional_uint64(2L);
132   EXPECT_EQ(FieldComparator::DIFFERENT,
133             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
134 }
135 
TEST_F(DefaultFieldComparatorTest,BooleanComparison)136 TEST_F(DefaultFieldComparatorTest, BooleanComparison) {
137   const FieldDescriptor* field = descriptor_->FindFieldByName("optional_bool");
138   message_1_.set_optional_bool(true);
139   message_2_.set_optional_bool(true);
140 
141   EXPECT_EQ(FieldComparator::SAME,
142             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
143 
144   message_2_.set_optional_bool(false);
145   EXPECT_EQ(FieldComparator::DIFFERENT,
146             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
147 }
148 
TEST_F(DefaultFieldComparatorTest,EnumComparison)149 TEST_F(DefaultFieldComparatorTest, EnumComparison) {
150   const FieldDescriptor* field =
151       descriptor_->FindFieldByName("optional_nested_enum");
152   message_1_.set_optional_nested_enum(TestAllTypes::BAR);
153   message_2_.set_optional_nested_enum(TestAllTypes::BAR);
154 
155   EXPECT_EQ(FieldComparator::SAME,
156             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
157 
158   message_2_.set_optional_nested_enum(TestAllTypes::BAZ);
159   EXPECT_EQ(FieldComparator::DIFFERENT,
160             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
161 }
162 
TEST_F(DefaultFieldComparatorTest,StringComparison)163 TEST_F(DefaultFieldComparatorTest, StringComparison) {
164   const FieldDescriptor* field =
165       descriptor_->FindFieldByName("optional_string");
166   message_1_.set_optional_string("foo");
167   message_2_.set_optional_string("foo");
168 
169   EXPECT_EQ(FieldComparator::SAME,
170             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
171 
172   message_2_.set_optional_string("bar");
173   EXPECT_EQ(FieldComparator::DIFFERENT,
174             comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
175 }
176 
TEST_F(DefaultFieldComparatorTest,FloatingPointComparisonExact)177 TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonExact) {
178   const FieldDescriptor* field_float =
179       descriptor_->FindFieldByName("optional_float");
180   const FieldDescriptor* field_double =
181       descriptor_->FindFieldByName("optional_double");
182 
183   message_1_.set_optional_float(0.1f);
184   message_2_.set_optional_float(0.1f);
185   message_1_.set_optional_double(0.1);
186   message_2_.set_optional_double(0.1);
187 
188   EXPECT_EQ(
189       FieldComparator::SAME,
190       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
191   EXPECT_EQ(
192       FieldComparator::SAME,
193       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
194 
195   message_2_.set_optional_float(0.2f);
196   message_2_.set_optional_double(0.2);
197 
198   EXPECT_EQ(
199       FieldComparator::DIFFERENT,
200       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
201   EXPECT_EQ(
202       FieldComparator::DIFFERENT,
203       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
204 }
205 
TEST_F(DefaultFieldComparatorTest,FloatingPointComparisonApproximate)206 TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonApproximate) {
207   const FieldDescriptor* field_float =
208       descriptor_->FindFieldByName("optional_float");
209   const FieldDescriptor* field_double =
210       descriptor_->FindFieldByName("optional_double");
211 
212   message_1_.set_optional_float(2.300005f);
213   message_2_.set_optional_float(2.300006f);
214   message_1_.set_optional_double(2.3000000000000003);
215   message_2_.set_optional_double(2.3000000000000007);
216 
217   // Approximate comparison depends on MathUtil, so we assert on MathUtil
218   // results first to check if that's where the failure was introduced.
219   ASSERT_NE(message_1_.optional_float(), message_2_.optional_float());
220   ASSERT_NE(message_1_.optional_double(), message_2_.optional_double());
221   ASSERT_TRUE(MathUtil::AlmostEquals(message_1_.optional_float(),
222                                      message_2_.optional_float()));
223   ASSERT_TRUE(MathUtil::AlmostEquals(message_1_.optional_double(),
224                                      message_2_.optional_double()));
225 
226   // DefaultFieldComparator's default float comparison mode is EXACT.
227   ASSERT_EQ(DefaultFieldComparator::EXACT, comparator_.float_comparison());
228   EXPECT_EQ(
229       FieldComparator::DIFFERENT,
230       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
231   EXPECT_EQ(
232       FieldComparator::DIFFERENT,
233       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
234 
235   comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
236 
237   EXPECT_EQ(
238       FieldComparator::SAME,
239       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
240   EXPECT_EQ(
241       FieldComparator::SAME,
242       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
243 }
244 
TEST_F(DefaultFieldComparatorTest,FloatingPointComparisonTreatNaNsAsEqual)245 TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonTreatNaNsAsEqual) {
246   const FieldDescriptor* field_float =
247       descriptor_->FindFieldByName("optional_float");
248   const FieldDescriptor* field_double =
249       descriptor_->FindFieldByName("optional_double");
250 
251   message_1_.set_optional_float(MathLimits<float>::kNaN);
252   message_2_.set_optional_float(MathLimits<float>::kNaN);
253   message_1_.set_optional_double(MathLimits<double>::kNaN);
254   message_2_.set_optional_double(MathLimits<double>::kNaN);
255 
256   // DefaultFieldComparator's default float comparison mode is EXACT with
257   // treating NaNs as different.
258   ASSERT_EQ(DefaultFieldComparator::EXACT, comparator_.float_comparison());
259   ASSERT_EQ(false, comparator_.treat_nan_as_equal());
260   EXPECT_EQ(
261       FieldComparator::DIFFERENT,
262       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
263   EXPECT_EQ(
264       FieldComparator::DIFFERENT,
265       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
266   comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
267   EXPECT_EQ(
268       FieldComparator::DIFFERENT,
269       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
270   EXPECT_EQ(
271       FieldComparator::DIFFERENT,
272       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
273 
274   comparator_.set_treat_nan_as_equal(true);
275   ASSERT_EQ(true, comparator_.treat_nan_as_equal());
276   comparator_.set_float_comparison(DefaultFieldComparator::EXACT);
277   EXPECT_EQ(
278       FieldComparator::SAME,
279       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
280   EXPECT_EQ(
281       FieldComparator::SAME,
282       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
283   comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
284   EXPECT_EQ(
285       FieldComparator::SAME,
286       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
287   EXPECT_EQ(
288       FieldComparator::SAME,
289       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
290 }
291 
TEST_F(DefaultFieldComparatorTest,FloatingPointComparisonWithinFractionOrMargin)292 TEST_F(DefaultFieldComparatorTest,
293        FloatingPointComparisonWithinFractionOrMargin) {
294   const FieldDescriptor* field_float =
295       descriptor_->FindFieldByName("optional_float");
296   const FieldDescriptor* field_double =
297       descriptor_->FindFieldByName("optional_double");
298 
299   message_1_.set_optional_float(100.0f);
300   message_2_.set_optional_float(109.9f);
301   message_1_.set_optional_double(100.0);
302   message_2_.set_optional_double(109.9);
303 
304   comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
305   EXPECT_EQ(
306       FieldComparator::DIFFERENT,
307       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
308   EXPECT_EQ(
309       FieldComparator::DIFFERENT,
310       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
311 
312   // Should fail since the fraction is too low.
313   comparator_.SetFractionAndMargin(field_float, 0.01, 0.0);
314   comparator_.SetFractionAndMargin(field_double, 0.01, 0.0);
315 
316   EXPECT_EQ(
317       FieldComparator::DIFFERENT,
318       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
319   EXPECT_EQ(
320       FieldComparator::DIFFERENT,
321       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
322 
323   // Should fail since the margin is too low.
324   comparator_.SetFractionAndMargin(field_float, 0.0, 9.0);
325   comparator_.SetFractionAndMargin(field_double, 0.0, 9.0);
326   EXPECT_EQ(
327       FieldComparator::DIFFERENT,
328       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
329   EXPECT_EQ(
330       FieldComparator::DIFFERENT,
331       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
332 
333   // Should succeed since the fraction is high enough.
334   comparator_.SetFractionAndMargin(field_float, 0.2, 0.0);
335   comparator_.SetFractionAndMargin(field_double, 0.2, 0.0);
336   EXPECT_EQ(
337       FieldComparator::SAME,
338       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
339   EXPECT_EQ(
340       FieldComparator::SAME,
341       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
342 
343   // Should succeed since the margin is high enough.
344   comparator_.SetFractionAndMargin(field_float, 0.0, 10.0);
345   comparator_.SetFractionAndMargin(field_double, 0.0, 10.0);
346   EXPECT_EQ(
347       FieldComparator::SAME,
348       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
349   EXPECT_EQ(
350       FieldComparator::SAME,
351       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
352 
353   // Setting values for one of the fields should not affect the other.
354   comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
355   EXPECT_EQ(
356       FieldComparator::SAME,
357       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
358   EXPECT_EQ(
359       FieldComparator::DIFFERENT,
360       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
361 
362   // +inf should be equal even though they are not technically within margin or
363   // fraction.
364   message_1_.set_optional_float(std::numeric_limits<float>::infinity());
365   message_2_.set_optional_float(std::numeric_limits<float>::infinity());
366   message_1_.set_optional_double(std::numeric_limits<double>::infinity());
367   message_2_.set_optional_double(std::numeric_limits<double>::infinity());
368   comparator_.SetFractionAndMargin(field_float, 0.0, 0.0);
369   comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
370   EXPECT_EQ(
371       FieldComparator::SAME,
372       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
373   EXPECT_EQ(
374       FieldComparator::SAME,
375       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
376 
377   // -inf should be equal even though they are not technically within margin or
378   // fraction.
379   message_1_.set_optional_float(-std::numeric_limits<float>::infinity());
380   message_2_.set_optional_float(-std::numeric_limits<float>::infinity());
381   message_1_.set_optional_double(-std::numeric_limits<double>::infinity());
382   message_2_.set_optional_double(-std::numeric_limits<double>::infinity());
383   comparator_.SetFractionAndMargin(field_float, 0.0, 0.0);
384   comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
385   EXPECT_EQ(
386       FieldComparator::SAME,
387       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
388   EXPECT_EQ(
389       FieldComparator::SAME,
390       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
391 
392   // Finite values and inf should not be equal, even for a positive fraction.
393   message_1_.set_optional_float(std::numeric_limits<float>::infinity());
394   message_2_.set_optional_float(0.0f);
395   message_1_.set_optional_double(std::numeric_limits<double>::infinity());
396   message_2_.set_optional_double(0.0);
397   comparator_.SetFractionAndMargin(field_float, 0.1, 0.0);
398   comparator_.SetFractionAndMargin(field_double, 0.1, 0.0);
399   EXPECT_EQ(FieldComparator::DIFFERENT,
400             comparator_.Compare(message_1_, message_2_, field_float, -1, -1,
401                                 nullptr));
402   EXPECT_EQ(FieldComparator::DIFFERENT,
403             comparator_.Compare(message_1_, message_2_, field_double, -1, -1,
404                                 nullptr));
405 }
406 
TEST_F(DefaultFieldComparatorTest,FloatingPointComparisonWithinDefaultFractionOrMargin)407 TEST_F(DefaultFieldComparatorTest,
408        FloatingPointComparisonWithinDefaultFractionOrMargin) {
409   const FieldDescriptor* field_float =
410       descriptor_->FindFieldByName("optional_float");
411   const FieldDescriptor* field_double =
412       descriptor_->FindFieldByName("optional_double");
413 
414   message_1_.set_optional_float(100.0f);
415   message_2_.set_optional_float(109.9f);
416   message_1_.set_optional_double(100.0);
417   message_2_.set_optional_double(109.9);
418 
419   comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
420   EXPECT_EQ(
421       FieldComparator::DIFFERENT,
422       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
423   EXPECT_EQ(
424       FieldComparator::DIFFERENT,
425       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
426 
427   // Set default fraction and margin.
428   comparator_.SetDefaultFractionAndMargin(0.01, 0.0);
429 
430   // Float comparisons should fail since the fraction is too low.
431   EXPECT_EQ(
432       FieldComparator::DIFFERENT,
433       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
434   EXPECT_EQ(
435       FieldComparator::DIFFERENT,
436       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
437 
438   // Set field-specific fraction and margin for one field (field_float) but not
439   // the other (field_double)
440   comparator_.SetFractionAndMargin(field_float, 0.2, 0.0);
441 
442   // The field with the override should succeed, since its field-specific
443   // fraction is high enough.
444   EXPECT_EQ(
445       FieldComparator::SAME,
446       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
447   // The field with no override should fail, since the default fraction is too
448   // low
449   EXPECT_EQ(
450       FieldComparator::DIFFERENT,
451       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
452 
453   // Set the default fraction and margin high enough so that fields that use
454   // the default should succeed
455   comparator_.SetDefaultFractionAndMargin(0.2, 0.0);
456   EXPECT_EQ(
457       FieldComparator::SAME,
458       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
459 
460   // The field with an override should still be OK
461   EXPECT_EQ(
462       FieldComparator::SAME,
463       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
464 
465   // Set fraction and margin for the field with an override to be too low
466   comparator_.SetFractionAndMargin(field_float, 0.01, 0.0);
467 
468   // Now our default is high enough but field_float's override is too low.
469   EXPECT_EQ(
470       FieldComparator::DIFFERENT,
471       comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
472   EXPECT_EQ(
473       FieldComparator::SAME,
474       comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
475 }
476 
477 // Simple test checking whether we compare values at correct indices.
TEST_F(DefaultFieldComparatorTest,RepeatedFieldComparison)478 TEST_F(DefaultFieldComparatorTest, RepeatedFieldComparison) {
479   const FieldDescriptor* field =
480       descriptor_->FindFieldByName("repeated_string");
481 
482   message_1_.add_repeated_string("foo");
483   message_1_.add_repeated_string("bar");
484   message_2_.add_repeated_string("bar");
485   message_2_.add_repeated_string("baz");
486 
487   EXPECT_EQ(FieldComparator::DIFFERENT,
488             comparator_.Compare(message_1_, message_2_, field, 0, 0, NULL));
489   EXPECT_EQ(FieldComparator::DIFFERENT,
490             comparator_.Compare(message_1_, message_2_, field, 1, 1, NULL));
491   EXPECT_EQ(FieldComparator::SAME,
492             comparator_.Compare(message_1_, message_2_, field, 1, 0, NULL));
493 }
494 
495 }  // namespace
496 }  // namespace util
497 }  // namespace protobuf
498 }  // namespace google
499