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 |