1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <algorithm>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::ElementsAre;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct trim_case {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* input;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TrimPositions positions;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* output;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TrimPositions return_value;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} trim_cases[] = {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" Google Video ", TRIM_LEADING, L"Google Video ", TRIM_LEADING},
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" Google Video ", TRIM_TRAILING, L" Google Video", TRIM_TRAILING},
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" Google Video ", TRIM_ALL, L"Google Video", TRIM_ALL},
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"Google Video", TRIM_ALL, L"Google Video", TRIM_NONE},
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"", TRIM_ALL, L"", TRIM_NONE},
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  ", TRIM_LEADING, L"", TRIM_LEADING},
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  ", TRIM_TRAILING, L"", TRIM_TRAILING},
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  ", TRIM_ALL, L"", TRIM_ALL},
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\t\rTest String\n", TRIM_ALL, L"Test String", TRIM_ALL},
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\x2002Test String\x00A0\x3000", TRIM_ALL, L"Test String", TRIM_ALL},
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct trim_case_ascii {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* input;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TrimPositions positions;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* output;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TrimPositions return_value;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} trim_cases_ascii[] = {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" Google Video ", TRIM_LEADING, "Google Video ", TRIM_LEADING},
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" Google Video ", TRIM_TRAILING, " Google Video", TRIM_TRAILING},
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" Google Video ", TRIM_ALL, "Google Video", TRIM_ALL},
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"Google Video", TRIM_ALL, "Google Video", TRIM_NONE},
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"", TRIM_ALL, "", TRIM_NONE},
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  ", TRIM_LEADING, "", TRIM_LEADING},
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  ", TRIM_TRAILING, "", TRIM_TRAILING},
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  ", TRIM_ALL, "", TRIM_ALL},
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"\t\rTest String\n", TRIM_ALL, "Test String", TRIM_ALL},
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper used to test TruncateUTF8ToByteSize.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Truncated(const std::string& input, const size_t byte_size,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::string* output) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t prev = input.length();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TruncateUTF8ToByteSize(input, byte_size, output);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return prev != output->length();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, TruncateUTF8ToByteSize) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty strings and invalid byte_size arguments
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(Truncated(std::string(), 0, &output));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output, "");
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xe1\x80\xbf", 0, &output));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output, "");
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xe1\x80\xbf", -1, &output));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xe1\x80\xbf", 4, &output));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing the truncation of valid UTF8 correctly
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("abc", 2, &output));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output, "ab");
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xc2\x81\xc2\x81", 2, &output));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xc2\x81"), 0);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xc2\x81\xc2\x81", 3, &output));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xc2\x81"), 0);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xc2\x81\xc2\x81", 4, &output));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xc2\x81\xc2\x81"), 0);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char array[] = "\x00\x00\xc2\x81\xc2\x81";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string array_string(array, arraysize(array));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Truncated(array_string, 4, &output));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(output.compare(std::string("\x00\x00\xc2\x81", 4)), 0);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char array[] = "\x00\xc2\x81\xc2\x81";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string array_string(array, arraysize(array));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Truncated(array_string, 4, &output));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(output.compare(std::string("\x00\xc2\x81", 3)), 0);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing invalid UTF8
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xed\xa0\x80\xed\xbf\xbf", 6, &output));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xed\xa0\x8f", 3, &output));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xed\xbf\xbf", 3, &output));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing invalid UTF8 mixed with valid UTF8
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xe1\x80\xbf", 3, &output));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xe1\x80\xbf"), 0);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xf1\x80\xa0\xbf", 4, &output));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xf1\x80\xa0\xbf"), 0);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf",
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              10, &output));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"), 0);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("a\xc2\x81\xe1\x80\xbf\xf1""a""\x80\xa0",
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              10, &output));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("a\xc2\x81\xe1\x80\xbf\xf1""a"), 0);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xef\xbb\xbf" "abc", 6, &output));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xef\xbb\xbf" "abc"), 0);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overlong sequences
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xc0\x80", 2, &output));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xc1\x80\xc1\x81", 4, &output));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xe0\x80\x80", 3, &output));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xe0\x82\x80", 3, &output));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xe0\x9f\xbf", 3, &output));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf0\x80\x80\x8D", 4, &output));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf0\x80\x82\x91", 4, &output));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf0\x80\xa0\x80", 4, &output));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf0\x8f\xbb\xbf", 4, &output));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf8\x80\x80\x80\xbf", 5, &output));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xfc\x80\x80\x80\xa0\xa5", 6, &output));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Beyond U+10FFFF (the upper limit of Unicode codespace)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf4\x90\x80\x80", 4, &output));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf8\xa0\xbf\x80\xbf", 5, &output));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xfc\x9c\xbf\x80\xbf\x80", 6, &output));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BOMs in UTF-16(BE|LE) and UTF-32(BE|LE)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xfe\xff", 2, &output));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xff\xfe", 2, &output));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char array[] = "\x00\x00\xfe\xff";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string array_string(array, arraysize(array));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Truncated(array_string, 4, &output));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(output.compare(std::string("\x00\x00", 2)), 0);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Variants on the previous test
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char array[] = "\xff\xfe\x00\x00";
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string array_string(array, 4);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(Truncated(array_string, 4, &output));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(output.compare(std::string("\xff\xfe\x00\x00", 4)), 0);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char array[] = "\xff\x00\x00\xfe";
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string array_string(array, arraysize(array));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Truncated(array_string, 4, &output));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(output.compare(std::string("\xff\x00\x00", 3)), 0);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-characters : U+xxFFF[EF] where xx is 0x00 through 0x10 and <FDD0,FDEF>
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xef\xbf\xbe", 3, &output));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf0\x8f\xbf\xbe", 4, &output));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xf3\xbf\xbf\xbf", 4, &output));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xef\xb7\x90", 3, &output));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xef\xb7\xaf", 3, &output));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Strings in legacy encodings that are valid in UTF-8, but
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are invalid as UTF-8 in real data.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("caf\xe9", 4, &output));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("caf"), 0);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xb0\xa1\xb0\xa2", 4, &output));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated("\xa7\x41\xa6\x6e", 4, &output));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xa7\x41\xa6\x6e\xd9\xee\xe4\xee", 7,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &output));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Testing using the same string as input and output.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(Truncated(output, 4, &output));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated(output, 3, &output));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\xa7\x41"), 0);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "abc" with U+201[CD] in windows-125[0-8]
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\x93" "abc\x94", 5, &output));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare("\x93" "abc"), 0);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U+0639 U+064E U+0644 U+064E in ISO-8859-6
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xd9\xee\xe4\xee", 4, &output));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U+03B3 U+03B5 U+03B9 U+03AC in ISO-8859-7
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Truncated("\xe3\xe5\xe9\xdC", 4, &output));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.compare(""), 0);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, TrimWhitespace) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 output;  // Allow contents to carry over to next testcase
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(trim_cases); ++i) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const trim_case& value = trim_cases[i];
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(value.return_value,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              TrimWhitespace(WideToUTF16(value.input), value.positions,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &output));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(WideToUTF16(value.output), output);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that TrimWhitespace() can take the same string for input and output
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output = ASCIIToUTF16("  This is a test \r\n");
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TRIM_ALL, TrimWhitespace(output, TRIM_ALL, &output));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("This is a test"), output);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once more, but with a string of whitespace
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output = ASCIIToUTF16("  \r\n");
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TRIM_ALL, TrimWhitespace(output, TRIM_ALL, &output));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string16(), output);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output_ascii;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(trim_cases_ascii); ++i) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const trim_case_ascii& value = trim_cases_ascii[i];
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(value.return_value,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              TrimWhitespace(value.input, value.positions, &output_ascii));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(value.output, output_ascii);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct collapse_case {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* input;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool trim;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* output;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} collapse_cases[] = {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" Google Video ", false, L"Google Video"},
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"Google Video", false, L"Google Video"},
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"", false, L""},
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  ", false, L""},
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\t\rTest String\n", false, L"Test String"},
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\x2002Test String\x00A0\x3000", false, L"Test String"},
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"    Test     \n  \t String    ", false, L"Test String"},
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\x2002Test\x1680 \x2028 \tString\x00A0\x3000", false, L"Test String"},
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"   Test String", false, L"Test String"},
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"Test String    ", false, L"Test String"},
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"Test String", false, L"Test String"},
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"", true, L""},
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\n", true, L""},
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  \r  ", true, L""},
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\nFoo", true, L"Foo"},
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"\r  Foo  ", true, L"Foo"},
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" Foo bar ", true, L"Foo bar"},
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L"  \tFoo  bar  \n", true, L"Foo bar"},
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {L" a \r b\n c \r\n d \t\re \t f \n ", true, L"abcde f"},
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, CollapseWhitespace) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(collapse_cases); ++i) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const collapse_case& value = collapse_cases[i];
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(WideToUTF16(value.output),
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              CollapseWhitespace(WideToUTF16(value.input), value.trim));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct collapse_case_ascii {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* input;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool trim;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* output;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} collapse_cases_ascii[] = {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" Google Video ", false, "Google Video"},
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"Google Video", false, "Google Video"},
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"", false, ""},
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  ", false, ""},
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"\t\rTest String\n", false, "Test String"},
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"    Test     \n  \t String    ", false, "Test String"},
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"   Test String", false, "Test String"},
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"Test String    ", false, "Test String"},
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"Test String", false, "Test String"},
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"", true, ""},
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"\n", true, ""},
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  \r  ", true, ""},
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"\nFoo", true, "Foo"},
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"\r  Foo  ", true, "Foo"},
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" Foo bar ", true, "Foo bar"},
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {"  \tFoo  bar  \n", true, "Foo bar"},
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {" a \r b\n c \r\n d \t\re \t f \n ", true, "abcde f"},
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, CollapseWhitespaceASCII) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(collapse_cases_ascii); ++i) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const collapse_case_ascii& value = collapse_cases_ascii[i];
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(value.output, CollapseWhitespaceASCII(value.input, value.trim));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, IsStringUTF8) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("abc"));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("\xc2\x81"));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("\xe1\x80\xbf"));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("\xf1\x80\xa0\xbf"));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8("\xef\xbb\xbf" "abc"));  // UTF-8 BOM
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // surrogate code points
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xed\xa0\x80\xed\xbf\xbf"));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xed\xa0\x8f"));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xed\xbf\xbf"));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overlong sequences
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xc0\x80"));  // U+0000
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xc1\x80\xc1\x81"));  // "AB"
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xe0\x80\x80"));  // U+0000
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xe0\x82\x80"));  // U+0080
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xe0\x9f\xbf"));  // U+07ff
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf0\x80\x80\x8D"));  // U+000D
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf0\x80\x82\x91"));  // U+0091
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf0\x80\xa0\x80"));  // U+0800
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf0\x8f\xbb\xbf"));  // U+FEFF (BOM)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf8\x80\x80\x80\xbf"));  // U+003F
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xfc\x80\x80\x80\xa0\xa5"));  // U+00A5
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Beyond U+10FFFF (the upper limit of Unicode codespace)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf4\x90\x80\x80"));  // U+110000
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf8\xa0\xbf\x80\xbf"));  // 5 bytes
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xfc\x9c\xbf\x80\xbf\x80"));  // 6 bytes
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BOMs in UTF-16(BE|LE) and UTF-32(BE|LE)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xfe\xff"));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xff\xfe"));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8(std::string("\x00\x00\xfe\xff", 4)));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xff\xfe\x00\x00"));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-characters : U+xxFFF[EF] where xx is 0x00 through 0x10 and <FDD0,FDEF>
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xef\xbf\xbe"));  // U+FFFE)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf0\x8f\xbf\xbe"));  // U+1FFFE
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xf3\xbf\xbf\xbf"));  // U+10FFFF
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xef\xb7\x90"));  // U+FDD0
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xef\xb7\xaf"));  // U+FDEF
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Strings in legacy encodings. We can certainly make up strings
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in a legacy encoding that are valid in UTF-8, but in real data,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // most of them are invalid as UTF-8.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("caf\xe9"));  // cafe with U+00E9 in ISO-8859-1
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xb0\xa1\xb0\xa2"));  // U+AC00, U+AC001 in EUC-KR
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xa7\x41\xa6\x6e"));  // U+4F60 U+597D in Big5
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "abc" with U+201[CD] in windows-125[0-8]
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\x93" "abc\x94"));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U+0639 U+064E U+0644 U+064E in ISO-8859-6
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xd9\xee\xe4\xee"));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // U+03B3 U+03B5 U+03B9 U+03AC in ISO-8859-7
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("\xe3\xe5\xe9\xdC"));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we support Embedded Nulls. The first uses the canonical UTF-8
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // representation, and the second uses a 2-byte sequence. The second version
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is invalid UTF-8 since UTF-8 states that the shortest encoding for a
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // given codepoint must be used.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kEmbeddedNull[] = "embedded\0null";
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsStringUTF8(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string(kEmbeddedNull, sizeof(kEmbeddedNull))));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringUTF8("embedded\xc0\x80U+0000"));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ConvertASCII) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* char_cases[] = {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Google Video",
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Hello, world\n",
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "0123ABCDwxyz \a\b\t\r\n!+,.~"
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const wchar_t* const wchar_cases[] = {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Google Video",
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Hello, world\n",
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"0123ABCDwxyz \a\b\t\r\n!+,.~"
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(char_cases); ++i) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(IsStringASCII(char_cases[i]));
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    string16 utf16 = ASCIIToUTF16(char_cases[i]);
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(WideToUTF16(wchar_cases[i]), utf16);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::string ascii = UTF16ToASCII(WideToUTF16(wchar_cases[i]));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(char_cases[i], ascii);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(IsStringASCII("Google \x80Video"));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert empty strings.
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  string16 empty16;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string empty;
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(empty, UTF16ToASCII(empty16));
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(empty16, ASCIIToUTF16(empty));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert strings with an embedded NUL character.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char chars_with_nul[] = "test\0string";
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int length_with_nul = arraysize(chars_with_nul) - 1;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string string_with_nul(chars_with_nul, length_with_nul);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring wide_with_nul = ASCIIToWide(string_with_nul);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<std::wstring::size_type>(length_with_nul),
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            wide_with_nul.length());
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string narrow_with_nul = UTF16ToASCII(WideToUTF16(wide_with_nul));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<std::string::size_type>(length_with_nul),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            narrow_with_nul.length());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, string_with_nul.compare(narrow_with_nul));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ToUpperASCII) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ('C', ToUpperASCII('C'));
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ('C', ToUpperASCII('c'));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ('2', ToUpperASCII('2'));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L'C', ToUpperASCII(L'C'));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L'C', ToUpperASCII(L'c'));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L'2', ToUpperASCII(L'2'));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string in_place_a("Cc2");
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringToUpperASCII(&in_place_a);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("CC2", in_place_a);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring in_place_w(L"Cc2");
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringToUpperASCII(&in_place_w);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L"CC2", in_place_w);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string original_a("Cc2");
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string upper_a = StringToUpperASCII(original_a);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("CC2", upper_a);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring original_w(L"Cc2");
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring upper_w = StringToUpperASCII(original_w);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L"CC2", upper_w);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, LowerCaseEqualsASCII) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char*    src_a;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char*    dst;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } lowercase_cases[] = {
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { "FoO", "foo" },
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { "foo", "foo" },
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { "FOO", "foo" },
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(lowercase_cases); ++i) {
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(LowerCaseEqualsASCII(ASCIIToUTF16(lowercase_cases[i].src_a),
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     lowercase_cases[i].dst));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(LowerCaseEqualsASCII(lowercase_cases[i].src_a,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     lowercase_cases[i].dst));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, FormatBytesUnlocalized) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 bytes;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expected behavior: we show one post-decimal digit when we have
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // under two pre-decimal digits, except in cases where it makes no
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sense (zero or bytes).
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since we switch units once we cross the 1000 mark, this keeps
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the display of file sizes or bytes consistently around three
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // digits.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, "0 B"},
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {512, "512 B"},
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1024*1024, "1.0 MB"},
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1024*1024*1024, "1.0 GB"},
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {10LL*1024*1024*1024, "10.0 GB"},
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {99LL*1024*1024*1024, "99.0 GB"},
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {105LL*1024*1024*1024, "105 GB"},
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {105LL*1024*1024*1024 + 500LL*1024*1024, "105 GB"},
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {~(1LL<<63), "8192 PB"},
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {99*1024 + 103, "99.1 kB"},
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1024*1024 + 103, "1.0 MB"},
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1024*1024 + 205 * 1024, "1.2 MB"},
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1024*1024*1024 + (927 * 1024*1024), "1.9 GB"},
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {10LL*1024*1024*1024, "10.0 GB"},
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100LL*1024*1024*1024, "100 GB"},
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ASCIIToUTF16(cases[i].expected),
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              FormatBytesUnlocalized(cases[i].bytes));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceSubstringsAfterOffset) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* str;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16::size_type start_offset;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* find_this;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* replace_with;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"aaa", 0, "a", "b", "bbb"},
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abb", 0, "ab", "a", "ab"},
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Removing some substrings inging", 0, "ing", "", "Remov some substrs "},
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Not found", 0, "x", "0", "Not found"},
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Not found again", 5, "x", "0", "Not found again"},
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {" Making it much longer ", 0, " ", "Four score and seven years ago",
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "Four score and seven years agoMakingFour score and seven years agoit"
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "Four score and seven years agomuchFour score and seven years agolonger"
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "Four score and seven years ago"},
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Invalid offset", 9999, "t", "foobar", "Invalid offset"},
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Replace me only me once", 9, "me ", "", "Replace me only once"},
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abababab", 2, "ab", "c", "abccc"},
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 str = ASCIIToUTF16(cases[i].str);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplaceSubstringsAfterOffset(&str, cases[i].start_offset,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ASCIIToUTF16(cases[i].find_this),
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ASCIIToUTF16(cases[i].replace_with));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ASCIIToUTF16(cases[i].expected), str);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceFirstSubstringAfterOffset) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* str;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16::size_type start_offset;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* find_this;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* replace_with;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* expected;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"aaa", 0, "a", "b", "baa"},
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abb", 0, "ab", "a", "ab"},
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Removing some substrings inging", 0, "ing", "",
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Remov some substrings inging"},
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Not found", 0, "x", "0", "Not found"},
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Not found again", 5, "x", "0", "Not found again"},
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {" Making it much longer ", 0, " ", "Four score and seven years ago",
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "Four score and seven years agoMaking it much longer "},
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Invalid offset", 9999, "t", "foobar", "Invalid offset"},
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"Replace me only me once", 4, "me ", "", "Replace only me once"},
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abababab", 2, "ab", "c", "abcabab"},
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 str = ASCIIToUTF16(cases[i].str);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplaceFirstSubstringAfterOffset(&str, cases[i].start_offset,
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ASCIIToUTF16(cases[i].find_this),
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ASCIIToUTF16(cases[i].replace_with));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ASCIIToUTF16(cases[i].expected), str);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, HexDigitToInt) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, HexDigitToInt('0'));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, HexDigitToInt('1'));
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, HexDigitToInt('2'));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, HexDigitToInt('3'));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, HexDigitToInt('4'));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, HexDigitToInt('5'));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, HexDigitToInt('6'));
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7, HexDigitToInt('7'));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, HexDigitToInt('8'));
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9, HexDigitToInt('9'));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, HexDigitToInt('A'));
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, HexDigitToInt('B'));
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, HexDigitToInt('C'));
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, HexDigitToInt('D'));
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14, HexDigitToInt('E'));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(15, HexDigitToInt('F'));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the lower case as well.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, HexDigitToInt('a'));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, HexDigitToInt('b'));
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, HexDigitToInt('c'));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, HexDigitToInt('d'));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14, HexDigitToInt('e'));
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(15, HexDigitToInt('f'));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This checks where we can use the assignment operator for a va_list. We need
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a way to do this since Visual C doesn't support va_copy, but assignment on
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// va_list is not guaranteed to be a copy. See StringAppendVT which uses this
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// capability.
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void VariableArgsFunc(const char* format, ...) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list org;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(org, format);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list dup;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GG_VA_COPY(dup, org);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i1 = va_arg(org, int);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int j1 = va_arg(org, int);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* s1 = va_arg(org, char*);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double d1 = va_arg(org, double);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(org);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i2 = va_arg(dup, int);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int j2 = va_arg(dup, int);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* s2 = va_arg(dup, char*);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double d2 = va_arg(dup, double);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(i1, i2);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(j1, j2);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ(s1, s2);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(d1, d2);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(dup);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, VAList) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariableArgsFunc("%d %d %s %lf", 45, 92, "This is interesting", 9.21);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for Tokenize
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename STR>
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TokenizeTest() {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<STR> r;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t size;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("This is a string"), STR(" "), &r);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, size);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, r.size());
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("This"));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR("is"));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR("a"));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[3], STR("string"));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one,two,three"), STR(","), &r);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, size);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, r.size());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR("two"));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR("three"));
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one,two:three;four"), STR(",:"), &r);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, size);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, r.size());
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR("two"));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR("three;four"));
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one,two:three;four"), STR(";,:"), &r);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, size);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, r.size());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR("two"));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR("three"));
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[3], STR("four"));
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one, two, three"), STR(","), &r);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, size);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, r.size());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR(" two"));
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR(" three"));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one, two, three, "), STR(","), &r);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, size);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4U, r.size());
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR(" two"));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR(" three"));
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[3], STR(" "));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("one, two, three,"), STR(","), &r);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, size);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, r.size());
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("one"));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR(" two"));
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[2], STR(" three"));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size = Tokenize(STR(), STR(","), &r);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, size);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, r.size());
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR(","), STR(","), &r);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, size);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, r.size());
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR(",;:."), STR(".:;,"), &r);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, size);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, r.size());
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("\t\ta\t"), STR("\t"), &r);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, size);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, r.size());
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("a"));
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = Tokenize(STR("\ta\t\nb\tcc"), STR("\n"), &r);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, size);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, r.size());
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[0], STR("\ta\t"));
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(r[1], STR("b\tcc"));
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  r.clear();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, TokenizeStdString) {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TokenizeTest<std::string>();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, TokenizeStringPiece) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TokenizeTest<base::StringPiece>();
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for JoinString
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, JoinString) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> in;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", JoinString(in, ','));
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in.push_back("a");
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a", JoinString(in, ','));
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in.push_back("b");
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in.push_back("c");
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a,b,c", JoinString(in, ','));
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  in.push_back(std::string());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a,b,c,", JoinString(in, ','));
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in.push_back(" ");
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a|b|c|| ", JoinString(in, '|'));
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for JoinString overloaded with std::string separator
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, JoinStringWithString) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string separator(", ");
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> parts;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), JoinString(parts, separator));
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back("a");
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a", JoinString(parts, separator));
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back("b");
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back("c");
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a, b, c", JoinString(parts, separator));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  parts.push_back(std::string());
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a, b, c, ", JoinString(parts, separator));
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(" ");
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("a|b|c|| ", JoinString(parts, "|"));
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for JoinString overloaded with string16 separator
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, JoinStringWithString16) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 separator = ASCIIToUTF16(", ");
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> parts;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string16(), JoinString(parts, separator));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(ASCIIToUTF16("a"));
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("a"), JoinString(parts, separator));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(ASCIIToUTF16("b"));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(ASCIIToUTF16("c"));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("a, b, c"), JoinString(parts, separator));
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(ASCIIToUTF16(""));
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("a, b, c, "), JoinString(parts, separator));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parts.push_back(ASCIIToUTF16(" "));
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("a|b|c|| "), JoinString(parts, ASCIIToUTF16("|")));
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, StartsWith) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII("javascript:url", "javascript", true));
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(StartsWithASCII("JavaScript:url", "javascript", true));
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII("javascript:url", "javascript", false));
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII("JavaScript:url", "javascript", false));
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(StartsWithASCII("java", "javascript", true));
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(StartsWithASCII("java", "javascript", false));
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(StartsWithASCII(std::string(), "javascript", false));
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(StartsWithASCII(std::string(), "javascript", true));
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII("java", std::string(), false));
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII("java", std::string(), true));
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(StartsWith(ASCIIToUTF16("javascript:url"),
801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         ASCIIToUTF16("javascript"), true));
802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(StartsWith(ASCIIToUTF16("JavaScript:url"),
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          ASCIIToUTF16("javascript"), true));
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(StartsWith(ASCIIToUTF16("javascript:url"),
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         ASCIIToUTF16("javascript"), false));
806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(StartsWith(ASCIIToUTF16("JavaScript:url"),
807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         ASCIIToUTF16("javascript"), false));
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(StartsWith(ASCIIToUTF16("java"),
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          ASCIIToUTF16("javascript"), true));
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(StartsWith(ASCIIToUTF16("java"),
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          ASCIIToUTF16("javascript"), false));
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(StartsWith(string16(), ASCIIToUTF16("javascript"), false));
813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(StartsWith(string16(), ASCIIToUTF16("javascript"), true));
814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(StartsWith(ASCIIToUTF16("java"), string16(), false));
815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(StartsWith(ASCIIToUTF16("java"), string16(), true));
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, EndsWith) {
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16("Foo.plugin"),
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       ASCIIToUTF16(".plugin"), true));
821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(ASCIIToUTF16("Foo.Plugin"),
822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        ASCIIToUTF16(".plugin"), true));
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16("Foo.plugin"),
824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       ASCIIToUTF16(".plugin"), false));
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16("Foo.Plugin"),
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       ASCIIToUTF16(".plugin"), false));
827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(ASCIIToUTF16(".plug"), ASCIIToUTF16(".plugin"), true));
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(ASCIIToUTF16(".plug"), ASCIIToUTF16(".plugin"), false));
829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(ASCIIToUTF16("Foo.plugin Bar"),
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        ASCIIToUTF16(".plugin"), true));
831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(ASCIIToUTF16("Foo.plugin Bar"),
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        ASCIIToUTF16(".plugin"), false));
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(string16(), ASCIIToUTF16(".plugin"), false));
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(EndsWith(string16(), ASCIIToUTF16(".plugin"), true));
835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16("Foo.plugin"), string16(), false));
836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16("Foo.plugin"), string16(), true));
837f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16(".plugin"),
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       ASCIIToUTF16(".plugin"), false));
839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(ASCIIToUTF16(".plugin"), ASCIIToUTF16(".plugin"), true));
840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(string16(), string16(), false));
841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(EndsWith(string16(), string16(), true));
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, GetStringFWithOffsets) {
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> subst;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("1"));
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("2"));
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<size_t> offsets;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReplaceStringPlaceholders(ASCIIToUTF16("Hello, $1. Your number is $2."),
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            subst,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &offsets);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, offsets.size());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7U, offsets[0]);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(25U, offsets[1]);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offsets.clear();
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReplaceStringPlaceholders(ASCIIToUTF16("Hello, $2. Your number is $1."),
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            subst,
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &offsets);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, offsets.size());
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(25U, offsets[0]);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7U, offsets[1]);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offsets.clear();
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceStringPlaceholdersTooFew) {
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test whether replacestringplaceholders works as expected when there
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are fewer inputs than outputs.
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> subst;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("9a"));
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("8b"));
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("7c"));
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 formatted =
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceStringPlaceholders(
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16("$1a,$2b,$3c,$4d,$5e,$6f,$1g,$2h,$3i"), subst, NULL);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(formatted, ASCIIToUTF16("9aa,8bb,7cc,d,e,f,9ag,8bh,7ci"));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceStringPlaceholders) {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> subst;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("9a"));
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("8b"));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("7c"));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("6d"));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("5e"));
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("4f"));
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("3g"));
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("2h"));
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("1i"));
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 formatted =
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceStringPlaceholders(
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16("$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i"), subst, NULL);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(formatted, ASCIIToUTF16("9aa,8bb,7cc,6dd,5ee,4ff,3gg,2hh,1ii"));
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceStringPlaceholdersMoreThan9Replacements) {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> subst;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("9a"));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("8b"));
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("7c"));
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("6d"));
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("5e"));
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("4f"));
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("3g"));
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("2h"));
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("1i"));
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("0j"));
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("-1k"));
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("-2l"));
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("-3m"));
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(ASCIIToUTF16("-4n"));
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 formatted =
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceStringPlaceholders(
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16("$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i,"
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "$10j,$11k,$12l,$13m,$14n,$1"), subst, NULL);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(formatted, ASCIIToUTF16("9aa,8bb,7cc,6dd,5ee,4ff,3gg,2hh,"
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "1ii,0jj,-1kk,-2ll,-3mm,-4nn,9a"));
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, StdStringReplaceStringPlaceholders) {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> subst;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("9a");
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("8b");
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("7c");
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("6d");
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("5e");
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("4f");
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("3g");
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("2h");
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("1i");
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string formatted =
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceStringPlaceholders(
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i", subst, NULL);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(formatted, "9aa,8bb,7cc,6dd,5ee,4ff,3gg,2hh,1ii");
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceStringPlaceholdersConsecutiveDollarSigns) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> subst;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("a");
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("b");
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back("c");
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ReplaceStringPlaceholders("$$1 $$$2 $$$$3", subst, NULL),
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "$1 $$2 $$$3");
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, MatchPatternTest) {
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("www.google.com", "*.com"));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("www.google.com", "*"));
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("www.google.com", "www*.g*.org"));
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("Hello", "H?l?o"));
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("www.google.com", "http://*)"));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("www.msn.com", "*.COM"));
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("Hello*1234", "He??o\\*1*"));
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("", "*.*"));
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("", "*"));
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("", "?"));
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("", ""));
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("Hello", ""));
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("Hello*", "Hello*"));
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop after a certain recursion depth.
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("123456789012345678", "?????????????????*"));
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test UTF8 matching.
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("heart: \xe2\x99\xa0", "*\xe2\x99\xa0"));
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("heart: \xe2\x99\xa0.", "heart: ?."));
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("hearts: \xe2\x99\xa0\xe2\x99\xa0", "*"));
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid sequences should be handled as a single invalid character.
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern("invalid: \xef\xbf\xbe", "invalid: ?"));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the pattern has invalid characters, it shouldn't match anything.
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(MatchPattern("\xf4\x90\x80\x80", "\xf4\x90\x80\x80"));
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test UTF16 character matching.
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern(UTF8ToUTF16("www.google.com"),
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           UTF8ToUTF16("*.com")));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern(UTF8ToUTF16("Hello*1234"),
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           UTF8ToUTF16("He??o\\*1*")));
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test verifies that consecutive wild cards are collapsed into 1
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wildcard (when this doesn't occur, MatchPattern reaches it's maximum
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // recursion depth).
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(MatchPattern(UTF8ToUTF16("Hello"),
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           UTF8ToUTF16("He********************************o")));
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, LcpyTest) {
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the normal case where we fit in our buffer.
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char dst[10];
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t wdst[10];
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::strlcpy(dst, "abcdefg", arraysize(dst)));
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test dst_size == 0, nothing should be written to |dst| and we should
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have the equivalent of strlen(src).
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char dst[2] = {1, 2};
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t wdst[2] = {1, 2};
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::strlcpy(dst, "abcdefg", 0));
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, dst[0]);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, dst[1]);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::wcslcpy(wdst, L"abcdefg", 0));
10145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(static_cast<wchar_t>(1), wdst[0]);
10155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(static_cast<wchar_t>(2), wdst[1]);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case were we _just_ competely fit including the null.
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char dst[8];
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t wdst[8];
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::strlcpy(dst, "abcdefg", arraysize(dst)));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case were we we are one smaller, so we can't fit the null.
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char dst[7];
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t wdst[7];
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::strlcpy(dst, "abcdefg", arraysize(dst)));
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(dst, "abcdef", 7));
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(wdst, L"abcdef", sizeof(wchar_t) * 7));
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case were we are just too small.
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char dst[3];
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t wdst[3];
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::strlcpy(dst, "abcdefg", arraysize(dst)));
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(dst, "ab", 3));
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, base::wcslcpy(wdst, L"abcdefg", arraysize(wdst)));
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(wdst, L"ab", sizeof(wchar_t) * 3));
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, WprintfFormatPortabilityTest) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const wchar_t* input;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool portable;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%ls", true },
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%s", false },
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%S", false },
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%lS", false },
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"Hello, %s", false },
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%lc", true },
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%c", false },
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%C", false },
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%lC", false },
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%ls %s", false },
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%s %ls", false },
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%s %ls %s", false },
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%f", true },
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%f %F", false },
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%d %D", false },
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%o %O", false },
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%u %U", false },
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%f %d %o %u", true },
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"%-8d (%02.1f%)", true },
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"% 10s", false },
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { L"% 10ls", true }
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(cases[i].portable, base::IsWprintfFormatPortable(cases[i].input));
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, RemoveChars) {
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kRemoveChars = "-/+*";
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string input = "A-+bc/d!*";
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RemoveChars(input, kRemoveChars, &input));
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Abcd!", input);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No characters match kRemoveChars.
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RemoveChars(input, kRemoveChars, &input));
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Abcd!", input);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty string.
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  input.clear();
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RemoveChars(input, kRemoveChars, &input));
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), input);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ReplaceChars) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestData {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* input;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* replace_chars;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* replace_with;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* output;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } cases[] = {
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "", "", "", "", false },
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "", "", "test", false },
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "", "!", "test", false },
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "z", "!", "test", false },
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "e", "!", "t!st", true },
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "e", "!?", "t!?st", true },
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "ez", "!", "t!st", true },
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "zed", "!?", "t!?st", true },
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "t", "!?", "!?es!?", true },
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "et", "!>", "!>!>s!>", true },
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "zest", "!", "!!!!", true },
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "szt", "!", "!e!!", true },
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test", "t", "test", "testestest", true },
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string output;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result = ReplaceChars(cases[i].input,
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               cases[i].replace_chars,
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               cases[i].replace_with,
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &output);
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(cases[i].result, result);
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(cases[i].output, output);
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(StringUtilTest, ContainsOnlyChars) {
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Providing an empty list of characters should return false but for the empty
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // string.
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(std::string(), std::string()));
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars("Hello", std::string()));
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(std::string(), "1234"));
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars("1", "1234"));
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars("1", "4321"));
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars("123", "4321"));
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars("123a", "4321"));
1141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(std::string(), kWhitespaceASCII));
1143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(" ", kWhitespaceASCII));
1144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars("\t", kWhitespaceASCII));
1145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars("\t \r \n  ", kWhitespaceASCII));
1146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars("a", kWhitespaceASCII));
1147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars("\thello\r \n  ", kWhitespaceASCII));
1148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(string16(), kWhitespaceUTF16));
1150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(ASCIIToUTF16(" "), kWhitespaceUTF16));
1151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(ASCIIToUTF16("\t"), kWhitespaceUTF16));
1152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(ContainsOnlyChars(ASCIIToUTF16("\t \r \n  "), kWhitespaceUTF16));
1153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars(ASCIIToUTF16("a"), kWhitespaceUTF16));
1154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(ContainsOnlyChars(ASCIIToUTF16("\thello\r \n  "),
1155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  kWhitespaceUTF16));
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WriteIntoTest : public testing::Test {
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WritesCorrectly(size_t num_chars) {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string buffer;
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char kOriginal[] = "supercali";
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(WriteInto(&buffer, num_chars + 1), kOriginal, num_chars);
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Using std::string(buffer.c_str()) instead of |buffer| truncates the
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // string at the first \0.
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string(kOriginal,
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          std::min(num_chars, arraysize(kOriginal) - 1)),
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              std::string(buffer.c_str()));
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(num_chars, buffer.size());
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WriteIntoTest, WriteInto) {
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Validate that WriteInto reserves enough space and
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sizes a string correctly.
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WritesCorrectly(1);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WritesCorrectly(2);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WritesCorrectly(5000);
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Validate that WriteInto doesn't modify other strings
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when using a Copy-on-Write implementation.
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kLive[] = "live";
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kDead[] = "dead";
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string live = kLive;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string dead = live;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strncpy(WriteInto(&dead, 5), kDead, 4);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kDead, dead);
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4u, dead.size());
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kLive, live);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4u, live.size());
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
1194