field_mask_util_test.cc 32 KB

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