field_mask_util_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 
32 
33 #include <algorithm>
34 
39 #include <google/protobuf/unittest.pb.h>
40 #include <gtest/gtest.h>
41 
42 namespace google {
43 namespace protobuf {
44 namespace util {
45 
47  protected:
51  return output;
52  } else {
53  return "#FAIL#";
54  }
55  }
56 
60  return output;
61  } else {
62  return "#FAIL#";
63  }
64  }
65 };
66 
67 namespace {
68 
69 TEST_F(SnakeCaseCamelCaseTest, SnakeToCamel) {
70  EXPECT_EQ("fooBar", SnakeCaseToCamelCase("foo_bar"));
71  EXPECT_EQ("FooBar", SnakeCaseToCamelCase("_foo_bar"));
72  EXPECT_EQ("foo3Bar", SnakeCaseToCamelCase("foo3_bar"));
73  // No uppercase letter is allowed.
74  EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("Foo"));
75  // Any character after a "_" must be a lowercase letter.
76  // 1. "_" cannot be followed by another "_".
77  // 2. "_" cannot be followed by a digit.
78  // 3. "_" cannot appear as the last character.
79  EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo__bar"));
80  EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_3bar"));
81  EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_bar_"));
82 }
83 
84 TEST_F(SnakeCaseCamelCaseTest, CamelToSnake) {
85  EXPECT_EQ("foo_bar", CamelCaseToSnakeCase("fooBar"));
86  EXPECT_EQ("_foo_bar", CamelCaseToSnakeCase("FooBar"));
87  EXPECT_EQ("foo3_bar", CamelCaseToSnakeCase("foo3Bar"));
88  // "_"s are not allowed.
89  EXPECT_EQ("#FAIL#", CamelCaseToSnakeCase("foo_bar"));
90 }
91 
92 TEST_F(SnakeCaseCamelCaseTest, RoundTripTest) {
93  // Enumerates all possible snake_case names and test that converting it to
94  // camelCase and then to snake_case again will yield the original name.
95  std::string name = "___abc123";
96  std::sort(name.begin(), name.end());
97  do {
98  std::string camelName = SnakeCaseToCamelCase(name);
99  if (camelName != "#FAIL#") {
100  EXPECT_EQ(name, CamelCaseToSnakeCase(camelName));
101  }
102  } while (std::next_permutation(name.begin(), name.end()));
103 
104  // Enumerates all possible camelCase names and test that converting it to
105  // snake_case and then to camelCase again will yield the original name.
106  name = "abcABC123";
107  std::sort(name.begin(), name.end());
108  do {
109  std::string camelName = CamelCaseToSnakeCase(name);
110  if (camelName != "#FAIL#") {
111  EXPECT_EQ(name, SnakeCaseToCamelCase(camelName));
112  }
113  } while (std::next_permutation(name.begin(), name.end()));
114 }
115 
117 using protobuf_unittest::NestedTestAllTypes;
118 using protobuf_unittest::TestAllTypes;
119 using protobuf_unittest::TestRequired;
120 using protobuf_unittest::TestRequiredMessage;
121 
122 TEST(FieldMaskUtilTest, StringFormat) {
123  FieldMask mask;
125  mask.add_paths("foo_bar");
127  mask.add_paths("baz_quz");
128  EXPECT_EQ("foo_bar,baz_quz", FieldMaskUtil::ToString(mask));
129 
131  EXPECT_EQ(0, mask.paths_size());
132  FieldMaskUtil::FromString("fooBar", &mask);
133  EXPECT_EQ(1, mask.paths_size());
134  EXPECT_EQ("fooBar", mask.paths(0));
135  FieldMaskUtil::FromString("fooBar,bazQuz", &mask);
136  EXPECT_EQ(2, mask.paths_size());
137  EXPECT_EQ("fooBar", mask.paths(0));
138  EXPECT_EQ("bazQuz", mask.paths(1));
139 }
140 
141 TEST(FieldMaskUtilTest, JsonStringFormat) {
142  FieldMask mask;
145  EXPECT_EQ("", value);
146  mask.add_paths("foo_bar");
148  EXPECT_EQ("fooBar", value);
149  mask.add_paths("bar_quz");
151  EXPECT_EQ("fooBar,barQuz", value);
152 
154  EXPECT_EQ(0, mask.paths_size());
156  EXPECT_EQ(1, mask.paths_size());
157  EXPECT_EQ("foo_bar", mask.paths(0));
158  FieldMaskUtil::FromJsonString("fooBar,bazQuz", &mask);
159  EXPECT_EQ(2, mask.paths_size());
160  EXPECT_EQ("foo_bar", mask.paths(0));
161  EXPECT_EQ("baz_quz", mask.paths(1));
162 }
163 
164 TEST(FieldMaskUtilTest, GetFieldDescriptors) {
165  std::vector<const FieldDescriptor*> field_descriptors;
167  TestAllTypes::descriptor(), "optional_int32", &field_descriptors));
168  EXPECT_EQ(1, field_descriptors.size());
169  EXPECT_EQ("optional_int32", field_descriptors[0]->name());
171  TestAllTypes::descriptor(), "optional_nonexist", nullptr));
173  "optional_nested_message.bb",
174  &field_descriptors));
175  EXPECT_EQ(2, field_descriptors.size());
176  EXPECT_EQ("optional_nested_message", field_descriptors[0]->name());
177  EXPECT_EQ("bb", field_descriptors[1]->name());
179  TestAllTypes::descriptor(), "optional_nested_message.nonexist", nullptr));
180  // FieldMask cannot be used to specify sub-fields of a repeated message.
182  TestAllTypes::descriptor(), "repeated_nested_message.bb", nullptr));
183 }
184 
185 TEST(FieldMaskUtilTest, TestIsVaildPath) {
186  EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
187  EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
188  EXPECT_TRUE(
189  FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
190  EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
191  "optional_nested_message.nonexist"));
192  // FieldMask cannot be used to specify sub-fields of a repeated message.
193  EXPECT_FALSE(
194  FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
195 }
196 
197 TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
198  FieldMask mask;
199  FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
200  EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
201 
203  "optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
204  EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
205 }
206 
207 TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
208  FieldMask mask;
209  mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>();
210  EXPECT_EQ(1, mask.paths_size());
212 
213  mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>();
214  EXPECT_EQ(75, mask.paths_size());
221  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
222  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
223  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
224  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
230  EXPECT_TRUE(
231  FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
232  EXPECT_TRUE(
233  FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
234  EXPECT_TRUE(
235  FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
236  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
237  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
238  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
245  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
246  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
247  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
248  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
254  EXPECT_TRUE(
255  FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
256  EXPECT_TRUE(
257  FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
258  EXPECT_TRUE(
259  FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
260  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
261  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
262  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
263 }
264 
265 TEST(FieldMaskUtilTest, TestToCanonicalForm) {
266  FieldMask in, out;
267  // Paths will be sorted.
268  FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
270  EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
271  // Duplicated paths will be removed.
272  FieldMaskUtil::FromString("foo,bar,foo", &in);
274  EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
275  // Sub-paths of other paths will be removed.
276  FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
278  EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
279 
280  // Test more deeply nested cases.
282  "foo.bar.baz1,"
283  "foo.bar.baz2.quz,"
284  "foo.bar.baz2",
285  &in);
287  EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
289  "foo.bar.baz1,"
290  "foo.bar.baz2,"
291  "foo.bar.baz2.quz",
292  &in);
294  EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
296  "foo.bar.baz1,"
297  "foo.bar.baz2,"
298  "foo.bar.baz2.quz,"
299  "foo.bar",
300  &in);
302  EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
304  "foo.bar.baz1,"
305  "foo.bar.baz2,"
306  "foo.bar.baz2.quz,"
307  "foo",
308  &in);
310  EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
311 }
312 
313 TEST(FieldMaskUtilTest, TestUnion) {
314  FieldMask mask1, mask2, out;
315  // Test cases without overlapping.
316  FieldMaskUtil::FromString("foo,baz", &mask1);
317  FieldMaskUtil::FromString("bar,quz", &mask2);
318  FieldMaskUtil::Union(mask1, mask2, &out);
319  EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
320  // Overlap with duplicated paths.
321  FieldMaskUtil::FromString("foo,baz.bb", &mask1);
322  FieldMaskUtil::FromString("baz.bb,quz", &mask2);
323  FieldMaskUtil::Union(mask1, mask2, &out);
324  EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
325  // Overlap with paths covering some other paths.
326  FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
327  FieldMaskUtil::FromString("foo.bar,bar", &mask2);
328  FieldMaskUtil::Union(mask1, mask2, &out);
329  EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
330 }
331 
332 TEST(FieldMaskUtilTest, TestIntersect) {
333  FieldMask mask1, mask2, out;
334  // Test cases without overlapping.
335  FieldMaskUtil::FromString("foo,baz", &mask1);
336  FieldMaskUtil::FromString("bar,quz", &mask2);
337  FieldMaskUtil::Intersect(mask1, mask2, &out);
339  // Overlap with duplicated paths.
340  FieldMaskUtil::FromString("foo,baz.bb", &mask1);
341  FieldMaskUtil::FromString("baz.bb,quz", &mask2);
342  FieldMaskUtil::Intersect(mask1, mask2, &out);
343  EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
344  // Overlap with paths covering some other paths.
345  FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
346  FieldMaskUtil::FromString("foo.bar,bar", &mask2);
347  FieldMaskUtil::Intersect(mask1, mask2, &out);
348  EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
349 }
350 
351 TEST(FieldMaskUtilTest, TestSubtract) {
352  FieldMask mask1, mask2, out;
353  // Normal case.
355  "optional_int32,optional_uint64,optional_nested_message,optional_foreign_"
356  "message,repeated_int32,repeated_foreign_message,repeated_nested_message."
357  "bb",
358  &mask1);
359 
361  "optional_int32,optional_nested_message.bb,optional_foreign_message.c,"
362  "repeated_int32,repeated_nested_message.bb,repeated_foreign_message.f,"
363  "repeated_foreign_message.d,repeated_nested_message.bb,repeated_uint32",
364  &mask2);
365 
366  FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
367  EXPECT_EQ(
368  "optional_foreign_message.d,optional_uint64,repeated_foreign_message.c",
370 
371  // mask1 is empty.
372  FieldMaskUtil::FromString("", &mask1);
373  FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
375 
376  // mask1 is "optional_nested_message" and mask2 is
377  // "optional_nested_message.nonexist_field".
378  FieldMaskUtil::FromString("optional_nested_message", &mask1);
379  FieldMaskUtil::FromString("optional_nested_message.nonexist_field", &mask2);
380  FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
381  EXPECT_EQ("optional_nested_message", FieldMaskUtil::ToString(out));
382 
383  // mask1 is "optional_nested_message" and mask2 is
384  // "optional_nested_message".
385  FieldMaskUtil::FromString("optional_nested_message", &mask1);
386  FieldMaskUtil::FromString("optional_nested_message", &mask2);
387  FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
389 
390  // Regression test for b/72727550
391  FieldMaskUtil::FromString("optional_foreign_message.c", &mask1);
392  FieldMaskUtil::FromString("optional_foreign_message,optional_nested_message",
393  &mask2);
394  FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
396 }
397 
398 TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
399  FieldMask mask;
400  FieldMaskUtil::FromString("foo.bar", &mask);
406 }
407 
408 TEST(FieldMaskUtilTest, MergeMessage) {
409  TestAllTypes src, dst;
412 
413 #define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name) \
414  { \
415  TestAllTypes tmp; \
416  tmp.set_##field_name(src.field_name()); \
417  FieldMask mask; \
418  mask.add_paths(#field_name); \
419  dst.Clear(); \
420  FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
421  EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
422  src.clear_##field_name(); \
423  tmp.clear_##field_name(); \
424  FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
425  EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
426  }
427  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
428  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
429  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
430  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
431  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
432  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
433  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
434  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
435  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
436  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
437  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
438  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
439  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
440  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
441  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
442  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
443  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
444  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
445 #undef TEST_MERGE_ONE_PRIMITIVE_FIELD
446 
447 #define TEST_MERGE_ONE_FIELD(field_name) \
448  { \
449  TestAllTypes tmp; \
450  *tmp.mutable_##field_name() = src.field_name(); \
451  FieldMask mask; \
452  mask.add_paths(#field_name); \
453  dst.Clear(); \
454  FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
455  EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
456  }
457  TEST_MERGE_ONE_FIELD(optional_nested_message)
458  TEST_MERGE_ONE_FIELD(optional_foreign_message)
459  TEST_MERGE_ONE_FIELD(optional_import_message)
460 
461  TEST_MERGE_ONE_FIELD(repeated_int32)
462  TEST_MERGE_ONE_FIELD(repeated_int64)
463  TEST_MERGE_ONE_FIELD(repeated_uint32)
464  TEST_MERGE_ONE_FIELD(repeated_uint64)
465  TEST_MERGE_ONE_FIELD(repeated_sint32)
466  TEST_MERGE_ONE_FIELD(repeated_sint64)
467  TEST_MERGE_ONE_FIELD(repeated_fixed32)
468  TEST_MERGE_ONE_FIELD(repeated_fixed64)
469  TEST_MERGE_ONE_FIELD(repeated_sfixed32)
470  TEST_MERGE_ONE_FIELD(repeated_sfixed64)
471  TEST_MERGE_ONE_FIELD(repeated_float)
472  TEST_MERGE_ONE_FIELD(repeated_double)
473  TEST_MERGE_ONE_FIELD(repeated_bool)
474  TEST_MERGE_ONE_FIELD(repeated_string)
476  TEST_MERGE_ONE_FIELD(repeated_nested_message)
477  TEST_MERGE_ONE_FIELD(repeated_foreign_message)
478  TEST_MERGE_ONE_FIELD(repeated_import_message)
479  TEST_MERGE_ONE_FIELD(repeated_nested_enum)
480  TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
481  TEST_MERGE_ONE_FIELD(repeated_import_enum)
482 #undef TEST_MERGE_ONE_FIELD
483 
484  // Test merge nested fields.
485  NestedTestAllTypes nested_src, nested_dst;
486  nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
487  nested_src.mutable_child()
488  ->mutable_child()
489  ->mutable_payload()
490  ->set_optional_int32(5678);
491  FieldMask mask;
492  FieldMaskUtil::FromString("child.payload", &mask);
493  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
494  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
495  EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
496 
497  FieldMaskUtil::FromString("child.child.payload", &mask);
498  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
499  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
500  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
501 
502  nested_dst.Clear();
503  FieldMaskUtil::FromString("child.child.payload", &mask);
504  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
505  EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
506  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
507 
508  nested_dst.Clear();
509  FieldMaskUtil::FromString("child", &mask);
510  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
511  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
512  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
513 
514  // Test MergeOptions.
515 
516  nested_dst.Clear();
517  nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
518  // Message fields will be merged by default.
519  FieldMaskUtil::FromString("child.payload", &mask);
520  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
521  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
522  EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
523  // Change the behavior to replace message fields.
524  options.set_replace_message_fields(true);
525  FieldMaskUtil::FromString("child.payload", &mask);
526  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
527  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
528  EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
529 
530  // By default, fields missing in source are not cleared in destination.
531  options.set_replace_message_fields(false);
532  nested_dst.mutable_payload();
533  EXPECT_TRUE(nested_dst.has_payload());
534  FieldMaskUtil::FromString("payload", &mask);
535  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
536  EXPECT_TRUE(nested_dst.has_payload());
537  // But they are cleared when replacing message fields.
538  options.set_replace_message_fields(true);
539  nested_dst.Clear();
540  nested_dst.mutable_payload();
541  FieldMaskUtil::FromString("payload", &mask);
542  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
543  EXPECT_FALSE(nested_dst.has_payload());
544 
545  nested_src.mutable_payload()->add_repeated_int32(1234);
546  nested_dst.mutable_payload()->add_repeated_int32(5678);
547  // Repeated fields will be appended by default.
548  FieldMaskUtil::FromString("payload.repeated_int32", &mask);
549  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
550  ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
551  EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
552  EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
553  // Change the behavior to replace repeated fields.
554  options.set_replace_repeated_fields(true);
555  FieldMaskUtil::FromString("payload.repeated_int32", &mask);
556  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
557  ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
558  EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
559 }
560 
561 TEST(FieldMaskUtilTest, TrimMessage) {
562 #define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name) \
563  { \
564  TestAllTypes msg; \
565  TestUtil::SetAllFields(&msg); \
566  TestAllTypes tmp; \
567  tmp.set_##field_name(msg.field_name()); \
568  FieldMask mask; \
569  mask.add_paths(#field_name); \
570  FieldMaskUtil::TrimMessage(mask, &msg); \
571  EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
572  }
573  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int32)
574  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int64)
575  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint32)
576  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint64)
577  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint32)
578  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint64)
579  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed32)
580  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed64)
581  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed32)
582  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed64)
583  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_float)
584  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_double)
585  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bool)
586  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_string)
587  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bytes)
588  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_nested_enum)
589  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
590  TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_import_enum)
591 #undef TEST_TRIM_ONE_PRIMITIVE_FIELD
592 
593 #define TEST_TRIM_ONE_FIELD(field_name) \
594  { \
595  TestAllTypes msg; \
596  TestUtil::SetAllFields(&msg); \
597  TestAllTypes tmp; \
598  *tmp.mutable_##field_name() = msg.field_name(); \
599  FieldMask mask; \
600  mask.add_paths(#field_name); \
601  FieldMaskUtil::TrimMessage(mask, &msg); \
602  EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
603  }
604  TEST_TRIM_ONE_FIELD(optional_nested_message)
605  TEST_TRIM_ONE_FIELD(optional_foreign_message)
606  TEST_TRIM_ONE_FIELD(optional_import_message)
607 
608  TEST_TRIM_ONE_FIELD(repeated_int32)
609  TEST_TRIM_ONE_FIELD(repeated_int64)
610  TEST_TRIM_ONE_FIELD(repeated_uint32)
611  TEST_TRIM_ONE_FIELD(repeated_uint64)
612  TEST_TRIM_ONE_FIELD(repeated_sint32)
613  TEST_TRIM_ONE_FIELD(repeated_sint64)
614  TEST_TRIM_ONE_FIELD(repeated_fixed32)
615  TEST_TRIM_ONE_FIELD(repeated_fixed64)
616  TEST_TRIM_ONE_FIELD(repeated_sfixed32)
617  TEST_TRIM_ONE_FIELD(repeated_sfixed64)
618  TEST_TRIM_ONE_FIELD(repeated_float)
619  TEST_TRIM_ONE_FIELD(repeated_double)
620  TEST_TRIM_ONE_FIELD(repeated_bool)
621  TEST_TRIM_ONE_FIELD(repeated_string)
623  TEST_TRIM_ONE_FIELD(repeated_nested_message)
624  TEST_TRIM_ONE_FIELD(repeated_foreign_message)
625  TEST_TRIM_ONE_FIELD(repeated_import_message)
626  TEST_TRIM_ONE_FIELD(repeated_nested_enum)
627  TEST_TRIM_ONE_FIELD(repeated_foreign_enum)
628  TEST_TRIM_ONE_FIELD(repeated_import_enum)
629 #undef TEST_TRIM_ONE_FIELD
630 
631  // Test trim nested fields.
632  NestedTestAllTypes nested_msg;
633  nested_msg.mutable_child()->mutable_payload()->set_optional_int32(1234);
634  nested_msg.mutable_child()
635  ->mutable_child()
636  ->mutable_payload()
637  ->set_optional_int32(5678);
638  NestedTestAllTypes trimmed_msg(nested_msg);
639  FieldMask mask;
640  FieldMaskUtil::FromString("child.payload", &mask);
641  FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
642  EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
643  EXPECT_EQ(0, trimmed_msg.child().child().payload().optional_int32());
644 
645  trimmed_msg = nested_msg;
646  FieldMaskUtil::FromString("child.child.payload", &mask);
647  FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
648  EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
649  EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
650 
651  trimmed_msg = nested_msg;
652  FieldMaskUtil::FromString("child", &mask);
653  FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
654  EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
655  EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
656 
657  trimmed_msg = nested_msg;
658  FieldMaskUtil::FromString("child.child", &mask);
659  FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
660  EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
661  EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
662 
663  // Verify than an empty FieldMask trims nothing
664  TestAllTypes all_types_msg;
665  TestUtil::SetAllFields(&all_types_msg);
666  TestAllTypes trimmed_all_types(all_types_msg);
667  FieldMask empty_mask;
668  FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types);
669  EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString());
670 
671  // Test trim required fields with keep_required_fields is set true.
673  TestRequired required_msg_1;
674  required_msg_1.set_a(1234);
675  required_msg_1.set_b(3456);
676  required_msg_1.set_c(5678);
677  TestRequired trimmed_required_msg_1(required_msg_1);
678  FieldMaskUtil::FromString("dummy2", &mask);
679  options.set_keep_required_fields(true);
680  FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
681  EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
682 
683  // Test trim required fields with keep_required_fields is set false.
684  required_msg_1.clear_a();
685  required_msg_1.clear_b();
686  required_msg_1.clear_c();
687  options.set_keep_required_fields(false);
688  FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
689  EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
690 
691  // Test trim required message with keep_required_fields is set true.
692  TestRequiredMessage required_msg_2;
693  required_msg_2.mutable_optional_message()->set_a(1234);
694  required_msg_2.mutable_optional_message()->set_b(3456);
695  required_msg_2.mutable_optional_message()->set_c(5678);
696  required_msg_2.mutable_required_message()->set_a(1234);
697  required_msg_2.mutable_required_message()->set_b(3456);
698  required_msg_2.mutable_required_message()->set_c(5678);
699  required_msg_2.mutable_required_message()->set_dummy2(7890);
700  TestRequired* repeated_msg = required_msg_2.add_repeated_message();
701  repeated_msg->set_a(1234);
702  repeated_msg->set_b(3456);
703  repeated_msg->set_c(5678);
704  TestRequiredMessage trimmed_required_msg_2(required_msg_2);
705  FieldMaskUtil::FromString("optional_message.dummy2", &mask);
706  options.set_keep_required_fields(true);
707  required_msg_2.clear_repeated_message();
708  required_msg_2.mutable_required_message()->clear_dummy2();
709  FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
710  EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
711 
712  FieldMaskUtil::FromString("required_message", &mask);
713  required_msg_2.mutable_required_message()->set_dummy2(7890);
714  trimmed_required_msg_2.mutable_required_message()->set_dummy2(7890);
715  required_msg_2.clear_optional_message();
716  FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
717  EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
718 
719  // Test trim required message with keep_required_fields is set false.
720  FieldMaskUtil::FromString("required_message.dummy2", &mask);
721  required_msg_2.mutable_required_message()->clear_a();
722  required_msg_2.mutable_required_message()->clear_b();
723  required_msg_2.mutable_required_message()->clear_c();
724  options.set_keep_required_fields(false);
725  FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
726  EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
727 
728  // Verify that trimming an empty message has no effect. In particular, fields
729  // mentioned in the field mask should not be created or changed.
730  TestAllTypes empty_msg;
732  "optional_int32,optional_bytes,optional_nested_message.bb", &mask);
733  FieldMaskUtil::TrimMessage(mask, &empty_msg);
734  EXPECT_FALSE(empty_msg.has_optional_int32());
735  EXPECT_FALSE(empty_msg.has_optional_bytes());
736  EXPECT_FALSE(empty_msg.has_optional_nested_message());
737 
738  // Verify trimming of oneof fields. This should work as expected even if
739  // multiple elements of the same oneof are included in the FieldMask.
740  TestAllTypes oneof_msg;
741  oneof_msg.set_oneof_uint32(11);
742  FieldMaskUtil::FromString("oneof_uint32,oneof_nested_message.bb", &mask);
743  FieldMaskUtil::TrimMessage(mask, &oneof_msg);
744  EXPECT_EQ(11, oneof_msg.oneof_uint32());
745 }
746 
747 TEST(FieldMaskUtilTest, TrimMessageReturnValue) {
748  FieldMask mask;
749  TestAllTypes trimed_msg;
750  TestAllTypes default_msg;
751 
752  // Field mask on optional field.
753  FieldMaskUtil::FromString("optional_int32", &mask);
754 
755  // Verify that if a message is updted by FieldMaskUtil::TrimMessage(), the
756  // function returns true.
757  // Test on primary field.
758  trimed_msg.set_optional_string("abc");
760  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
761  trimed_msg.Clear();
762 
763  // Test on repeated primary field.
764  trimed_msg.add_repeated_string("abc");
765  trimed_msg.add_repeated_string("def");
767  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
768  trimed_msg.Clear();
769 
770  // Test on nested message.
771  trimed_msg.mutable_optional_nested_message()->set_bb(123);
773  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
774  trimed_msg.Clear();
775 
776  // Test on repeated nested message.
777  trimed_msg.add_repeated_nested_message()->set_bb(123);
778  trimed_msg.add_repeated_nested_message()->set_bb(456);
780  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
781  trimed_msg.Clear();
782 
783  // Test on oneof field.
784  trimed_msg.set_oneof_uint32(123);
786  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
787  trimed_msg.Clear();
788 
789  // If there is no field set other then those whitelisted,
790  // FieldMaskUtil::TrimMessage() should return false.
791  trimed_msg.set_optional_int32(123);
793  EXPECT_EQ(trimed_msg.optional_int32(), 123);
794  trimed_msg.Clear();
795 
796  // Field mask on repated field.
797  FieldMaskUtil::FromString("repeated_string", &mask);
798  trimed_msg.add_repeated_string("abc");
799  trimed_msg.add_repeated_string("def");
801  EXPECT_EQ(trimed_msg.repeated_string(0), "abc");
802  EXPECT_EQ(trimed_msg.repeated_string(1), "def");
803  trimed_msg.Clear();
804 
805  // Field mask on nested message.
806  FieldMaskUtil::FromString("optional_nested_message.bb", &mask);
807  trimed_msg.mutable_optional_nested_message()->set_bb(123);
809  EXPECT_EQ(trimed_msg.optional_nested_message().bb(), 123);
810  trimed_msg.Clear();
811 
812  // TODO(b/32443320): field mask on repeated nested message is not yet
813  // supported.
814 }
815 
816 
817 } // namespace
818 } // namespace util
819 } // namespace protobuf
820 } // namespace google
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::util::FieldMaskUtil::TrimOptions
TrimOptions()
Definition: field_mask_util.h:227
google::protobuf::util::SnakeCaseCamelCaseTest::SnakeCaseToCamelCase
string SnakeCaseToCamelCase(const std::string &input)
Definition: field_mask_util_test.cc:48
google::protobuf::util::FieldMaskUtil::TrimMessage
static bool TrimMessage(const FieldMask &mask, Message *message)
Definition: field_mask_util.cc:696
google::protobuf::value
const Descriptor::ReservedRange value
Definition: src/google/protobuf/descriptor.h:1954
field_mask.pb.h
src
GLenum src
Definition: glcorearb.h:3364
google::protobuf::util::TEST
TEST(DelimitedMessageUtilTest, DelimitedMessages)
Definition: delimited_message_util_test.cc:47
FieldMask
Definition: field_mask.pb.h:69
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
input
std::string input
Definition: tokenizer_unittest.cc:197
gtest.h
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
FieldMask
struct FieldMask FieldMask
Definition: php/ext/google/protobuf/protobuf.h:640
google::protobuf::util::FieldMaskUtil::Union
static void Union(const FieldMask &mask1, const FieldMask &mask2, FieldMask *out)
Definition: field_mask_util.cc:632
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
TEST_TRIM_ONE_PRIMITIVE_FIELD
#define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name)
TEST_TRIM_ONE_FIELD
#define TEST_TRIM_ONE_FIELD(field_name)
testing::Test
Definition: gtest.h:415
tests.google.protobuf.internal.test_util.SetAllFields
def SetAllFields(message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:182
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:2082
google::protobuf::util::SnakeCaseCamelCaseTest
Definition: field_mask_util_test.cc:46
mask
GLint GLuint mask
Definition: glcorearb.h:2789
google::protobuf::util::FieldMaskUtil::FromJsonString
static bool FromJsonString(StringPiece str, FieldMask *out)
Definition: field_mask_util.cc:122
google::protobuf::util::FieldMaskUtil::GetFieldDescriptors
static bool GetFieldDescriptors(const Descriptor *descriptor, StringPiece path, std::vector< const FieldDescriptor * > *field_descriptors)
Definition: field_mask_util.cc:136
TEST_MERGE_ONE_FIELD
#define TEST_MERGE_ONE_FIELD(field_name)
field_mask_util.h
EXPECT_TRUE
#define EXPECT_TRUE(cond)
Definition: glog/src/googletest.h:137
google::protobuf::util::FieldMaskUtil::FromString
static void FromString(StringPiece str, FieldMask *out)
Definition: field_mask_util.cc:49
google::protobuf::util::FieldMaskUtil::ToString
static std::string ToString(const FieldMask &mask)
Definition: field_mask_util.cc:45
google::protobuf::util::FieldMaskUtil::IsPathInFieldMask
static bool IsPathInFieldMask(StringPiece path, const FieldMask &mask)
Definition: field_mask_util.cc:668
google::protobuf::util::FieldMaskUtil::ToJsonString
static bool ToJsonString(const FieldMask &mask, std::string *out)
Definition: field_mask_util.cc:106
google::protobuf::util::FieldMaskUtil::CamelCaseToSnakeCase
static bool CamelCaseToSnakeCase(StringPiece input, std::string *output)
Definition: field_mask_util.cc:88
google::protobuf::util::FieldMaskUtil::Intersect
static void Intersect(const FieldMask &mask1, const FieldMask &mask2, FieldMask *out)
Definition: field_mask_util.cc:641
common.h
google::protobuf::TEST_F
TEST_F(DynamicMessageTest, Descriptor)
Definition: dynamic_message_unittest.cc:126
EXPECT_FALSE
#define EXPECT_FALSE(cond)
Definition: glog/src/googletest.h:145
google::protobuf::util::FieldMaskUtil::SnakeCaseToCamelCase
static bool SnakeCaseToCamelCase(StringPiece input, std::string *output)
Definition: field_mask_util.cc:58
logging.h
dst
GLenum GLenum dst
Definition: glcorearb.h:3364
google::protobuf::util::FieldMaskUtil::MergeOptions
MergeOptions()
Definition: field_mask_util.h:199
google::protobuf::util::SnakeCaseCamelCaseTest::CamelCaseToSnakeCase
string CamelCaseToSnakeCase(const std::string &input)
Definition: field_mask_util_test.cc:57
google::protobuf::util::FieldMaskUtil::ToCanonicalForm
static void ToCanonicalForm(const FieldMask &mask, FieldMask *out)
Definition: field_mask_util.cc:625
google::protobuf::util::FieldMaskUtil::MergeMessageTo
static void MergeMessageTo(const Message &source, const FieldMask &mask, const MergeOptions &options, Message *destination)
Definition: field_mask_util.cc:685
repeated_bytes
static size_t repeated_bytes(void *closure, const void *handler_data, const char *str, size_t len, const upb_bufhandle *handle)
Definition: php/ext/google/protobuf/upb.c:12825
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
test_util.h
google
Definition: data_proto2_to_proto3_util.h:11
TEST_MERGE_ONE_PRIMITIVE_FIELD
#define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name)


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