• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 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/compiler/objectivec/objectivec_helpers.h>
32 #include <google/protobuf/testing/googletest.h>
33 #include <gtest/gtest.h>
34 
35 namespace google {
36 namespace protobuf {
37 namespace compiler {
38 namespace objectivec {
39 namespace {
40 
TEST(ObjCHelper,TextFormatDecodeData_DecodeDataForString_RawStrings)41 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
42   string input_for_decode("abcdefghIJ");
43   string desired_output_for_decode;
44   string expected;
45   string result;
46 
47   // Different data, can't transform.
48 
49   desired_output_for_decode = "zbcdefghIJ";
50   expected = string("\0zbcdefghIJ\0", 12);
51   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
52                                                      desired_output_for_decode);
53   EXPECT_EQ(expected, result);
54 
55   desired_output_for_decode = "abcdezghIJ";
56   expected = string("\0abcdezghIJ\0", 12);
57   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
58                                                      desired_output_for_decode);
59   EXPECT_EQ(expected, result);
60 
61   // Shortened data, can't transform.
62 
63   desired_output_for_decode = "abcdefghI";
64   expected = string("\0abcdefghI\0", 11);
65   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
66                                                      desired_output_for_decode);
67   EXPECT_EQ(expected, result);
68 
69   // Extra data, can't transform.
70 
71   desired_output_for_decode = "abcdefghIJz";
72   expected = string("\0abcdefghIJz\0", 13);
73   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
74                                                      desired_output_for_decode);
75   EXPECT_EQ(expected, result);
76 }
77 
TEST(ObjCHelper,TextFormatDecodeData_DecodeDataForString_ByteCodes)78 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
79   string input_for_decode("abcdefghIJ");
80   string desired_output_for_decode;
81   string expected;
82   string result;
83 
84   desired_output_for_decode = "abcdefghIJ";
85   expected = string("\x0A\x0", 2);
86   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
87                                                      desired_output_for_decode);
88   EXPECT_EQ(expected, result);
89 
90   desired_output_for_decode = "_AbcdefghIJ";
91   expected = string("\xCA\x0", 2);
92   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
93                                                      desired_output_for_decode);
94   EXPECT_EQ(expected, result);
95 
96   desired_output_for_decode = "ABCD__EfghI_j";
97   expected = string("\x64\x80\xC5\xA1\x0", 5);
98   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
99                                                      desired_output_for_decode);
100   EXPECT_EQ(expected, result);
101 
102   // Long name so multiple decode ops are needed.
103 
104   input_for_decode =
105       "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
106   desired_output_for_decode =
107       "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
108   expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
109   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
110                                                      desired_output_for_decode);
111   EXPECT_EQ(expected, result);
112 }
113 
114 // Death tests do not work on Windows as of yet.
115 #ifdef PROTOBUF_HAS_DEATH_TEST
TEST(ObjCHelperDeathTest,TextFormatDecodeData_DecodeDataForString_Failures)116 TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
117   // Empty inputs.
118 
119   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""),
120               ::testing::KilledBySignal(SIGABRT),
121               "error: got empty string for making TextFormat data, input:");
122   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""),
123               ::testing::KilledBySignal(SIGABRT),
124               "error: got empty string for making TextFormat data, input:");
125   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"),
126               ::testing::KilledBySignal(SIGABRT),
127               "error: got empty string for making TextFormat data, input:");
128 
129   // Null char in the string.
130 
131   string str_with_null_char("ab\0c", 4);
132   EXPECT_EXIT(
133       TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
134       ::testing::KilledBySignal(SIGABRT),
135       "error: got a null char in a string for making TextFormat data, input:");
136   EXPECT_EXIT(
137       TextFormatDecodeData::DecodeDataForString("def", str_with_null_char),
138       ::testing::KilledBySignal(SIGABRT),
139       "error: got a null char in a string for making TextFormat data, input:");
140 }
141 #endif  // PROTOBUF_HAS_DEATH_TEST
142 
TEST(ObjCHelper,TextFormatDecodeData_RawStrings)143 TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
144   TextFormatDecodeData decode_data;
145 
146   // Different data, can't transform.
147   decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ");
148   decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ");
149   // Shortened data, can't transform.
150   decode_data.AddString(2, "abcdefghIJ", "abcdefghI");
151   // Extra data, can't transform.
152   decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz");
153 
154   EXPECT_EQ(4, decode_data.num_entries());
155 
156   uint8 expected_data[] = {
157       0x4,
158       0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0,
159       0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0,
160       0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
161       0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
162   };
163   string expected((const char*)expected_data, sizeof(expected_data));
164 
165   EXPECT_EQ(expected, decode_data.Data());
166 }
167 
TEST(ObjCHelper,TextFormatDecodeData_ByteCodes)168 TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
169   TextFormatDecodeData decode_data;
170 
171   decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
172   decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
173   decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
174   decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j");
175   decode_data.AddString(1000,
176                         "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000",
177                         "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000");
178 
179   EXPECT_EQ(5, decode_data.num_entries());
180 
181   uint8 expected_data[] = {
182       0x5,
183       // All as is (00 op)
184       0x1,  0x0A, 0x0,
185       // Underscore, upper + 9 (10 op)
186       0x3,  0xCA, 0x0,
187       //  Upper + 3 (10 op), underscore, upper + 5 (10 op)
188       0x2,  0x44, 0xC6, 0x0,
189       // All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op),
190       // underscore, lower + 0 (01 op)
191       0x4,  0x64, 0x80, 0xC5, 0xA1, 0x0,
192       // 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op),
193       //   underscore, lower + 3 (01 op), underscore, lower + 1 (01 op),
194       //   underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00
195       //   op),
196       //   underscore, as is + 3 (00 op)
197       0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
198   };
199   string expected((const char*)expected_data, sizeof(expected_data));
200 
201   EXPECT_EQ(expected, decode_data.Data());
202 }
203 
204 
205 // Death tests do not work on Windows as of yet.
206 #ifdef PROTOBUF_HAS_DEATH_TEST
TEST(ObjCHelperDeathTest,TextFormatDecodeData_Failures)207 TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
208   TextFormatDecodeData decode_data;
209 
210   // Empty inputs.
211 
212   EXPECT_EXIT(decode_data.AddString(1, "", ""),
213               ::testing::KilledBySignal(SIGABRT),
214               "error: got empty string for making TextFormat data, input:");
215   EXPECT_EXIT(decode_data.AddString(1, "a", ""),
216               ::testing::KilledBySignal(SIGABRT),
217               "error: got empty string for making TextFormat data, input:");
218   EXPECT_EXIT(decode_data.AddString(1, "", "a"),
219               ::testing::KilledBySignal(SIGABRT),
220               "error: got empty string for making TextFormat data, input:");
221 
222   // Null char in the string.
223 
224   string str_with_null_char("ab\0c", 4);
225   EXPECT_EXIT(
226       decode_data.AddString(1, str_with_null_char, "def"),
227       ::testing::KilledBySignal(SIGABRT),
228       "error: got a null char in a string for making TextFormat data, input:");
229   EXPECT_EXIT(
230       decode_data.AddString(1, "def", str_with_null_char),
231       ::testing::KilledBySignal(SIGABRT),
232       "error: got a null char in a string for making TextFormat data, input:");
233 
234   // Duplicate keys
235 
236   decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
237   decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
238   decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
239   EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"),
240               ::testing::KilledBySignal(SIGABRT),
241               "error: duplicate key \\(2\\) making TextFormat data, input:");
242 }
243 #endif  // PROTOBUF_HAS_DEATH_TEST
244 
245 // TODO(thomasvl): Should probably add some unittests for all the special cases
246 // of name mangling (class name, field name, enum names).  Rather than doing
247 // this with an ObjC test in the objectivec directory, we should be able to
248 // use src/google/protobuf/compiler/importer* (like other tests) to support a
249 // virtual file system to feed in protos, once we have the Descriptor tree, the
250 // tests could use the helper methods for generating names and validate the
251 // right things are happening.
252 
253 }  // namespace
254 }  // namespace objectivec
255 }  // namespace compiler
256 }  // namespace protobuf
257 }  // namespace google
258