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