field_comparator_test.cc
Go to the documentation of this file.
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 
34 
35 #include <google/protobuf/unittest.pb.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:
54  void SetUp() { descriptor_ = TestAllTypes::descriptor(); }
55 
57  DefaultFieldComparator comparator_;
58  TestAllTypes message_1_;
59  TestAllTypes message_2_;
60 };
61 
62 TEST_F(DefaultFieldComparatorTest, RecursesIntoGroup) {
63  const FieldDescriptor* field = descriptor_->FindFieldByName("optionalgroup");
66 }
67 
68 TEST_F(DefaultFieldComparatorTest, RecursesIntoNestedMessage) {
69  const FieldDescriptor* field =
70  descriptor_->FindFieldByName("optional_nested_message");
73 }
74 
75 TEST_F(DefaultFieldComparatorTest, RecursesIntoForeignMessage) {
76  const FieldDescriptor* field =
77  descriptor_->FindFieldByName("optional_foreign_message");
80 }
81 
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 
89 
90  message_2_.set_optional_int32(-1);
93 }
94 
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 
102 
103  message_2_.set_optional_int64(-1L);
106 }
107 
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 
116 
117  message_2_.set_optional_uint32(2);
120 }
121 
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 
130 
131  message_2_.set_optional_uint64(2L);
134 }
135 
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 
143 
144  message_2_.set_optional_bool(false);
147 }
148 
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 
157 
158  message_2_.set_optional_nested_enum(TestAllTypes::BAZ);
161 }
162 
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 
171 
172  message_2_.set_optional_string("bar");
175 }
176 
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(
190  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
191  EXPECT_EQ(
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(
200  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
201  EXPECT_EQ(
203  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
204 }
205 
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());
222  message_2_.optional_float()));
224  message_2_.optional_double()));
225 
226  // DefaultFieldComparator's default float comparison mode is EXACT.
228  EXPECT_EQ(
230  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
231  EXPECT_EQ(
233  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
234 
236 
237  EXPECT_EQ(
239  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
240  EXPECT_EQ(
242  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
243 }
244 
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.
260  EXPECT_EQ(
262  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
263  EXPECT_EQ(
265  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
267  EXPECT_EQ(
269  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
270  EXPECT_EQ(
272  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
273 
277  EXPECT_EQ(
279  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
280  EXPECT_EQ(
282  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
284  EXPECT_EQ(
286  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
287  EXPECT_EQ(
289  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
290 }
291 
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 
305  EXPECT_EQ(
307  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
308  EXPECT_EQ(
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(
318  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
319  EXPECT_EQ(
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(
328  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
329  EXPECT_EQ(
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(
338  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
339  EXPECT_EQ(
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(
348  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
349  EXPECT_EQ(
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(
357  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
358  EXPECT_EQ(
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(
372  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
373  EXPECT_EQ(
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(
387  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
388  EXPECT_EQ(
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);
400  comparator_.Compare(message_1_, message_2_, field_float, -1, -1,
401  nullptr));
403  comparator_.Compare(message_1_, message_2_, field_double, -1, -1,
404  nullptr));
405 }
406 
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 
420  EXPECT_EQ(
422  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
423  EXPECT_EQ(
425  comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
426 
427  // Set default fraction and margin.
429 
430  // Float comparisons should fail since the fraction is too low.
431  EXPECT_EQ(
433  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
434  EXPECT_EQ(
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(
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(
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
456  EXPECT_EQ(
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(
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(
471  comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
472  EXPECT_EQ(
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.
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 
493 }
494 
495 } // namespace
496 } // namespace util
497 } // namespace protobuf
498 } // namespace google
ASSERT_NE
#define ASSERT_NE(val1, val2)
Definition: gtest.h:2086
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::util::DefaultFieldComparator::set_treat_nan_as_equal
void set_treat_nan_as_equal(bool treat_nan_as_equal)
Definition: field_comparator.h:130
gtest.h
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
google::protobuf::util::FieldComparator::DIFFERENT
@ DIFFERENT
Definition: field_comparator.h:68
google::protobuf::util::FieldComparator::RECURSE
@ RECURSE
Definition: field_comparator.h:71
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::util::FieldComparator::SAME
@ SAME
Definition: field_comparator.h:66
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
testing::Test
Definition: gtest.h:415
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:2082
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
google::protobuf::util::DefaultFieldComparator::EXACT
@ EXACT
Definition: field_comparator.h:103
google::protobuf::util::DefaultFieldComparator::SetFractionAndMargin
void SetFractionAndMargin(const FieldDescriptor *field, double fraction, double margin)
Definition: field_comparator.cc:144
message_1_
TestAllTypes message_1_
Definition: field_comparator_test.cc:58
mathutil.h
comparator_
DefaultFieldComparator comparator_
Definition: field_comparator_test.cc:57
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: gtest.h:1995
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::MathLimits::kNaN
static const Type kNaN
Definition: mathlimits.h:118
google::protobuf::util::DefaultFieldComparator::SetDefaultFractionAndMargin
void SetDefaultFractionAndMargin(double fraction, double margin)
Definition: field_comparator.cc:138
google::protobuf::MathUtil::AlmostEquals
static bool AlmostEquals(T a, T b)
Definition: mathutil.h:69
google::protobuf::TEST_F
TEST_F(DynamicMessageTest, Descriptor)
Definition: dynamic_message_unittest.cc:126
message_2_
TestAllTypes message_2_
Definition: field_comparator_test.cc:59
field_comparator.h
descriptor.h
google::protobuf::util::DefaultFieldComparator::Compare
ComparisonResult Compare(const Message &message_1, const Message &message_2, const FieldDescriptor *field, int index_1, int index_2, const util::FieldContext *field_context) override
Definition: field_comparator.cc:58
google::protobuf::util::DefaultFieldComparator::set_float_comparison
void set_float_comparison(FloatComparison float_comparison)
Definition: field_comparator.h:121
f
GLfloat f
Definition: glcorearb.h:3964
descriptor_
const Descriptor * descriptor_
Definition: field_comparator_test.cc:56
google::protobuf::util::DefaultFieldComparator::APPROXIMATE
@ APPROXIMATE
Definition: field_comparator.h:104
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::util::DefaultFieldComparator::float_comparison
FloatComparison float_comparison() const
Definition: field_comparator.h:125
google::protobuf::util::DefaultFieldComparator::treat_nan_as_equal
bool treat_nan_as_equal() const
Definition: field_comparator.h:134


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:51