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