| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 #include <google/protobuf/util/field_mask_util.h> | 31 #include <google/protobuf/util/field_mask_util.h> |
| 32 | 32 |
| 33 #include <algorithm> |
| 34 |
| 35 #include <google/protobuf/stubs/logging.h> |
| 36 #include <google/protobuf/stubs/common.h> |
| 33 #include <google/protobuf/field_mask.pb.h> | 37 #include <google/protobuf/field_mask.pb.h> |
| 34 #include <google/protobuf/unittest.pb.h> | 38 #include <google/protobuf/unittest.pb.h> |
| 35 #include <google/protobuf/test_util.h> | 39 #include <google/protobuf/test_util.h> |
| 36 #include <gtest/gtest.h> | 40 #include <gtest/gtest.h> |
| 37 | 41 |
| 38 namespace google { | 42 namespace google { |
| 39 namespace protobuf { | 43 namespace protobuf { |
| 40 namespace util { | 44 namespace util { |
| 45 |
| 46 class SnakeCaseCamelCaseTest : public ::testing::Test { |
| 47 protected: |
| 48 string SnakeCaseToCamelCase(const string& input) { |
| 49 string output; |
| 50 if (FieldMaskUtil::SnakeCaseToCamelCase(input, &output)) { |
| 51 return output; |
| 52 } else { |
| 53 return "#FAIL#"; |
| 54 } |
| 55 } |
| 56 |
| 57 string CamelCaseToSnakeCase(const string& input) { |
| 58 string output; |
| 59 if (FieldMaskUtil::CamelCaseToSnakeCase(input, &output)) { |
| 60 return output; |
| 61 } else { |
| 62 return "#FAIL#"; |
| 63 } |
| 64 } |
| 65 }; |
| 66 |
| 41 namespace { | 67 namespace { |
| 42 | 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 string name = "___abc123"; |
| 96 std::sort(name.begin(), name.end()); |
| 97 do { |
| 98 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 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 |
| 43 using protobuf_unittest::TestAllTypes; | 116 using protobuf_unittest::TestAllTypes; |
| 44 using protobuf_unittest::NestedTestAllTypes; | 117 using protobuf_unittest::NestedTestAllTypes; |
| 45 using google::protobuf::FieldMask; | 118 using google::protobuf::FieldMask; |
| 46 | 119 |
| 47 TEST(FieldMaskUtilTest, StringFormat) { | 120 TEST(FieldMaskUtilTest, StringFormat) { |
| 48 FieldMask mask; | 121 FieldMask mask; |
| 49 EXPECT_EQ("", FieldMaskUtil::ToString(mask)); | 122 EXPECT_EQ("", FieldMaskUtil::ToString(mask)); |
| 50 mask.add_paths("foo"); | 123 mask.add_paths("foo_bar"); |
| 51 EXPECT_EQ("foo", FieldMaskUtil::ToString(mask)); | 124 EXPECT_EQ("foo_bar", FieldMaskUtil::ToString(mask)); |
| 52 mask.add_paths("bar"); | 125 mask.add_paths("baz_quz"); |
| 53 EXPECT_EQ("foo,bar", FieldMaskUtil::ToString(mask)); | 126 EXPECT_EQ("foo_bar,baz_quz", FieldMaskUtil::ToString(mask)); |
| 54 | 127 |
| 55 FieldMaskUtil::FromString("", &mask); | 128 FieldMaskUtil::FromString("", &mask); |
| 56 EXPECT_EQ(0, mask.paths_size()); | 129 EXPECT_EQ(0, mask.paths_size()); |
| 57 FieldMaskUtil::FromString("foo", &mask); | 130 FieldMaskUtil::FromString("fooBar", &mask); |
| 58 EXPECT_EQ(1, mask.paths_size()); | 131 EXPECT_EQ(1, mask.paths_size()); |
| 59 EXPECT_EQ("foo", mask.paths(0)); | 132 EXPECT_EQ("fooBar", mask.paths(0)); |
| 60 FieldMaskUtil::FromString("foo,bar", &mask); | 133 FieldMaskUtil::FromString("fooBar,bazQuz", &mask); |
| 61 EXPECT_EQ(2, mask.paths_size()); | 134 EXPECT_EQ(2, mask.paths_size()); |
| 62 EXPECT_EQ("foo", mask.paths(0)); | 135 EXPECT_EQ("fooBar", mask.paths(0)); |
| 63 EXPECT_EQ("bar", mask.paths(1)); | 136 EXPECT_EQ("bazQuz", mask.paths(1)); |
| 137 } |
| 138 |
| 139 TEST(FieldMaskUtilTest, JsonStringFormat) { |
| 140 FieldMask mask; |
| 141 string value; |
| 142 EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value)); |
| 143 EXPECT_EQ("", value); |
| 144 mask.add_paths("foo_bar"); |
| 145 EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value)); |
| 146 EXPECT_EQ("fooBar", value); |
| 147 mask.add_paths("bar_quz"); |
| 148 EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value)); |
| 149 EXPECT_EQ("fooBar,barQuz", value); |
| 150 |
| 151 FieldMaskUtil::FromJsonString("", &mask); |
| 152 EXPECT_EQ(0, mask.paths_size()); |
| 153 FieldMaskUtil::FromJsonString("fooBar", &mask); |
| 154 EXPECT_EQ(1, mask.paths_size()); |
| 155 EXPECT_EQ("foo_bar", mask.paths(0)); |
| 156 FieldMaskUtil::FromJsonString("fooBar,bazQuz", &mask); |
| 157 EXPECT_EQ(2, mask.paths_size()); |
| 158 EXPECT_EQ("foo_bar", mask.paths(0)); |
| 159 EXPECT_EQ("baz_quz", mask.paths(1)); |
| 64 } | 160 } |
| 65 | 161 |
| 66 TEST(FieldMaskUtilTest, TestIsVaildPath) { | 162 TEST(FieldMaskUtilTest, TestIsVaildPath) { |
| 67 EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32")); | 163 EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32")); |
| 68 EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist")); | 164 EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist")); |
| 69 EXPECT_TRUE( | 165 EXPECT_TRUE( |
| 70 FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb")); | 166 FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb")); |
| 71 EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>( | 167 EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>( |
| 72 "optional_nested_message.nonexist")); | 168 "optional_nested_message.nonexist")); |
| 73 // FieldMask cannot be used to specify sub-fields of a repeated message. | 169 // FieldMask cannot be used to specify sub-fields of a repeated message. |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst); | 482 FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst); |
| 387 ASSERT_EQ(1, nested_dst.payload().repeated_int32_size()); | 483 ASSERT_EQ(1, nested_dst.payload().repeated_int32_size()); |
| 388 EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0)); | 484 EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0)); |
| 389 } | 485 } |
| 390 | 486 |
| 391 | 487 |
| 392 } // namespace | 488 } // namespace |
| 393 } // namespace util | 489 } // namespace util |
| 394 } // namespace protobuf | 490 } // namespace protobuf |
| 395 } // namespace google | 491 } // namespace google |
| OLD | NEW |