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