OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/base/arraysize.h" | |
12 #include "webrtc/base/gunit.h" | |
13 #include "webrtc/base/stringencode.h" | |
14 #include "webrtc/base/stringutils.h" | |
15 | |
16 namespace rtc { | |
17 | |
18 TEST(Utf8EncodeTest, EncodeDecode) { | |
19 const struct Utf8Test { | |
20 const char* encoded; | |
21 size_t encsize, enclen; | |
22 unsigned long decoded; | |
23 } kTests[] = { | |
24 {"a ", 5, 1, 'a'}, | |
25 {"\x7F ", 5, 1, 0x7F}, | |
26 {"\xC2\x80 ", 5, 2, 0x80}, | |
27 {"\xDF\xBF ", 5, 2, 0x7FF}, | |
28 {"\xE0\xA0\x80 ", 5, 3, 0x800}, | |
29 {"\xEF\xBF\xBF ", 5, 3, 0xFFFF}, | |
30 {"\xF0\x90\x80\x80 ", 5, 4, 0x10000}, | |
31 {"\xF0\x90\x80\x80 ", 3, 0, 0x10000}, | |
32 {"\xF0\xF0\x80\x80 ", 5, 0, 0}, | |
33 {"\xF0\x90\x80 ", 5, 0, 0}, | |
34 {"\x90\x80\x80 ", 5, 0, 0}, | |
35 {nullptr, 0, 0}, | |
36 }; | |
37 for (size_t i = 0; kTests[i].encoded; ++i) { | |
38 unsigned long val = 0; | |
39 ASSERT_EQ(kTests[i].enclen, utf8_decode(kTests[i].encoded, | |
40 kTests[i].encsize, | |
41 &val)); | |
42 unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded; | |
43 ASSERT_EQ(result, val); | |
44 | |
45 if (kTests[i].decoded == 0) { | |
46 // Not an interesting encoding test case | |
47 continue; | |
48 } | |
49 | |
50 char buffer[5]; | |
51 memset(buffer, 0x01, arraysize(buffer)); | |
52 ASSERT_EQ(kTests[i].enclen, utf8_encode(buffer, | |
53 kTests[i].encsize, | |
54 kTests[i].decoded)); | |
55 ASSERT_TRUE(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0); | |
56 // Make sure remainder of buffer is unchanged | |
57 ASSERT_TRUE(memory_check(buffer + kTests[i].enclen, | |
58 0x1, | |
59 arraysize(buffer) - kTests[i].enclen)); | |
60 } | |
61 } | |
62 | |
63 class HexEncodeTest : public testing::Test { | |
64 public: | |
65 HexEncodeTest() : enc_res_(0), dec_res_(0) { | |
66 for (size_t i = 0; i < sizeof(data_); ++i) { | |
67 data_[i] = (i + 128) & 0xff; | |
68 } | |
69 memset(decoded_, 0x7f, sizeof(decoded_)); | |
70 } | |
71 | |
72 char data_[10]; | |
73 char encoded_[31]; | |
74 char decoded_[11]; | |
75 size_t enc_res_; | |
76 size_t dec_res_; | |
77 }; | |
78 | |
79 // Test that we can convert to/from hex with no delimiter. | |
80 TEST_F(HexEncodeTest, TestWithNoDelimiter) { | |
81 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); | |
82 ASSERT_EQ(sizeof(data_) * 2, enc_res_); | |
83 ASSERT_STREQ("80818283848586878889", encoded_); | |
84 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); | |
85 ASSERT_EQ(sizeof(data_), dec_res_); | |
86 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); | |
87 } | |
88 | |
89 // Test that we can convert to/from hex with a colon delimiter. | |
90 TEST_F(HexEncodeTest, TestWithDelimiter) { | |
91 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), | |
92 data_, sizeof(data_), ':'); | |
93 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); | |
94 ASSERT_STREQ("80:81:82:83:84:85:86:87:88:89", encoded_); | |
95 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), | |
96 encoded_, enc_res_, ':'); | |
97 ASSERT_EQ(sizeof(data_), dec_res_); | |
98 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); | |
99 } | |
100 | |
101 // Test that encoding with one delimiter and decoding with another fails. | |
102 TEST_F(HexEncodeTest, TestWithWrongDelimiter) { | |
103 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), | |
104 data_, sizeof(data_), ':'); | |
105 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); | |
106 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), | |
107 encoded_, enc_res_, '/'); | |
108 ASSERT_EQ(0U, dec_res_); | |
109 } | |
110 | |
111 // Test that encoding without a delimiter and decoding with one fails. | |
112 TEST_F(HexEncodeTest, TestExpectedDelimiter) { | |
113 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); | |
114 ASSERT_EQ(sizeof(data_) * 2, enc_res_); | |
115 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), | |
116 encoded_, enc_res_, ':'); | |
117 ASSERT_EQ(0U, dec_res_); | |
118 } | |
119 | |
120 // Test that encoding with a delimiter and decoding without one fails. | |
121 TEST_F(HexEncodeTest, TestExpectedNoDelimiter) { | |
122 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), | |
123 data_, sizeof(data_), ':'); | |
124 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); | |
125 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); | |
126 ASSERT_EQ(0U, dec_res_); | |
127 } | |
128 | |
129 // Test that we handle a zero-length buffer with no delimiter. | |
130 TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) { | |
131 enc_res_ = hex_encode(encoded_, sizeof(encoded_), "", 0); | |
132 ASSERT_EQ(0U, enc_res_); | |
133 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); | |
134 ASSERT_EQ(0U, dec_res_); | |
135 } | |
136 | |
137 // Test that we handle a zero-length buffer with a delimiter. | |
138 TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) { | |
139 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), "", 0, ':'); | |
140 ASSERT_EQ(0U, enc_res_); | |
141 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), | |
142 encoded_, enc_res_, ':'); | |
143 ASSERT_EQ(0U, dec_res_); | |
144 } | |
145 | |
146 // Test the std::string variants that take no delimiter. | |
147 TEST_F(HexEncodeTest, TestHelpersNoDelimiter) { | |
148 std::string result = hex_encode(data_, sizeof(data_)); | |
149 ASSERT_EQ("80818283848586878889", result); | |
150 dec_res_ = hex_decode(decoded_, sizeof(decoded_), result); | |
151 ASSERT_EQ(sizeof(data_), dec_res_); | |
152 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); | |
153 } | |
154 | |
155 // Test the std::string variants that use a delimiter. | |
156 TEST_F(HexEncodeTest, TestHelpersWithDelimiter) { | |
157 std::string result = hex_encode_with_delimiter(data_, sizeof(data_), ':'); | |
158 ASSERT_EQ("80:81:82:83:84:85:86:87:88:89", result); | |
159 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), result, ':'); | |
160 ASSERT_EQ(sizeof(data_), dec_res_); | |
161 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); | |
162 } | |
163 | |
164 // Test that encoding into a too-small output buffer (without delimiter) fails. | |
165 TEST_F(HexEncodeTest, TestEncodeTooShort) { | |
166 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 2, | |
167 data_, sizeof(data_), 0); | |
168 ASSERT_EQ(0U, enc_res_); | |
169 } | |
170 | |
171 // Test that encoding into a too-small output buffer (with delimiter) fails. | |
172 TEST_F(HexEncodeTest, TestEncodeWithDelimiterTooShort) { | |
173 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 3 - 1, | |
174 data_, sizeof(data_), ':'); | |
175 ASSERT_EQ(0U, enc_res_); | |
176 } | |
177 | |
178 // Test that decoding into a too-small output buffer fails. | |
179 TEST_F(HexEncodeTest, TestDecodeTooShort) { | |
180 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0); | |
181 ASSERT_EQ(0U, dec_res_); | |
182 ASSERT_EQ(0x7f, decoded_[4]); | |
183 } | |
184 | |
185 // Test that decoding non-hex data fails. | |
186 TEST_F(HexEncodeTest, TestDecodeBogusData) { | |
187 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0); | |
188 ASSERT_EQ(0U, dec_res_); | |
189 } | |
190 | |
191 // Test that decoding an odd number of hex characters fails. | |
192 TEST_F(HexEncodeTest, TestDecodeOddHexDigits) { | |
193 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0); | |
194 ASSERT_EQ(0U, dec_res_); | |
195 } | |
196 | |
197 // Test that decoding a string with too many delimiters fails. | |
198 TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) { | |
199 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':'); | |
200 ASSERT_EQ(0U, dec_res_); | |
201 } | |
202 | |
203 // Test that decoding a string with a leading delimiter fails. | |
204 TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) { | |
205 dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':'); | |
206 ASSERT_EQ(0U, dec_res_); | |
207 } | |
208 | |
209 // Test that decoding a string with a trailing delimiter fails. | |
210 TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) { | |
211 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':'); | |
212 ASSERT_EQ(0U, dec_res_); | |
213 } | |
214 | |
215 // Tests counting substrings. | |
216 TEST(TokenizeTest, CountSubstrings) { | |
217 std::vector<std::string> fields; | |
218 | |
219 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields)); | |
220 fields.clear(); | |
221 EXPECT_EQ(1ul, tokenize("one", ' ', &fields)); | |
222 | |
223 // Extra spaces should be ignored. | |
224 fields.clear(); | |
225 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields)); | |
226 fields.clear(); | |
227 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields)); | |
228 fields.clear(); | |
229 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields)); | |
230 } | |
231 | |
232 // Tests comparing substrings. | |
233 TEST(TokenizeTest, CompareSubstrings) { | |
234 std::vector<std::string> fields; | |
235 | |
236 tokenize("find middle one", ' ', &fields); | |
237 ASSERT_EQ(3ul, fields.size()); | |
238 ASSERT_STREQ("middle", fields.at(1).c_str()); | |
239 fields.clear(); | |
240 | |
241 // Extra spaces should be ignored. | |
242 tokenize(" find middle one ", ' ', &fields); | |
243 ASSERT_EQ(3ul, fields.size()); | |
244 ASSERT_STREQ("middle", fields.at(1).c_str()); | |
245 fields.clear(); | |
246 tokenize(" ", ' ', &fields); | |
247 ASSERT_EQ(0ul, fields.size()); | |
248 } | |
249 | |
250 TEST(TokenizeTest, TokenizeAppend) { | |
251 ASSERT_EQ(0ul, tokenize_append("A B C", ' ', nullptr)); | |
252 | |
253 std::vector<std::string> fields; | |
254 | |
255 tokenize_append("A B C", ' ', &fields); | |
256 ASSERT_EQ(3ul, fields.size()); | |
257 ASSERT_STREQ("B", fields.at(1).c_str()); | |
258 | |
259 tokenize_append("D E", ' ', &fields); | |
260 ASSERT_EQ(5ul, fields.size()); | |
261 ASSERT_STREQ("B", fields.at(1).c_str()); | |
262 ASSERT_STREQ("E", fields.at(4).c_str()); | |
263 } | |
264 | |
265 TEST(TokenizeTest, TokenizeWithMarks) { | |
266 ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', nullptr)); | |
267 | |
268 std::vector<std::string> fields; | |
269 tokenize("A B C", ' ', '"', '"', &fields); | |
270 ASSERT_EQ(3ul, fields.size()); | |
271 ASSERT_STREQ("C", fields.at(2).c_str()); | |
272 | |
273 tokenize("\"A B\" C", ' ', '"', '"', &fields); | |
274 ASSERT_EQ(2ul, fields.size()); | |
275 ASSERT_STREQ("A B", fields.at(0).c_str()); | |
276 | |
277 tokenize("D \"A B\" C", ' ', '"', '"', &fields); | |
278 ASSERT_EQ(3ul, fields.size()); | |
279 ASSERT_STREQ("D", fields.at(0).c_str()); | |
280 ASSERT_STREQ("A B", fields.at(1).c_str()); | |
281 | |
282 tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields); | |
283 ASSERT_EQ(4ul, fields.size()); | |
284 ASSERT_STREQ("D", fields.at(0).c_str()); | |
285 ASSERT_STREQ("A B", fields.at(1).c_str()); | |
286 ASSERT_STREQ("E F", fields.at(3).c_str()); | |
287 | |
288 // No matching marks. | |
289 tokenize("D \"A B", ' ', '"', '"', &fields); | |
290 ASSERT_EQ(3ul, fields.size()); | |
291 ASSERT_STREQ("D", fields.at(0).c_str()); | |
292 ASSERT_STREQ("\"A", fields.at(1).c_str()); | |
293 | |
294 tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields); | |
295 ASSERT_EQ(5ul, fields.size()); | |
296 ASSERT_STREQ("D", fields.at(0).c_str()); | |
297 ASSERT_STREQ("A B", fields.at(1).c_str()); | |
298 ASSERT_STREQ("E F", fields.at(3).c_str()); | |
299 } | |
300 | |
301 TEST(TokenizeTest, TokenizeWithEmptyTokens) { | |
302 std::vector<std::string> fields; | |
303 EXPECT_EQ(3ul, tokenize_with_empty_tokens("a.b.c", '.', &fields)); | |
304 EXPECT_EQ("a", fields[0]); | |
305 EXPECT_EQ("b", fields[1]); | |
306 EXPECT_EQ("c", fields[2]); | |
307 | |
308 EXPECT_EQ(3ul, tokenize_with_empty_tokens("..c", '.', &fields)); | |
309 EXPECT_TRUE(fields[0].empty()); | |
310 EXPECT_TRUE(fields[1].empty()); | |
311 EXPECT_EQ("c", fields[2]); | |
312 | |
313 EXPECT_EQ(1ul, tokenize_with_empty_tokens("", '.', &fields)); | |
314 EXPECT_TRUE(fields[0].empty()); | |
315 } | |
316 | |
317 TEST(TokenizeFirstTest, NoLeadingSpaces) { | |
318 std::string token; | |
319 std::string rest; | |
320 | |
321 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest)); | |
322 ASSERT_STREQ("A", token.c_str()); | |
323 ASSERT_STREQ("&*${}", rest.c_str()); | |
324 | |
325 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest)); | |
326 ASSERT_STREQ("A", token.c_str()); | |
327 ASSERT_STREQ("B& *${}", rest.c_str()); | |
328 | |
329 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest)); | |
330 ASSERT_STREQ("A", token.c_str()); | |
331 ASSERT_STREQ("B& *${} ", rest.c_str()); | |
332 } | |
333 | |
334 TEST(TokenizeFirstTest, LeadingSpaces) { | |
335 std::string token; | |
336 std::string rest; | |
337 | |
338 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest)); | |
339 ASSERT_STREQ("", token.c_str()); | |
340 ASSERT_STREQ("A B C", rest.c_str()); | |
341 | |
342 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest)); | |
343 ASSERT_STREQ("", token.c_str()); | |
344 ASSERT_STREQ("A B C ", rest.c_str()); | |
345 } | |
346 | |
347 TEST(TokenizeFirstTest, SingleToken) { | |
348 std::string token; | |
349 std::string rest; | |
350 | |
351 // In the case where we cannot find delimiter the whole string is a token. | |
352 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest)); | |
353 | |
354 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest)); | |
355 ASSERT_STREQ("ABC", token.c_str()); | |
356 ASSERT_STREQ("", rest.c_str()); | |
357 | |
358 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest)); | |
359 ASSERT_STREQ("", token.c_str()); | |
360 ASSERT_STREQ("ABC ", rest.c_str()); | |
361 } | |
362 | |
363 // Tests counting substrings. | |
364 TEST(SplitTest, CountSubstrings) { | |
365 std::vector<std::string> fields; | |
366 | |
367 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields)); | |
368 fields.clear(); | |
369 EXPECT_EQ(1ul, split("one", ',', &fields)); | |
370 | |
371 // Empty fields between commas count. | |
372 fields.clear(); | |
373 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields)); | |
374 fields.clear(); | |
375 EXPECT_EQ(3ul, split(",three,", ',', &fields)); | |
376 fields.clear(); | |
377 EXPECT_EQ(1ul, split("", ',', &fields)); | |
378 } | |
379 | |
380 // Tests comparing substrings. | |
381 TEST(SplitTest, CompareSubstrings) { | |
382 std::vector<std::string> fields; | |
383 | |
384 split("find,middle,one", ',', &fields); | |
385 ASSERT_EQ(3ul, fields.size()); | |
386 ASSERT_STREQ("middle", fields.at(1).c_str()); | |
387 fields.clear(); | |
388 | |
389 // Empty fields between commas count. | |
390 split("find,,middle,one", ',', &fields); | |
391 ASSERT_EQ(4ul, fields.size()); | |
392 ASSERT_STREQ("middle", fields.at(2).c_str()); | |
393 fields.clear(); | |
394 split("", ',', &fields); | |
395 ASSERT_EQ(1ul, fields.size()); | |
396 ASSERT_STREQ("", fields.at(0).c_str()); | |
397 } | |
398 | |
399 TEST(BoolTest, DecodeValid) { | |
400 bool value; | |
401 EXPECT_TRUE(FromString("true", &value)); | |
402 EXPECT_TRUE(value); | |
403 EXPECT_TRUE(FromString("true,", &value)); | |
404 EXPECT_TRUE(value); | |
405 EXPECT_TRUE(FromString("true , true", &value)); | |
406 EXPECT_TRUE(value); | |
407 EXPECT_TRUE(FromString("true ,\n false", &value)); | |
408 EXPECT_TRUE(value); | |
409 EXPECT_TRUE(FromString(" true \n", &value)); | |
410 EXPECT_TRUE(value); | |
411 | |
412 EXPECT_TRUE(FromString("false", &value)); | |
413 EXPECT_FALSE(value); | |
414 EXPECT_TRUE(FromString(" false ", &value)); | |
415 EXPECT_FALSE(value); | |
416 EXPECT_TRUE(FromString(" false, ", &value)); | |
417 EXPECT_FALSE(value); | |
418 | |
419 EXPECT_TRUE(FromString<bool>("true\n")); | |
420 EXPECT_FALSE(FromString<bool>("false\n")); | |
421 } | |
422 | |
423 TEST(BoolTest, DecodeInvalid) { | |
424 bool value; | |
425 EXPECT_FALSE(FromString("True", &value)); | |
426 EXPECT_FALSE(FromString("TRUE", &value)); | |
427 EXPECT_FALSE(FromString("False", &value)); | |
428 EXPECT_FALSE(FromString("FALSE", &value)); | |
429 EXPECT_FALSE(FromString("0", &value)); | |
430 EXPECT_FALSE(FromString("1", &value)); | |
431 EXPECT_FALSE(FromString("0,", &value)); | |
432 EXPECT_FALSE(FromString("1,", &value)); | |
433 EXPECT_FALSE(FromString("1,0", &value)); | |
434 EXPECT_FALSE(FromString("1.", &value)); | |
435 EXPECT_FALSE(FromString("1.0", &value)); | |
436 EXPECT_FALSE(FromString("", &value)); | |
437 EXPECT_FALSE(FromString<bool>("false\nfalse")); | |
438 } | |
439 | |
440 TEST(BoolTest, RoundTrip) { | |
441 bool value; | |
442 EXPECT_TRUE(FromString(ToString(true), &value)); | |
443 EXPECT_TRUE(value); | |
444 EXPECT_TRUE(FromString(ToString(false), &value)); | |
445 EXPECT_FALSE(value); | |
446 } | |
447 | |
448 } // namespace rtc | |
OLD | NEW |