1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include "base/strings/string16.h" 8 #include "base/strings/string_piece.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace base { 13 14 template <typename T> 15 class CommonStringPieceTest : public ::testing::Test { 16 public: 17 static const T as_string(const char* input) { 18 return T(input); 19 } 20 static const T& as_string(const T& input) { 21 return input; 22 } 23 }; 24 25 template <> 26 class CommonStringPieceTest<string16> : public ::testing::Test { 27 public: 28 static const string16 as_string(const char* input) { 29 return ASCIIToUTF16(input); 30 } 31 static const string16 as_string(const std::string& input) { 32 return ASCIIToUTF16(input); 33 } 34 }; 35 36 typedef ::testing::Types<std::string, string16> SupportedStringTypes; 37 38 TYPED_TEST_CASE(CommonStringPieceTest, SupportedStringTypes); 39 40 TYPED_TEST(CommonStringPieceTest, CheckComparisonOperators) { 41 #define CMP_Y(op, x, y) \ 42 { \ 43 TypeParam lhs(TestFixture::as_string(x)); \ 44 TypeParam rhs(TestFixture::as_string(y)); \ 45 ASSERT_TRUE( (BasicStringPiece<TypeParam>((lhs.c_str())) op \ 46 BasicStringPiece<TypeParam>((rhs.c_str())))); \ 47 ASSERT_TRUE( (BasicStringPiece<TypeParam>((lhs.c_str())).compare( \ 48 BasicStringPiece<TypeParam>((rhs.c_str()))) op 0)); \ 49 } 50 51 #define CMP_N(op, x, y) \ 52 { \ 53 TypeParam lhs(TestFixture::as_string(x)); \ 54 TypeParam rhs(TestFixture::as_string(y)); \ 55 ASSERT_FALSE( (BasicStringPiece<TypeParam>((lhs.c_str())) op \ 56 BasicStringPiece<TypeParam>((rhs.c_str())))); \ 57 ASSERT_FALSE( (BasicStringPiece<TypeParam>((lhs.c_str())).compare( \ 58 BasicStringPiece<TypeParam>((rhs.c_str()))) op 0)); \ 59 } 60 61 CMP_Y(==, "", ""); 62 CMP_Y(==, "a", "a"); 63 CMP_Y(==, "aa", "aa"); 64 CMP_N(==, "a", ""); 65 CMP_N(==, "", "a"); 66 CMP_N(==, "a", "b"); 67 CMP_N(==, "a", "aa"); 68 CMP_N(==, "aa", "a"); 69 70 CMP_N(!=, "", ""); 71 CMP_N(!=, "a", "a"); 72 CMP_N(!=, "aa", "aa"); 73 CMP_Y(!=, "a", ""); 74 CMP_Y(!=, "", "a"); 75 CMP_Y(!=, "a", "b"); 76 CMP_Y(!=, "a", "aa"); 77 CMP_Y(!=, "aa", "a"); 78 79 CMP_Y(<, "a", "b"); 80 CMP_Y(<, "a", "aa"); 81 CMP_Y(<, "aa", "b"); 82 CMP_Y(<, "aa", "bb"); 83 CMP_N(<, "a", "a"); 84 CMP_N(<, "b", "a"); 85 CMP_N(<, "aa", "a"); 86 CMP_N(<, "b", "aa"); 87 CMP_N(<, "bb", "aa"); 88 89 CMP_Y(<=, "a", "a"); 90 CMP_Y(<=, "a", "b"); 91 CMP_Y(<=, "a", "aa"); 92 CMP_Y(<=, "aa", "b"); 93 CMP_Y(<=, "aa", "bb"); 94 CMP_N(<=, "b", "a"); 95 CMP_N(<=, "aa", "a"); 96 CMP_N(<=, "b", "aa"); 97 CMP_N(<=, "bb", "aa"); 98 99 CMP_N(>=, "a", "b"); 100 CMP_N(>=, "a", "aa"); 101 CMP_N(>=, "aa", "b"); 102 CMP_N(>=, "aa", "bb"); 103 CMP_Y(>=, "a", "a"); 104 CMP_Y(>=, "b", "a"); 105 CMP_Y(>=, "aa", "a"); 106 CMP_Y(>=, "b", "aa"); 107 CMP_Y(>=, "bb", "aa"); 108 109 CMP_N(>, "a", "a"); 110 CMP_N(>, "a", "b"); 111 CMP_N(>, "a", "aa"); 112 CMP_N(>, "aa", "b"); 113 CMP_N(>, "aa", "bb"); 114 CMP_Y(>, "b", "a"); 115 CMP_Y(>, "aa", "a"); 116 CMP_Y(>, "b", "aa"); 117 CMP_Y(>, "bb", "aa"); 118 119 std::string x; 120 for (int i = 0; i < 256; i++) { 121 x += 'a'; 122 std::string y = x; 123 CMP_Y(==, x, y); 124 for (int j = 0; j < i; j++) { 125 std::string z = x; 126 z[j] = 'b'; // Differs in position 'j' 127 CMP_N(==, x, z); 128 } 129 } 130 131 #undef CMP_Y 132 #undef CMP_N 133 } 134 135 TYPED_TEST(CommonStringPieceTest, CheckSTL) { 136 TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); 137 TypeParam abc(TestFixture::as_string("abc")); 138 TypeParam xyz(TestFixture::as_string("xyz")); 139 TypeParam foobar(TestFixture::as_string("foobar")); 140 141 BasicStringPiece<TypeParam> a(alphabet); 142 BasicStringPiece<TypeParam> b(abc); 143 BasicStringPiece<TypeParam> c(xyz); 144 BasicStringPiece<TypeParam> d(foobar); 145 BasicStringPiece<TypeParam> e; 146 TypeParam temp(TestFixture::as_string("123")); 147 temp += static_cast<typename TypeParam::value_type>(0); 148 temp += TestFixture::as_string("456"); 149 BasicStringPiece<TypeParam> f(temp); 150 151 ASSERT_EQ(a[6], static_cast<typename TypeParam::value_type>('g')); 152 ASSERT_EQ(b[0], static_cast<typename TypeParam::value_type>('a')); 153 ASSERT_EQ(c[2], static_cast<typename TypeParam::value_type>('z')); 154 ASSERT_EQ(f[3], static_cast<typename TypeParam::value_type>('\0')); 155 ASSERT_EQ(f[5], static_cast<typename TypeParam::value_type>('5')); 156 157 ASSERT_EQ(*d.data(), static_cast<typename TypeParam::value_type>('f')); 158 ASSERT_EQ(d.data()[5], static_cast<typename TypeParam::value_type>('r')); 159 ASSERT_TRUE(e.data() == NULL); 160 161 ASSERT_EQ(*a.begin(), static_cast<typename TypeParam::value_type>('a')); 162 ASSERT_EQ(*(b.begin() + 2), static_cast<typename TypeParam::value_type>('c')); 163 ASSERT_EQ(*(c.end() - 1), static_cast<typename TypeParam::value_type>('z')); 164 165 ASSERT_EQ(*a.rbegin(), static_cast<typename TypeParam::value_type>('z')); 166 ASSERT_EQ(*(b.rbegin() + 2), 167 static_cast<typename TypeParam::value_type>('a')); 168 ASSERT_EQ(*(c.rend() - 1), static_cast<typename TypeParam::value_type>('x')); 169 ASSERT_TRUE(a.rbegin() + 26 == a.rend()); 170 171 ASSERT_EQ(a.size(), 26U); 172 ASSERT_EQ(b.size(), 3U); 173 ASSERT_EQ(c.size(), 3U); 174 ASSERT_EQ(d.size(), 6U); 175 ASSERT_EQ(e.size(), 0U); 176 ASSERT_EQ(f.size(), 7U); 177 178 ASSERT_TRUE(!d.empty()); 179 ASSERT_TRUE(d.begin() != d.end()); 180 ASSERT_TRUE(d.begin() + 6 == d.end()); 181 182 ASSERT_TRUE(e.empty()); 183 ASSERT_TRUE(e.begin() == e.end()); 184 185 d.clear(); 186 ASSERT_EQ(d.size(), 0U); 187 ASSERT_TRUE(d.empty()); 188 ASSERT_TRUE(d.data() == NULL); 189 ASSERT_TRUE(d.begin() == d.end()); 190 191 ASSERT_GE(a.max_size(), a.capacity()); 192 ASSERT_GE(a.capacity(), a.size()); 193 } 194 195 // STL stuff only supported by the std::string version 196 TEST(StringPieceTest, CheckSTL) { 197 StringPiece a("abcdefghijklmnopqrstuvwxyz"); 198 StringPiece b("abc"); 199 StringPiece c("xyz"); 200 StringPiece d("foobar"); 201 d.clear(); 202 StringPiece e; 203 std::string temp("123"); 204 temp += '\0'; 205 temp += "456"; 206 StringPiece f(temp); 207 208 char buf[4] = { '%', '%', '%', '%' }; 209 ASSERT_EQ(a.copy(buf, 4), 4U); 210 ASSERT_EQ(buf[0], a[0]); 211 ASSERT_EQ(buf[1], a[1]); 212 ASSERT_EQ(buf[2], a[2]); 213 ASSERT_EQ(buf[3], a[3]); 214 ASSERT_EQ(a.copy(buf, 3, 7), 3U); 215 ASSERT_EQ(buf[0], a[7]); 216 ASSERT_EQ(buf[1], a[8]); 217 ASSERT_EQ(buf[2], a[9]); 218 ASSERT_EQ(buf[3], a[3]); 219 ASSERT_EQ(c.copy(buf, 99), 3U); 220 ASSERT_EQ(buf[0], c[0]); 221 ASSERT_EQ(buf[1], c[1]); 222 ASSERT_EQ(buf[2], c[2]); 223 ASSERT_EQ(buf[3], a[3]); 224 225 ASSERT_EQ(StringPiece::npos, std::string::npos); 226 227 ASSERT_EQ(a.find(b), 0U); 228 ASSERT_EQ(a.find(b, 1), StringPiece::npos); 229 ASSERT_EQ(a.find(c), 23U); 230 ASSERT_EQ(a.find(c, 9), 23U); 231 ASSERT_EQ(a.find(c, StringPiece::npos), StringPiece::npos); 232 ASSERT_EQ(b.find(c), StringPiece::npos); 233 ASSERT_EQ(b.find(c, StringPiece::npos), StringPiece::npos); 234 ASSERT_EQ(a.find(d), 0U); 235 ASSERT_EQ(a.find(e), 0U); 236 ASSERT_EQ(a.find(d, 12), 12U); 237 ASSERT_EQ(a.find(e, 17), 17U); 238 StringPiece g("xx not found bb"); 239 ASSERT_EQ(a.find(g), StringPiece::npos); 240 // empty string nonsense 241 ASSERT_EQ(d.find(b), StringPiece::npos); 242 ASSERT_EQ(e.find(b), StringPiece::npos); 243 ASSERT_EQ(d.find(b, 4), StringPiece::npos); 244 ASSERT_EQ(e.find(b, 7), StringPiece::npos); 245 246 size_t empty_search_pos = std::string().find(std::string()); 247 ASSERT_EQ(d.find(d), empty_search_pos); 248 ASSERT_EQ(d.find(e), empty_search_pos); 249 ASSERT_EQ(e.find(d), empty_search_pos); 250 ASSERT_EQ(e.find(e), empty_search_pos); 251 ASSERT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); 252 ASSERT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); 253 ASSERT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); 254 ASSERT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); 255 256 ASSERT_EQ(a.find('a'), 0U); 257 ASSERT_EQ(a.find('c'), 2U); 258 ASSERT_EQ(a.find('z'), 25U); 259 ASSERT_EQ(a.find('$'), StringPiece::npos); 260 ASSERT_EQ(a.find('\0'), StringPiece::npos); 261 ASSERT_EQ(f.find('\0'), 3U); 262 ASSERT_EQ(f.find('3'), 2U); 263 ASSERT_EQ(f.find('5'), 5U); 264 ASSERT_EQ(g.find('o'), 4U); 265 ASSERT_EQ(g.find('o', 4), 4U); 266 ASSERT_EQ(g.find('o', 5), 8U); 267 ASSERT_EQ(a.find('b', 5), StringPiece::npos); 268 // empty string nonsense 269 ASSERT_EQ(d.find('\0'), StringPiece::npos); 270 ASSERT_EQ(e.find('\0'), StringPiece::npos); 271 ASSERT_EQ(d.find('\0', 4), StringPiece::npos); 272 ASSERT_EQ(e.find('\0', 7), StringPiece::npos); 273 ASSERT_EQ(d.find('x'), StringPiece::npos); 274 ASSERT_EQ(e.find('x'), StringPiece::npos); 275 ASSERT_EQ(d.find('x', 4), StringPiece::npos); 276 ASSERT_EQ(e.find('x', 7), StringPiece::npos); 277 278 ASSERT_EQ(a.rfind(b), 0U); 279 ASSERT_EQ(a.rfind(b, 1), 0U); 280 ASSERT_EQ(a.rfind(c), 23U); 281 ASSERT_EQ(a.rfind(c, 22U), StringPiece::npos); 282 ASSERT_EQ(a.rfind(c, 1U), StringPiece::npos); 283 ASSERT_EQ(a.rfind(c, 0U), StringPiece::npos); 284 ASSERT_EQ(b.rfind(c), StringPiece::npos); 285 ASSERT_EQ(b.rfind(c, 0U), StringPiece::npos); 286 ASSERT_EQ(a.rfind(d), (size_t) a.as_string().rfind(std::string())); 287 ASSERT_EQ(a.rfind(e), a.as_string().rfind(std::string())); 288 ASSERT_EQ(a.rfind(d, 12), 12U); 289 ASSERT_EQ(a.rfind(e, 17), 17U); 290 ASSERT_EQ(a.rfind(g), StringPiece::npos); 291 ASSERT_EQ(d.rfind(b), StringPiece::npos); 292 ASSERT_EQ(e.rfind(b), StringPiece::npos); 293 ASSERT_EQ(d.rfind(b, 4), StringPiece::npos); 294 ASSERT_EQ(e.rfind(b, 7), StringPiece::npos); 295 // empty string nonsense 296 ASSERT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); 297 ASSERT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); 298 ASSERT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); 299 ASSERT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); 300 ASSERT_EQ(d.rfind(d), std::string().rfind(std::string())); 301 ASSERT_EQ(e.rfind(d), std::string().rfind(std::string())); 302 ASSERT_EQ(d.rfind(e), std::string().rfind(std::string())); 303 ASSERT_EQ(e.rfind(e), std::string().rfind(std::string())); 304 305 ASSERT_EQ(g.rfind('o'), 8U); 306 ASSERT_EQ(g.rfind('q'), StringPiece::npos); 307 ASSERT_EQ(g.rfind('o', 8), 8U); 308 ASSERT_EQ(g.rfind('o', 7), 4U); 309 ASSERT_EQ(g.rfind('o', 3), StringPiece::npos); 310 ASSERT_EQ(f.rfind('\0'), 3U); 311 ASSERT_EQ(f.rfind('\0', 12), 3U); 312 ASSERT_EQ(f.rfind('3'), 2U); 313 ASSERT_EQ(f.rfind('5'), 5U); 314 // empty string nonsense 315 ASSERT_EQ(d.rfind('o'), StringPiece::npos); 316 ASSERT_EQ(e.rfind('o'), StringPiece::npos); 317 ASSERT_EQ(d.rfind('o', 4), StringPiece::npos); 318 ASSERT_EQ(e.rfind('o', 7), StringPiece::npos); 319 320 ASSERT_EQ( 321 StringPiece("one,two:three;four").find_first_of(StringPiece(",:"), 1), 322 3U); 323 ASSERT_EQ(a.find_first_of(b), 0U); 324 ASSERT_EQ(a.find_first_of(b, 0), 0U); 325 ASSERT_EQ(a.find_first_of(b, 1), 1U); 326 ASSERT_EQ(a.find_first_of(b, 2), 2U); 327 ASSERT_EQ(a.find_first_of(b, 3), StringPiece::npos); 328 ASSERT_EQ(a.find_first_of(c), 23U); 329 ASSERT_EQ(a.find_first_of(c, 23), 23U); 330 ASSERT_EQ(a.find_first_of(c, 24), 24U); 331 ASSERT_EQ(a.find_first_of(c, 25), 25U); 332 ASSERT_EQ(a.find_first_of(c, 26), StringPiece::npos); 333 ASSERT_EQ(g.find_first_of(b), 13U); 334 ASSERT_EQ(g.find_first_of(c), 0U); 335 ASSERT_EQ(a.find_first_of(f), StringPiece::npos); 336 ASSERT_EQ(f.find_first_of(a), StringPiece::npos); 337 // empty string nonsense 338 ASSERT_EQ(a.find_first_of(d), StringPiece::npos); 339 ASSERT_EQ(a.find_first_of(e), StringPiece::npos); 340 ASSERT_EQ(d.find_first_of(b), StringPiece::npos); 341 ASSERT_EQ(e.find_first_of(b), StringPiece::npos); 342 ASSERT_EQ(d.find_first_of(d), StringPiece::npos); 343 ASSERT_EQ(e.find_first_of(d), StringPiece::npos); 344 ASSERT_EQ(d.find_first_of(e), StringPiece::npos); 345 ASSERT_EQ(e.find_first_of(e), StringPiece::npos); 346 347 ASSERT_EQ(a.find_first_not_of(b), 3U); 348 ASSERT_EQ(a.find_first_not_of(c), 0U); 349 ASSERT_EQ(b.find_first_not_of(a), StringPiece::npos); 350 ASSERT_EQ(c.find_first_not_of(a), StringPiece::npos); 351 ASSERT_EQ(f.find_first_not_of(a), 0U); 352 ASSERT_EQ(a.find_first_not_of(f), 0U); 353 ASSERT_EQ(a.find_first_not_of(d), 0U); 354 ASSERT_EQ(a.find_first_not_of(e), 0U); 355 // empty string nonsense 356 ASSERT_EQ(d.find_first_not_of(a), StringPiece::npos); 357 ASSERT_EQ(e.find_first_not_of(a), StringPiece::npos); 358 ASSERT_EQ(d.find_first_not_of(d), StringPiece::npos); 359 ASSERT_EQ(e.find_first_not_of(d), StringPiece::npos); 360 ASSERT_EQ(d.find_first_not_of(e), StringPiece::npos); 361 ASSERT_EQ(e.find_first_not_of(e), StringPiece::npos); 362 363 StringPiece h("===="); 364 ASSERT_EQ(h.find_first_not_of('='), StringPiece::npos); 365 ASSERT_EQ(h.find_first_not_of('=', 3), StringPiece::npos); 366 ASSERT_EQ(h.find_first_not_of('\0'), 0U); 367 ASSERT_EQ(g.find_first_not_of('x'), 2U); 368 ASSERT_EQ(f.find_first_not_of('\0'), 0U); 369 ASSERT_EQ(f.find_first_not_of('\0', 3), 4U); 370 ASSERT_EQ(f.find_first_not_of('\0', 2), 2U); 371 // empty string nonsense 372 ASSERT_EQ(d.find_first_not_of('x'), StringPiece::npos); 373 ASSERT_EQ(e.find_first_not_of('x'), StringPiece::npos); 374 ASSERT_EQ(d.find_first_not_of('\0'), StringPiece::npos); 375 ASSERT_EQ(e.find_first_not_of('\0'), StringPiece::npos); 376 377 // StringPiece g("xx not found bb"); 378 StringPiece i("56"); 379 ASSERT_EQ(h.find_last_of(a), StringPiece::npos); 380 ASSERT_EQ(g.find_last_of(a), g.size()-1); 381 ASSERT_EQ(a.find_last_of(b), 2U); 382 ASSERT_EQ(a.find_last_of(c), a.size()-1); 383 ASSERT_EQ(f.find_last_of(i), 6U); 384 ASSERT_EQ(a.find_last_of('a'), 0U); 385 ASSERT_EQ(a.find_last_of('b'), 1U); 386 ASSERT_EQ(a.find_last_of('z'), 25U); 387 ASSERT_EQ(a.find_last_of('a', 5), 0U); 388 ASSERT_EQ(a.find_last_of('b', 5), 1U); 389 ASSERT_EQ(a.find_last_of('b', 0), StringPiece::npos); 390 ASSERT_EQ(a.find_last_of('z', 25), 25U); 391 ASSERT_EQ(a.find_last_of('z', 24), StringPiece::npos); 392 ASSERT_EQ(f.find_last_of(i, 5), 5U); 393 ASSERT_EQ(f.find_last_of(i, 6), 6U); 394 ASSERT_EQ(f.find_last_of(a, 4), StringPiece::npos); 395 // empty string nonsense 396 ASSERT_EQ(f.find_last_of(d), StringPiece::npos); 397 ASSERT_EQ(f.find_last_of(e), StringPiece::npos); 398 ASSERT_EQ(f.find_last_of(d, 4), StringPiece::npos); 399 ASSERT_EQ(f.find_last_of(e, 4), StringPiece::npos); 400 ASSERT_EQ(d.find_last_of(d), StringPiece::npos); 401 ASSERT_EQ(d.find_last_of(e), StringPiece::npos); 402 ASSERT_EQ(e.find_last_of(d), StringPiece::npos); 403 ASSERT_EQ(e.find_last_of(e), StringPiece::npos); 404 ASSERT_EQ(d.find_last_of(f), StringPiece::npos); 405 ASSERT_EQ(e.find_last_of(f), StringPiece::npos); 406 ASSERT_EQ(d.find_last_of(d, 4), StringPiece::npos); 407 ASSERT_EQ(d.find_last_of(e, 4), StringPiece::npos); 408 ASSERT_EQ(e.find_last_of(d, 4), StringPiece::npos); 409 ASSERT_EQ(e.find_last_of(e, 4), StringPiece::npos); 410 ASSERT_EQ(d.find_last_of(f, 4), StringPiece::npos); 411 ASSERT_EQ(e.find_last_of(f, 4), StringPiece::npos); 412 413 ASSERT_EQ(a.find_last_not_of(b), a.size()-1); 414 ASSERT_EQ(a.find_last_not_of(c), 22U); 415 ASSERT_EQ(b.find_last_not_of(a), StringPiece::npos); 416 ASSERT_EQ(b.find_last_not_of(b), StringPiece::npos); 417 ASSERT_EQ(f.find_last_not_of(i), 4U); 418 ASSERT_EQ(a.find_last_not_of(c, 24), 22U); 419 ASSERT_EQ(a.find_last_not_of(b, 3), 3U); 420 ASSERT_EQ(a.find_last_not_of(b, 2), StringPiece::npos); 421 // empty string nonsense 422 ASSERT_EQ(f.find_last_not_of(d), f.size()-1); 423 ASSERT_EQ(f.find_last_not_of(e), f.size()-1); 424 ASSERT_EQ(f.find_last_not_of(d, 4), 4U); 425 ASSERT_EQ(f.find_last_not_of(e, 4), 4U); 426 ASSERT_EQ(d.find_last_not_of(d), StringPiece::npos); 427 ASSERT_EQ(d.find_last_not_of(e), StringPiece::npos); 428 ASSERT_EQ(e.find_last_not_of(d), StringPiece::npos); 429 ASSERT_EQ(e.find_last_not_of(e), StringPiece::npos); 430 ASSERT_EQ(d.find_last_not_of(f), StringPiece::npos); 431 ASSERT_EQ(e.find_last_not_of(f), StringPiece::npos); 432 ASSERT_EQ(d.find_last_not_of(d, 4), StringPiece::npos); 433 ASSERT_EQ(d.find_last_not_of(e, 4), StringPiece::npos); 434 ASSERT_EQ(e.find_last_not_of(d, 4), StringPiece::npos); 435 ASSERT_EQ(e.find_last_not_of(e, 4), StringPiece::npos); 436 ASSERT_EQ(d.find_last_not_of(f, 4), StringPiece::npos); 437 ASSERT_EQ(e.find_last_not_of(f, 4), StringPiece::npos); 438 439 ASSERT_EQ(h.find_last_not_of('x'), h.size() - 1); 440 ASSERT_EQ(h.find_last_not_of('='), StringPiece::npos); 441 ASSERT_EQ(b.find_last_not_of('c'), 1U); 442 ASSERT_EQ(h.find_last_not_of('x', 2), 2U); 443 ASSERT_EQ(h.find_last_not_of('=', 2), StringPiece::npos); 444 ASSERT_EQ(b.find_last_not_of('b', 1), 0U); 445 // empty string nonsense 446 ASSERT_EQ(d.find_last_not_of('x'), StringPiece::npos); 447 ASSERT_EQ(e.find_last_not_of('x'), StringPiece::npos); 448 ASSERT_EQ(d.find_last_not_of('\0'), StringPiece::npos); 449 ASSERT_EQ(e.find_last_not_of('\0'), StringPiece::npos); 450 451 ASSERT_EQ(a.substr(0, 3), b); 452 ASSERT_EQ(a.substr(23), c); 453 ASSERT_EQ(a.substr(23, 3), c); 454 ASSERT_EQ(a.substr(23, 99), c); 455 ASSERT_EQ(a.substr(0), a); 456 ASSERT_EQ(a.substr(3, 2), "de"); 457 // empty string nonsense 458 ASSERT_EQ(a.substr(99, 2), e); 459 ASSERT_EQ(d.substr(99), e); 460 ASSERT_EQ(d.substr(0, 99), e); 461 ASSERT_EQ(d.substr(99, 99), e); 462 } 463 464 TYPED_TEST(CommonStringPieceTest, CheckCustom) { 465 TypeParam foobar(TestFixture::as_string("foobar")); 466 BasicStringPiece<TypeParam> a(foobar); 467 TypeParam s1(TestFixture::as_string("123")); 468 s1 += static_cast<typename TypeParam::value_type>('\0'); 469 s1 += TestFixture::as_string("456"); 470 BasicStringPiece<TypeParam> b(s1); 471 BasicStringPiece<TypeParam> e; 472 TypeParam s2; 473 474 // remove_prefix 475 BasicStringPiece<TypeParam> c(a); 476 c.remove_prefix(3); 477 ASSERT_EQ(c, TestFixture::as_string("bar")); 478 c = a; 479 c.remove_prefix(0); 480 ASSERT_EQ(c, a); 481 c.remove_prefix(c.size()); 482 ASSERT_EQ(c, e); 483 484 // remove_suffix 485 c = a; 486 c.remove_suffix(3); 487 ASSERT_EQ(c, TestFixture::as_string("foo")); 488 c = a; 489 c.remove_suffix(0); 490 ASSERT_EQ(c, a); 491 c.remove_suffix(c.size()); 492 ASSERT_EQ(c, e); 493 494 // set 495 c.set(foobar.c_str()); 496 ASSERT_EQ(c, a); 497 c.set(foobar.c_str(), 6); 498 ASSERT_EQ(c, a); 499 c.set(foobar.c_str(), 0); 500 ASSERT_EQ(c, e); 501 c.set(foobar.c_str(), 7); // Note, has an embedded NULL 502 ASSERT_NE(c, a); 503 504 // as_string 505 TypeParam s3(a.as_string().c_str(), 7); // Note, has an embedded NULL 506 ASSERT_TRUE(c == s3); 507 TypeParam s4(e.as_string()); 508 ASSERT_TRUE(s4.empty()); 509 } 510 511 TEST(StringPieceTest, CheckCustom) { 512 StringPiece a("foobar"); 513 std::string s1("123"); 514 s1 += '\0'; 515 s1 += "456"; 516 StringPiece b(s1); 517 StringPiece e; 518 std::string s2; 519 520 // CopyToString 521 a.CopyToString(&s2); 522 ASSERT_EQ(s2.size(), 6U); 523 ASSERT_EQ(s2, "foobar"); 524 b.CopyToString(&s2); 525 ASSERT_EQ(s2.size(), 7U); 526 ASSERT_EQ(s1, s2); 527 e.CopyToString(&s2); 528 ASSERT_TRUE(s2.empty()); 529 530 // AppendToString 531 s2.erase(); 532 a.AppendToString(&s2); 533 ASSERT_EQ(s2.size(), 6U); 534 ASSERT_EQ(s2, "foobar"); 535 a.AppendToString(&s2); 536 ASSERT_EQ(s2.size(), 12U); 537 ASSERT_EQ(s2, "foobarfoobar"); 538 539 // starts_with 540 ASSERT_TRUE(a.starts_with(a)); 541 ASSERT_TRUE(a.starts_with("foo")); 542 ASSERT_TRUE(a.starts_with(e)); 543 ASSERT_TRUE(b.starts_with(s1)); 544 ASSERT_TRUE(b.starts_with(b)); 545 ASSERT_TRUE(b.starts_with(e)); 546 ASSERT_TRUE(e.starts_with("")); 547 ASSERT_TRUE(!a.starts_with(b)); 548 ASSERT_TRUE(!b.starts_with(a)); 549 ASSERT_TRUE(!e.starts_with(a)); 550 551 // ends with 552 ASSERT_TRUE(a.ends_with(a)); 553 ASSERT_TRUE(a.ends_with("bar")); 554 ASSERT_TRUE(a.ends_with(e)); 555 ASSERT_TRUE(b.ends_with(s1)); 556 ASSERT_TRUE(b.ends_with(b)); 557 ASSERT_TRUE(b.ends_with(e)); 558 ASSERT_TRUE(e.ends_with("")); 559 ASSERT_TRUE(!a.ends_with(b)); 560 ASSERT_TRUE(!b.ends_with(a)); 561 ASSERT_TRUE(!e.ends_with(a)); 562 563 StringPiece c; 564 c.set(static_cast<const void*>("foobar"), 6); 565 ASSERT_EQ(c, a); 566 c.set(static_cast<const void*>("foobar"), 0); 567 ASSERT_EQ(c, e); 568 c.set(static_cast<const void*>("foobar"), 7); 569 ASSERT_NE(c, a); 570 } 571 572 TYPED_TEST(CommonStringPieceTest, CheckNULL) { 573 // we used to crash here, but now we don't. 574 BasicStringPiece<TypeParam> s(NULL); 575 ASSERT_EQ(s.data(), (const typename TypeParam::value_type*)NULL); 576 ASSERT_EQ(s.size(), 0U); 577 578 s.set(NULL); 579 ASSERT_EQ(s.data(), (const typename TypeParam::value_type*)NULL); 580 ASSERT_EQ(s.size(), 0U); 581 582 TypeParam str = s.as_string(); 583 ASSERT_EQ(str.length(), 0U); 584 ASSERT_EQ(str, TypeParam()); 585 } 586 587 TYPED_TEST(CommonStringPieceTest, CheckComparisons2) { 588 TypeParam alphabet(TestFixture::as_string("abcdefghijklmnopqrstuvwxyz")); 589 TypeParam alphabet_z(TestFixture::as_string("abcdefghijklmnopqrstuvwxyzz")); 590 TypeParam alphabet_y(TestFixture::as_string("abcdefghijklmnopqrstuvwxyy")); 591 BasicStringPiece<TypeParam> abc(alphabet); 592 593 // check comparison operations on strings longer than 4 bytes. 594 ASSERT_TRUE(abc == BasicStringPiece<TypeParam>(alphabet)); 595 ASSERT_TRUE(abc.compare(BasicStringPiece<TypeParam>(alphabet)) == 0); 596 597 ASSERT_TRUE(abc < BasicStringPiece<TypeParam>(alphabet_z)); 598 ASSERT_TRUE(abc.compare(BasicStringPiece<TypeParam>(alphabet_z)) < 0); 599 600 ASSERT_TRUE(abc > BasicStringPiece<TypeParam>(alphabet_y)); 601 ASSERT_TRUE(abc.compare(BasicStringPiece<TypeParam>(alphabet_y)) > 0); 602 } 603 604 // Test operations only supported by std::string version. 605 TEST(StringPieceTest, CheckComparisons2) { 606 StringPiece abc("abcdefghijklmnopqrstuvwxyz"); 607 608 // starts_with 609 ASSERT_TRUE(abc.starts_with(abc)); 610 ASSERT_TRUE(abc.starts_with("abcdefghijklm")); 611 ASSERT_TRUE(!abc.starts_with("abcdefguvwxyz")); 612 613 // ends_with 614 ASSERT_TRUE(abc.ends_with(abc)); 615 ASSERT_TRUE(!abc.ends_with("abcdefguvwxyz")); 616 ASSERT_TRUE(abc.ends_with("nopqrstuvwxyz")); 617 } 618 619 TYPED_TEST(CommonStringPieceTest, StringCompareNotAmbiguous) { 620 ASSERT_TRUE(TestFixture::as_string("hello").c_str() == 621 TestFixture::as_string("hello")); 622 ASSERT_TRUE(TestFixture::as_string("hello").c_str() < 623 TestFixture::as_string("world")); 624 } 625 626 TYPED_TEST(CommonStringPieceTest, HeterogenousStringPieceEquals) { 627 TypeParam hello(TestFixture::as_string("hello")); 628 629 ASSERT_TRUE(BasicStringPiece<TypeParam>(hello) == hello); 630 ASSERT_TRUE(hello.c_str() == BasicStringPiece<TypeParam>(hello)); 631 } 632 633 // string16-specific stuff 634 TEST(StringPiece16Test, CheckSTL) { 635 // Check some non-ascii characters. 636 string16 fifth(ASCIIToUTF16("123")); 637 fifth.push_back(0x0000); 638 fifth.push_back(0xd8c5); 639 fifth.push_back(0xdffe); 640 StringPiece16 f(fifth); 641 642 ASSERT_EQ(f[3], '\0'); 643 ASSERT_EQ(f[5], static_cast<char16>(0xdffe)); 644 645 ASSERT_EQ(f.size(), 6U); 646 } 647 648 649 650 TEST(StringPiece16Test, CheckConversion) { 651 // Make sure that we can convert from UTF8 to UTF16 and back. We use a two 652 // byte character (G clef) to test this. 653 ASSERT_EQ( 654 UTF16ToUTF8( 655 StringPiece16(UTF8ToUTF16("\xf0\x9d\x84\x9e")).as_string()), 656 "\xf0\x9d\x84\x9e"); 657 } 658 659 TYPED_TEST(CommonStringPieceTest, CheckConstructors) { 660 TypeParam str(TestFixture::as_string("hello world")); 661 TypeParam empty; 662 663 ASSERT_TRUE(str == BasicStringPiece<TypeParam>(str)); 664 ASSERT_TRUE(str == BasicStringPiece<TypeParam>(str.c_str())); 665 ASSERT_TRUE(TestFixture::as_string("hello") == 666 BasicStringPiece<TypeParam>(str.c_str(), 5)); 667 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(str.c_str(), 0U)); 668 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(NULL)); 669 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(NULL, 0U)); 670 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>()); 671 ASSERT_TRUE(str == BasicStringPiece<TypeParam>(str.begin(), str.end())); 672 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(str.begin(), str.begin())); 673 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(empty)); 674 ASSERT_TRUE(empty == BasicStringPiece<TypeParam>(empty.begin(), empty.end())); 675 } 676 677 } // namespace base 678