xref: /aosp_15_r20/external/cronet/base/strings/string_util_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <math.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdarg.h>
9*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include <algorithm>
13*6777b538SAndroid Build Coastguard Worker #include <string>
14*6777b538SAndroid Build Coastguard Worker #include <string_view>
15*6777b538SAndroid Build Coastguard Worker #include <type_traits>
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include "base/bits.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
21*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
22*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker using ::testing::ElementsAre;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker namespace base {
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker namespace {
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker const struct trim_case {
31*6777b538SAndroid Build Coastguard Worker   const wchar_t* input;
32*6777b538SAndroid Build Coastguard Worker   const TrimPositions positions;
33*6777b538SAndroid Build Coastguard Worker   const wchar_t* output;
34*6777b538SAndroid Build Coastguard Worker   const TrimPositions return_value;
35*6777b538SAndroid Build Coastguard Worker } trim_cases[] = {
36*6777b538SAndroid Build Coastguard Worker     {L" Google Video ", TRIM_LEADING, L"Google Video ", TRIM_LEADING},
37*6777b538SAndroid Build Coastguard Worker     {L" Google Video ", TRIM_TRAILING, L" Google Video", TRIM_TRAILING},
38*6777b538SAndroid Build Coastguard Worker     {L" Google Video ", TRIM_ALL, L"Google Video", TRIM_ALL},
39*6777b538SAndroid Build Coastguard Worker     {L"Google Video", TRIM_ALL, L"Google Video", TRIM_NONE},
40*6777b538SAndroid Build Coastguard Worker     {L"", TRIM_ALL, L"", TRIM_NONE},
41*6777b538SAndroid Build Coastguard Worker     {L"  ", TRIM_LEADING, L"", TRIM_LEADING},
42*6777b538SAndroid Build Coastguard Worker     {L"  ", TRIM_TRAILING, L"", TRIM_TRAILING},
43*6777b538SAndroid Build Coastguard Worker     {L"  ", TRIM_ALL, L"", TRIM_ALL},
44*6777b538SAndroid Build Coastguard Worker     {L"\t\rTest String\n", TRIM_ALL, L"Test String", TRIM_ALL},
45*6777b538SAndroid Build Coastguard Worker     {L"\x2002Test String\x00A0\x3000", TRIM_ALL, L"Test String", TRIM_ALL},
46*6777b538SAndroid Build Coastguard Worker };
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker const struct trim_case_ascii {
49*6777b538SAndroid Build Coastguard Worker   const char* input;
50*6777b538SAndroid Build Coastguard Worker   const TrimPositions positions;
51*6777b538SAndroid Build Coastguard Worker   const char* output;
52*6777b538SAndroid Build Coastguard Worker   const TrimPositions return_value;
53*6777b538SAndroid Build Coastguard Worker } trim_cases_ascii[] = {
54*6777b538SAndroid Build Coastguard Worker     {" Google Video ", TRIM_LEADING, "Google Video ", TRIM_LEADING},
55*6777b538SAndroid Build Coastguard Worker     {" Google Video ", TRIM_TRAILING, " Google Video", TRIM_TRAILING},
56*6777b538SAndroid Build Coastguard Worker     {" Google Video ", TRIM_ALL, "Google Video", TRIM_ALL},
57*6777b538SAndroid Build Coastguard Worker     {"Google Video", TRIM_ALL, "Google Video", TRIM_NONE},
58*6777b538SAndroid Build Coastguard Worker     {"", TRIM_ALL, "", TRIM_NONE},
59*6777b538SAndroid Build Coastguard Worker     {"  ", TRIM_LEADING, "", TRIM_LEADING},
60*6777b538SAndroid Build Coastguard Worker     {"  ", TRIM_TRAILING, "", TRIM_TRAILING},
61*6777b538SAndroid Build Coastguard Worker     {"  ", TRIM_ALL, "", TRIM_ALL},
62*6777b538SAndroid Build Coastguard Worker     {"\t\rTest String\n", TRIM_ALL, "Test String", TRIM_ALL},
63*6777b538SAndroid Build Coastguard Worker };
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker // Helper used to test TruncateUTF8ToByteSize.
Truncated(const std::string & input,const size_t byte_size,std::string * output)66*6777b538SAndroid Build Coastguard Worker bool Truncated(const std::string& input,
67*6777b538SAndroid Build Coastguard Worker                const size_t byte_size,
68*6777b538SAndroid Build Coastguard Worker                std::string* output) {
69*6777b538SAndroid Build Coastguard Worker     size_t prev = input.length();
70*6777b538SAndroid Build Coastguard Worker     TruncateUTF8ToByteSize(input, byte_size, output);
71*6777b538SAndroid Build Coastguard Worker     return prev != output->length();
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker using TestFunction = bool (*)(StringPiece str);
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker // Helper used to test IsStringUTF8[AllowingNoncharacters].
TestStructurallyValidUtf8(TestFunction fn)77*6777b538SAndroid Build Coastguard Worker void TestStructurallyValidUtf8(TestFunction fn) {
78*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("abc"));
79*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("\xC2\x81"));
80*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("\xE1\x80\xBF"));
81*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("\xF1\x80\xA0\xBF"));
82*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("\xF1\x80\xA0\xBF"));
83*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("a\xC2\x81\xE1\x80\xBF\xF1\x80\xA0\xBF"));
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker   // U+FEFF used as UTF-8 BOM.
86*6777b538SAndroid Build Coastguard Worker   // clang-format off
87*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn("\xEF\xBB\xBF" "abc"));
88*6777b538SAndroid Build Coastguard Worker   // clang-format on
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   // Embedded nulls in canonical UTF-8 representation.
91*6777b538SAndroid Build Coastguard Worker   using std::string_literals::operator""s;
92*6777b538SAndroid Build Coastguard Worker   const std::string kEmbeddedNull = "embedded\0null"s;
93*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(fn(kEmbeddedNull));
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker // Helper used to test IsStringUTF8[AllowingNoncharacters].
TestStructurallyInvalidUtf8(TestFunction fn)97*6777b538SAndroid Build Coastguard Worker void TestStructurallyInvalidUtf8(TestFunction fn) {
98*6777b538SAndroid Build Coastguard Worker   // Invalid encoding of U+1FFFE (0x8F instead of 0x9F)
99*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF0\x8F\xBF\xBE"));
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   // Surrogate code points
102*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xED\xA0\x80\xED\xBF\xBF"));
103*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xED\xA0\x8F"));
104*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xED\xBF\xBF"));
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   // Overlong sequences
107*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xC0\x80"));                  // U+0000
108*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xC1\x80\xC1\x81"));          // "AB"
109*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xE0\x80\x80"));              // U+0000
110*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xE0\x82\x80"));              // U+0080
111*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xE0\x9F\xBF"));              // U+07FF
112*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF0\x80\x80\x8D"));          // U+000D
113*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF0\x80\x82\x91"));          // U+0091
114*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF0\x80\xA0\x80"));          // U+0800
115*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF0\x8F\xBB\xBF"));          // U+FEFF (BOM)
116*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF8\x80\x80\x80\xBF"));      // U+003F
117*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xFC\x80\x80\x80\xA0\xA5"));  // U+00A5
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // Beyond U+10FFFF (the upper limit of Unicode codespace)
120*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF4\x90\x80\x80"));          // U+110000
121*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xF8\xA0\xBF\x80\xBF"));      // 5 bytes
122*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xFC\x9C\xBF\x80\xBF\x80"));  // 6 bytes
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker   // BOM in UTF-16(BE|LE)
125*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xFE\xFF"));
126*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xFF\xFE"));
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   // Strings in legacy encodings. We can certainly make up strings
129*6777b538SAndroid Build Coastguard Worker   // in a legacy encoding that are valid in UTF-8, but in real data,
130*6777b538SAndroid Build Coastguard Worker   // most of them are invalid as UTF-8.
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   // cafe with U+00E9 in ISO-8859-1
133*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("caf\xE9"));
134*6777b538SAndroid Build Coastguard Worker   // U+AC00, U+AC001 in EUC-KR
135*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xB0\xA1\xB0\xA2"));
136*6777b538SAndroid Build Coastguard Worker   // U+4F60 U+597D in Big5
137*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xA7\x41\xA6\x6E"));
138*6777b538SAndroid Build Coastguard Worker   // "abc" with U+201[CD] in windows-125[0-8]
139*6777b538SAndroid Build Coastguard Worker   // clang-format off
140*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\x93" "abc\x94"));
141*6777b538SAndroid Build Coastguard Worker   // clang-format on
142*6777b538SAndroid Build Coastguard Worker   // U+0639 U+064E U+0644 U+064E in ISO-8859-6
143*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xD9\xEE\xE4\xEE"));
144*6777b538SAndroid Build Coastguard Worker   // U+03B3 U+03B5 U+03B9 U+03AC in ISO-8859-7
145*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn("\xE3\xE5\xE9\xDC"));
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker   // BOM in UTF-32(BE|LE)
148*6777b538SAndroid Build Coastguard Worker   using std::string_literals::operator""s;
149*6777b538SAndroid Build Coastguard Worker   const std::string kUtf32BeBom = "\x00\x00\xFE\xFF"s;
150*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn(kUtf32BeBom));
151*6777b538SAndroid Build Coastguard Worker   const std::string kUtf32LeBom = "\xFF\xFE\x00\x00"s;
152*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(fn(kUtf32LeBom));
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker // Helper used to test IsStringUTF8[AllowingNoncharacters].
TestNoncharacters(TestFunction fn,bool expected_result)156*6777b538SAndroid Build Coastguard Worker void TestNoncharacters(TestFunction fn, bool expected_result) {
157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xEF\xB7\x90"), expected_result);      // U+FDD0
158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xEF\xB7\x9F"), expected_result);      // U+FDDF
159*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xEF\xB7\xAF"), expected_result);      // U+FDEF
160*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xEF\xBF\xBE"), expected_result);      // U+FFFE
161*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xEF\xBF\xBF"), expected_result);      // U+FFFF
162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\x9F\xBF\xBE"), expected_result);  // U+01FFFE
163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\x9F\xBF\xBF"), expected_result);  // U+01FFFF
164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\xAF\xBF\xBE"), expected_result);  // U+02FFFE
165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\xAF\xBF\xBF"), expected_result);  // U+02FFFF
166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\xBF\xBF\xBE"), expected_result);  // U+03FFFE
167*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF0\xBF\xBF\xBF"), expected_result);  // U+03FFFF
168*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\x8F\xBF\xBE"), expected_result);  // U+04FFFE
169*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\x8F\xBF\xBF"), expected_result);  // U+04FFFF
170*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\x9F\xBF\xBE"), expected_result);  // U+05FFFE
171*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\x9F\xBF\xBF"), expected_result);  // U+05FFFF
172*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\xAF\xBF\xBE"), expected_result);  // U+06FFFE
173*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\xAF\xBF\xBF"), expected_result);  // U+06FFFF
174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\xBF\xBF\xBE"), expected_result);  // U+07FFFE
175*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF1\xBF\xBF\xBF"), expected_result);  // U+07FFFF
176*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\x8F\xBF\xBE"), expected_result);  // U+08FFFE
177*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\x8F\xBF\xBF"), expected_result);  // U+08FFFF
178*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\x9F\xBF\xBE"), expected_result);  // U+09FFFE
179*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\x9F\xBF\xBF"), expected_result);  // U+09FFFF
180*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\xAF\xBF\xBE"), expected_result);  // U+0AFFFE
181*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\xAF\xBF\xBF"), expected_result);  // U+0AFFFF
182*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\xBF\xBF\xBE"), expected_result);  // U+0BFFFE
183*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF2\xBF\xBF\xBF"), expected_result);  // U+0BFFFF
184*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\x8F\xBF\xBE"), expected_result);  // U+0CFFFE
185*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\x8F\xBF\xBF"), expected_result);  // U+0CFFFF
186*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\x9F\xBF\xBE"), expected_result);  // U+0DFFFE
187*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\x9F\xBF\xBF"), expected_result);  // U+0DFFFF
188*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\xAF\xBF\xBE"), expected_result);  // U+0EFFFE
189*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\xAF\xBF\xBF"), expected_result);  // U+0EFFFF
190*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\xBF\xBF\xBE"), expected_result);  // U+0FFFFE
191*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF3\xBF\xBF\xBF"), expected_result);  // U+0FFFFF
192*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF4\x8F\xBF\xBE"), expected_result);  // U+10FFFE
193*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(fn("\xF4\x8F\xBF\xBF"), expected_result);  // U+10FFFF
194*6777b538SAndroid Build Coastguard Worker }
195*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,TruncateUTF8ToByteSize)196*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, TruncateUTF8ToByteSize) {
197*6777b538SAndroid Build Coastguard Worker   std::string output;
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   // Empty strings and invalid byte_size arguments
200*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated(std::string(), 0, &output));
201*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output, "");
202*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xe1\x80\xbf", 0, &output));
203*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output, "");
204*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xe1\x80\xbf", static_cast<size_t>(-1), &output));
205*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xe1\x80\xbf", 4, &output));
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   // Testing the truncation of valid UTF8 correctly
208*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("abc", 2, &output));
209*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output, "ab");
210*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xc2\x81\xc2\x81", 2, &output));
211*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xc2\x81"), 0);
212*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xc2\x81\xc2\x81", 3, &output));
213*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xc2\x81"), 0);
214*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xc2\x81\xc2\x81", 4, &output));
215*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xc2\x81\xc2\x81"), 0);
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   {
218*6777b538SAndroid Build Coastguard Worker     const char array[] = "\x00\x00\xc2\x81\xc2\x81";
219*6777b538SAndroid Build Coastguard Worker     const std::string array_string(array, std::size(array));
220*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(Truncated(array_string, 4, &output));
221*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(output.compare(std::string("\x00\x00\xc2\x81", 4)), 0);
222*6777b538SAndroid Build Coastguard Worker   }
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   {
225*6777b538SAndroid Build Coastguard Worker     const char array[] = "\x00\xc2\x81\xc2\x81";
226*6777b538SAndroid Build Coastguard Worker     const std::string array_string(array, std::size(array));
227*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(Truncated(array_string, 4, &output));
228*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(output.compare(std::string("\x00\xc2\x81", 3)), 0);
229*6777b538SAndroid Build Coastguard Worker   }
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker   // Testing invalid UTF8
232*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xed\xa0\x80\xed\xbf\xbf", 6, &output));
233*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
234*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xed\xa0\x8f", 3, &output));
235*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
236*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xed\xbf\xbf", 3, &output));
237*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
238*6777b538SAndroid Build Coastguard Worker 
239*6777b538SAndroid Build Coastguard Worker   // Testing invalid UTF8 mixed with valid UTF8
240*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xe1\x80\xbf", 3, &output));
241*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xe1\x80\xbf"), 0);
242*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xf1\x80\xa0\xbf", 4, &output));
243*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xf1\x80\xa0\xbf"), 0);
244*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf",
245*6777b538SAndroid Build Coastguard Worker               10, &output));
246*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"), 0);
247*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("a\xc2\x81\xe1\x80\xbf\xf1""a""\x80\xa0",
248*6777b538SAndroid Build Coastguard Worker               10, &output));
249*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("a\xc2\x81\xe1\x80\xbf\xf1""a"), 0);
250*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xef\xbb\xbf" "abc", 6, &output));
251*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xef\xbb\xbf" "abc"), 0);
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker   // Overlong sequences
254*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xc0\x80", 2, &output));
255*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
256*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xc1\x80\xc1\x81", 4, &output));
257*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
258*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xe0\x80\x80", 3, &output));
259*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
260*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xe0\x82\x80", 3, &output));
261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
262*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xe0\x9f\xbf", 3, &output));
263*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
264*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf0\x80\x80\x8D", 4, &output));
265*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
266*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf0\x80\x82\x91", 4, &output));
267*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
268*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf0\x80\xa0\x80", 4, &output));
269*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
270*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf0\x8f\xbb\xbf", 4, &output));
271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
272*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf8\x80\x80\x80\xbf", 5, &output));
273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
274*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xfc\x80\x80\x80\xa0\xa5", 6, &output));
275*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   // Beyond U+10FFFF (the upper limit of Unicode codespace)
278*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf4\x90\x80\x80", 4, &output));
279*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
280*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf8\xa0\xbf\x80\xbf", 5, &output));
281*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
282*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xfc\x9c\xbf\x80\xbf\x80", 6, &output));
283*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker   // BOMs in UTF-16(BE|LE) and UTF-32(BE|LE)
286*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xfe\xff", 2, &output));
287*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
288*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xff\xfe", 2, &output));
289*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker   {
292*6777b538SAndroid Build Coastguard Worker     const char array[] = "\x00\x00\xfe\xff";
293*6777b538SAndroid Build Coastguard Worker     const std::string array_string(array, std::size(array));
294*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(Truncated(array_string, 4, &output));
295*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(output.compare(std::string("\x00\x00", 2)), 0);
296*6777b538SAndroid Build Coastguard Worker   }
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker   // Variants on the previous test
299*6777b538SAndroid Build Coastguard Worker   {
300*6777b538SAndroid Build Coastguard Worker     const char array[] = "\xff\xfe\x00\x00";
301*6777b538SAndroid Build Coastguard Worker     const std::string array_string(array, 4);
302*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(Truncated(array_string, 4, &output));
303*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(output.compare(std::string("\xff\xfe\x00\x00", 4)), 0);
304*6777b538SAndroid Build Coastguard Worker   }
305*6777b538SAndroid Build Coastguard Worker   {
306*6777b538SAndroid Build Coastguard Worker     const char array[] = "\xff\x00\x00\xfe";
307*6777b538SAndroid Build Coastguard Worker     const std::string array_string(array, std::size(array));
308*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(Truncated(array_string, 4, &output));
309*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(output.compare(std::string("\xff\x00\x00", 3)), 0);
310*6777b538SAndroid Build Coastguard Worker   }
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker   // Non-characters : U+xxFFF[EF] where xx is 0x00 through 0x10 and <FDD0,FDEF>
313*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xef\xbf\xbe", 3, &output));
314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
315*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf0\x8f\xbf\xbe", 4, &output));
316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
317*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xf3\xbf\xbf\xbf", 4, &output));
318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
319*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xef\xb7\x90", 3, &output));
320*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
321*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xef\xb7\xaf", 3, &output));
322*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
323*6777b538SAndroid Build Coastguard Worker 
324*6777b538SAndroid Build Coastguard Worker   // Strings in legacy encodings that are valid in UTF-8, but
325*6777b538SAndroid Build Coastguard Worker   // are invalid as UTF-8 in real data.
326*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("caf\xe9", 4, &output));
327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("caf"), 0);
328*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xb0\xa1\xb0\xa2", 4, &output));
329*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
330*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated("\xa7\x41\xa6\x6e", 4, &output));
331*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
332*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xa7\x41\xa6\x6e\xd9\xee\xe4\xee", 7,
333*6777b538SAndroid Build Coastguard Worker               &output));
334*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker   // Testing using the same string as input and output.
337*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Truncated(output, 4, &output));
338*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xa7\x41\xa6\x6e"), 0);
339*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated(output, 3, &output));
340*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\xa7\x41"), 0);
341*6777b538SAndroid Build Coastguard Worker 
342*6777b538SAndroid Build Coastguard Worker   // "abc" with U+201[CD] in windows-125[0-8]
343*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\x93" "abc\x94", 5, &output));
344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare("\x93" "abc"), 0);
345*6777b538SAndroid Build Coastguard Worker 
346*6777b538SAndroid Build Coastguard Worker   // U+0639 U+064E U+0644 U+064E in ISO-8859-6
347*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xd9\xee\xe4\xee", 4, &output));
348*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
349*6777b538SAndroid Build Coastguard Worker 
350*6777b538SAndroid Build Coastguard Worker   // U+03B3 U+03B5 U+03B9 U+03AC in ISO-8859-7
351*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(Truncated("\xe3\xe5\xe9\xdC", 4, &output));
352*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(output.compare(""), 0);
353*6777b538SAndroid Build Coastguard Worker }
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_16_BIT)
TEST(StringUtilTest,as_wcstr)356*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, as_wcstr) {
357*6777b538SAndroid Build Coastguard Worker   char16_t rw_buffer[10] = {};
358*6777b538SAndroid Build Coastguard Worker   static_assert(
359*6777b538SAndroid Build Coastguard Worker       std::is_same_v<wchar_t*, decltype(as_writable_wcstr(rw_buffer))>, "");
360*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<void*>(rw_buffer), as_writable_wcstr(rw_buffer));
361*6777b538SAndroid Build Coastguard Worker 
362*6777b538SAndroid Build Coastguard Worker   std::u16string rw_str(10, '\0');
363*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<wchar_t*, decltype(as_writable_wcstr(rw_str))>,
364*6777b538SAndroid Build Coastguard Worker                 "");
365*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(rw_str.data()), as_writable_wcstr(rw_str));
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker   const char16_t ro_buffer[10] = {};
368*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<const wchar_t*, decltype(as_wcstr(ro_buffer))>,
369*6777b538SAndroid Build Coastguard Worker                 "");
370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(ro_buffer), as_wcstr(ro_buffer));
371*6777b538SAndroid Build Coastguard Worker 
372*6777b538SAndroid Build Coastguard Worker   const std::u16string ro_str(10, '\0');
373*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<const wchar_t*, decltype(as_wcstr(ro_str))>, "");
374*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(ro_str.data()), as_wcstr(ro_str));
375*6777b538SAndroid Build Coastguard Worker 
376*6777b538SAndroid Build Coastguard Worker   StringPiece16 piece = ro_buffer;
377*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<const wchar_t*, decltype(as_wcstr(piece))>, "");
378*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(piece.data()), as_wcstr(piece));
379*6777b538SAndroid Build Coastguard Worker }
380*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,as_u16cstr)381*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, as_u16cstr) {
382*6777b538SAndroid Build Coastguard Worker   wchar_t rw_buffer[10] = {};
383*6777b538SAndroid Build Coastguard Worker   static_assert(
384*6777b538SAndroid Build Coastguard Worker       std::is_same_v<char16_t*, decltype(as_writable_u16cstr(rw_buffer))>, "");
385*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<void*>(rw_buffer), as_writable_u16cstr(rw_buffer));
386*6777b538SAndroid Build Coastguard Worker 
387*6777b538SAndroid Build Coastguard Worker   std::wstring rw_str(10, '\0');
388*6777b538SAndroid Build Coastguard Worker   static_assert(
389*6777b538SAndroid Build Coastguard Worker       std::is_same_v<char16_t*, decltype(as_writable_u16cstr(rw_str))>, "");
390*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(rw_str.data()),
391*6777b538SAndroid Build Coastguard Worker             as_writable_u16cstr(rw_str));
392*6777b538SAndroid Build Coastguard Worker 
393*6777b538SAndroid Build Coastguard Worker   const wchar_t ro_buffer[10] = {};
394*6777b538SAndroid Build Coastguard Worker   static_assert(
395*6777b538SAndroid Build Coastguard Worker       std::is_same_v<const char16_t*, decltype(as_u16cstr(ro_buffer))>, "");
396*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(ro_buffer), as_u16cstr(ro_buffer));
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker   const std::wstring ro_str(10, '\0');
399*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<const char16_t*, decltype(as_u16cstr(ro_str))>,
400*6777b538SAndroid Build Coastguard Worker                 "");
401*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(ro_str.data()), as_u16cstr(ro_str));
402*6777b538SAndroid Build Coastguard Worker 
403*6777b538SAndroid Build Coastguard Worker   std::wstring_view piece = ro_buffer;
404*6777b538SAndroid Build Coastguard Worker   static_assert(std::is_same_v<const char16_t*, decltype(as_u16cstr(piece))>,
405*6777b538SAndroid Build Coastguard Worker                 "");
406*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<const void*>(piece.data()), as_u16cstr(piece));
407*6777b538SAndroid Build Coastguard Worker }
408*6777b538SAndroid Build Coastguard Worker #endif  // defined(WCHAR_T_IS_16_BIT)
409*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,TrimWhitespace)410*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, TrimWhitespace) {
411*6777b538SAndroid Build Coastguard Worker   std::u16string output;  // Allow contents to carry over to next testcase
412*6777b538SAndroid Build Coastguard Worker   for (const auto& value : trim_cases) {
413*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(value.return_value,
414*6777b538SAndroid Build Coastguard Worker               TrimWhitespace(WideToUTF16(value.input), value.positions,
415*6777b538SAndroid Build Coastguard Worker                              &output));
416*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(WideToUTF16(value.output), output);
417*6777b538SAndroid Build Coastguard Worker   }
418*6777b538SAndroid Build Coastguard Worker 
419*6777b538SAndroid Build Coastguard Worker   // Test that TrimWhitespace() can take the same string for input and output
420*6777b538SAndroid Build Coastguard Worker   output = u"  This is a test \r\n";
421*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TRIM_ALL, TrimWhitespace(output, TRIM_ALL, &output));
422*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"This is a test", output);
423*6777b538SAndroid Build Coastguard Worker 
424*6777b538SAndroid Build Coastguard Worker   // Once more, but with a string of whitespace
425*6777b538SAndroid Build Coastguard Worker   output = u"  \r\n";
426*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(TRIM_ALL, TrimWhitespace(output, TRIM_ALL, &output));
427*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), output);
428*6777b538SAndroid Build Coastguard Worker 
429*6777b538SAndroid Build Coastguard Worker   std::string output_ascii;
430*6777b538SAndroid Build Coastguard Worker   for (const auto& value : trim_cases_ascii) {
431*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(value.return_value,
432*6777b538SAndroid Build Coastguard Worker               TrimWhitespaceASCII(value.input, value.positions, &output_ascii));
433*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(value.output, output_ascii);
434*6777b538SAndroid Build Coastguard Worker   }
435*6777b538SAndroid Build Coastguard Worker }
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker static const struct collapse_case {
438*6777b538SAndroid Build Coastguard Worker   const wchar_t* input;
439*6777b538SAndroid Build Coastguard Worker   const bool trim;
440*6777b538SAndroid Build Coastguard Worker   const wchar_t* output;
441*6777b538SAndroid Build Coastguard Worker } collapse_cases[] = {
442*6777b538SAndroid Build Coastguard Worker   {L" Google Video ", false, L"Google Video"},
443*6777b538SAndroid Build Coastguard Worker   {L"Google Video", false, L"Google Video"},
444*6777b538SAndroid Build Coastguard Worker   {L"", false, L""},
445*6777b538SAndroid Build Coastguard Worker   {L"  ", false, L""},
446*6777b538SAndroid Build Coastguard Worker   {L"\t\rTest String\n", false, L"Test String"},
447*6777b538SAndroid Build Coastguard Worker   {L"\x2002Test String\x00A0\x3000", false, L"Test String"},
448*6777b538SAndroid Build Coastguard Worker   {L"    Test     \n  \t String    ", false, L"Test String"},
449*6777b538SAndroid Build Coastguard Worker   {L"\x2002Test\x1680 \x2028 \tString\x00A0\x3000", false, L"Test String"},
450*6777b538SAndroid Build Coastguard Worker   {L"   Test String", false, L"Test String"},
451*6777b538SAndroid Build Coastguard Worker   {L"Test String    ", false, L"Test String"},
452*6777b538SAndroid Build Coastguard Worker   {L"Test String", false, L"Test String"},
453*6777b538SAndroid Build Coastguard Worker   {L"", true, L""},
454*6777b538SAndroid Build Coastguard Worker   {L"\n", true, L""},
455*6777b538SAndroid Build Coastguard Worker   {L"  \r  ", true, L""},
456*6777b538SAndroid Build Coastguard Worker   {L"\nFoo", true, L"Foo"},
457*6777b538SAndroid Build Coastguard Worker   {L"\r  Foo  ", true, L"Foo"},
458*6777b538SAndroid Build Coastguard Worker   {L" Foo bar ", true, L"Foo bar"},
459*6777b538SAndroid Build Coastguard Worker   {L"  \tFoo  bar  \n", true, L"Foo bar"},
460*6777b538SAndroid Build Coastguard Worker   {L" a \r b\n c \r\n d \t\re \t f \n ", true, L"abcde f"},
461*6777b538SAndroid Build Coastguard Worker };
462*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,CollapseWhitespace)463*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, CollapseWhitespace) {
464*6777b538SAndroid Build Coastguard Worker   for (const auto& value : collapse_cases) {
465*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(WideToUTF16(value.output),
466*6777b538SAndroid Build Coastguard Worker               CollapseWhitespace(WideToUTF16(value.input), value.trim));
467*6777b538SAndroid Build Coastguard Worker   }
468*6777b538SAndroid Build Coastguard Worker }
469*6777b538SAndroid Build Coastguard Worker 
470*6777b538SAndroid Build Coastguard Worker static const struct collapse_case_ascii {
471*6777b538SAndroid Build Coastguard Worker   const char* input;
472*6777b538SAndroid Build Coastguard Worker   const bool trim;
473*6777b538SAndroid Build Coastguard Worker   const char* output;
474*6777b538SAndroid Build Coastguard Worker } collapse_cases_ascii[] = {
475*6777b538SAndroid Build Coastguard Worker     {" Google Video ", false, "Google Video"},
476*6777b538SAndroid Build Coastguard Worker     {"Google Video", false, "Google Video"},
477*6777b538SAndroid Build Coastguard Worker     {"", false, ""},
478*6777b538SAndroid Build Coastguard Worker     {"  ", false, ""},
479*6777b538SAndroid Build Coastguard Worker     {"\t\rTest String\n", false, "Test String"},
480*6777b538SAndroid Build Coastguard Worker     {"    Test     \n  \t String    ", false, "Test String"},
481*6777b538SAndroid Build Coastguard Worker     {"   Test String", false, "Test String"},
482*6777b538SAndroid Build Coastguard Worker     {"Test String    ", false, "Test String"},
483*6777b538SAndroid Build Coastguard Worker     {"Test String", false, "Test String"},
484*6777b538SAndroid Build Coastguard Worker     {"", true, ""},
485*6777b538SAndroid Build Coastguard Worker     {"\n", true, ""},
486*6777b538SAndroid Build Coastguard Worker     {"  \r  ", true, ""},
487*6777b538SAndroid Build Coastguard Worker     {"\nFoo", true, "Foo"},
488*6777b538SAndroid Build Coastguard Worker     {"\r  Foo  ", true, "Foo"},
489*6777b538SAndroid Build Coastguard Worker     {" Foo bar ", true, "Foo bar"},
490*6777b538SAndroid Build Coastguard Worker     // \u00A0 is whitespace, but not _ASCII_ whitespace, so it should not be
491*6777b538SAndroid Build Coastguard Worker     // collapsed by CollapseWhitespaceASCII().
492*6777b538SAndroid Build Coastguard Worker     {"Foo\u00A0bar", true, "Foo\u00A0bar"},
493*6777b538SAndroid Build Coastguard Worker     {"  \tFoo  bar  \n", true, "Foo bar"},
494*6777b538SAndroid Build Coastguard Worker     {" a \r b\n c \r\n d \t\re \t f \n ", true, "abcde f"},
495*6777b538SAndroid Build Coastguard Worker };
496*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,CollapseWhitespaceASCII)497*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, CollapseWhitespaceASCII) {
498*6777b538SAndroid Build Coastguard Worker   for (const auto& value : collapse_cases_ascii) {
499*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(value.output, CollapseWhitespaceASCII(value.input, value.trim));
500*6777b538SAndroid Build Coastguard Worker   }
501*6777b538SAndroid Build Coastguard Worker }
502*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,IsStringUTF8)503*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, IsStringUTF8) {
504*6777b538SAndroid Build Coastguard Worker   {
505*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE("IsStringUTF8");
506*6777b538SAndroid Build Coastguard Worker     TestStructurallyValidUtf8(&IsStringUTF8);
507*6777b538SAndroid Build Coastguard Worker     TestStructurallyInvalidUtf8(&IsStringUTF8);
508*6777b538SAndroid Build Coastguard Worker     TestNoncharacters(&IsStringUTF8, false);
509*6777b538SAndroid Build Coastguard Worker   }
510*6777b538SAndroid Build Coastguard Worker 
511*6777b538SAndroid Build Coastguard Worker   {
512*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE("IsStringUTF8AllowingNoncharacters");
513*6777b538SAndroid Build Coastguard Worker     TestStructurallyValidUtf8(&IsStringUTF8AllowingNoncharacters);
514*6777b538SAndroid Build Coastguard Worker     TestStructurallyInvalidUtf8(&IsStringUTF8AllowingNoncharacters);
515*6777b538SAndroid Build Coastguard Worker     TestNoncharacters(&IsStringUTF8AllowingNoncharacters, true);
516*6777b538SAndroid Build Coastguard Worker   }
517*6777b538SAndroid Build Coastguard Worker }
518*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,IsStringASCII)519*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, IsStringASCII) {
520*6777b538SAndroid Build Coastguard Worker   static char char_ascii[] =
521*6777b538SAndroid Build Coastguard Worker       "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
522*6777b538SAndroid Build Coastguard Worker   static char16_t char16_ascii[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
523*6777b538SAndroid Build Coastguard Worker                                     '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', '0',
524*6777b538SAndroid Build Coastguard Worker                                     '1', '2', '3', '4', '5', '6', '7', '8', '9',
525*6777b538SAndroid Build Coastguard Worker                                     '0', 'A', 'B', 'C', 'D', 'E', 'F', 0};
526*6777b538SAndroid Build Coastguard Worker   static std::wstring wchar_ascii(
527*6777b538SAndroid Build Coastguard Worker       L"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF");
528*6777b538SAndroid Build Coastguard Worker 
529*6777b538SAndroid Build Coastguard Worker   // Test a variety of the fragment start positions and lengths in order to make
530*6777b538SAndroid Build Coastguard Worker   // sure that bit masking in IsStringASCII works correctly.
531*6777b538SAndroid Build Coastguard Worker   // Also, test that a non-ASCII character will be detected regardless of its
532*6777b538SAndroid Build Coastguard Worker   // position inside the string.
533*6777b538SAndroid Build Coastguard Worker   {
534*6777b538SAndroid Build Coastguard Worker     const size_t string_length = std::size(char_ascii) - 1;
535*6777b538SAndroid Build Coastguard Worker     for (size_t offset = 0; offset < 8; ++offset) {
536*6777b538SAndroid Build Coastguard Worker       for (size_t len = 0, max_len = string_length - offset; len < max_len;
537*6777b538SAndroid Build Coastguard Worker            ++len) {
538*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(IsStringASCII(StringPiece(char_ascii + offset, len)));
539*6777b538SAndroid Build Coastguard Worker         for (size_t char_pos = offset; char_pos < len; ++char_pos) {
540*6777b538SAndroid Build Coastguard Worker           char_ascii[char_pos] |= '\x80';
541*6777b538SAndroid Build Coastguard Worker           EXPECT_FALSE(IsStringASCII(StringPiece(char_ascii + offset, len)));
542*6777b538SAndroid Build Coastguard Worker           char_ascii[char_pos] &= ~'\x80';
543*6777b538SAndroid Build Coastguard Worker         }
544*6777b538SAndroid Build Coastguard Worker       }
545*6777b538SAndroid Build Coastguard Worker     }
546*6777b538SAndroid Build Coastguard Worker   }
547*6777b538SAndroid Build Coastguard Worker 
548*6777b538SAndroid Build Coastguard Worker   {
549*6777b538SAndroid Build Coastguard Worker     const size_t string_length = std::size(char16_ascii) - 1;
550*6777b538SAndroid Build Coastguard Worker     for (size_t offset = 0; offset < 4; ++offset) {
551*6777b538SAndroid Build Coastguard Worker       for (size_t len = 0, max_len = string_length - offset; len < max_len;
552*6777b538SAndroid Build Coastguard Worker            ++len) {
553*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(IsStringASCII(StringPiece16(char16_ascii + offset, len)));
554*6777b538SAndroid Build Coastguard Worker         for (size_t char_pos = offset; char_pos < len; ++char_pos) {
555*6777b538SAndroid Build Coastguard Worker           char16_ascii[char_pos] |= 0x80;
556*6777b538SAndroid Build Coastguard Worker           EXPECT_FALSE(
557*6777b538SAndroid Build Coastguard Worker               IsStringASCII(StringPiece16(char16_ascii + offset, len)));
558*6777b538SAndroid Build Coastguard Worker           char16_ascii[char_pos] &= ~0x80;
559*6777b538SAndroid Build Coastguard Worker           // Also test when the upper half is non-zero.
560*6777b538SAndroid Build Coastguard Worker           char16_ascii[char_pos] |= 0x100;
561*6777b538SAndroid Build Coastguard Worker           EXPECT_FALSE(
562*6777b538SAndroid Build Coastguard Worker               IsStringASCII(StringPiece16(char16_ascii + offset, len)));
563*6777b538SAndroid Build Coastguard Worker           char16_ascii[char_pos] &= ~0x100;
564*6777b538SAndroid Build Coastguard Worker         }
565*6777b538SAndroid Build Coastguard Worker       }
566*6777b538SAndroid Build Coastguard Worker     }
567*6777b538SAndroid Build Coastguard Worker   }
568*6777b538SAndroid Build Coastguard Worker 
569*6777b538SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_32_BIT)
570*6777b538SAndroid Build Coastguard Worker   {
571*6777b538SAndroid Build Coastguard Worker     const size_t string_length = wchar_ascii.length();
572*6777b538SAndroid Build Coastguard Worker     for (size_t len = 0; len < string_length; ++len) {
573*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(IsStringASCII(wchar_ascii.substr(0, len)));
574*6777b538SAndroid Build Coastguard Worker       for (size_t char_pos = 0; char_pos < len; ++char_pos) {
575*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] |= 0x80;
576*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(IsStringASCII(wchar_ascii.substr(0, len)));
577*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] &= ~0x80;
578*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] |= 0x100;
579*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(IsStringASCII(wchar_ascii.substr(0, len)));
580*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] &= ~0x100;
581*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] |= 0x10000;
582*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(IsStringASCII(wchar_ascii.substr(0, len)));
583*6777b538SAndroid Build Coastguard Worker         wchar_ascii[char_pos] &= ~0x10000;
584*6777b538SAndroid Build Coastguard Worker       }
585*6777b538SAndroid Build Coastguard Worker     }
586*6777b538SAndroid Build Coastguard Worker   }
587*6777b538SAndroid Build Coastguard Worker #endif  // WCHAR_T_IS_32_BIT
588*6777b538SAndroid Build Coastguard Worker }
589*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ConvertASCII)590*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ConvertASCII) {
591*6777b538SAndroid Build Coastguard Worker   static const char* const char_cases[] = {
592*6777b538SAndroid Build Coastguard Worker     "Google Video",
593*6777b538SAndroid Build Coastguard Worker     "Hello, world\n",
594*6777b538SAndroid Build Coastguard Worker     "0123ABCDwxyz \a\b\t\r\n!+,.~"
595*6777b538SAndroid Build Coastguard Worker   };
596*6777b538SAndroid Build Coastguard Worker 
597*6777b538SAndroid Build Coastguard Worker   static const wchar_t* const wchar_cases[] = {
598*6777b538SAndroid Build Coastguard Worker     L"Google Video",
599*6777b538SAndroid Build Coastguard Worker     L"Hello, world\n",
600*6777b538SAndroid Build Coastguard Worker     L"0123ABCDwxyz \a\b\t\r\n!+,.~"
601*6777b538SAndroid Build Coastguard Worker   };
602*6777b538SAndroid Build Coastguard Worker 
603*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(char_cases); ++i) {
604*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(IsStringASCII(char_cases[i]));
605*6777b538SAndroid Build Coastguard Worker     std::u16string utf16 = ASCIIToUTF16(char_cases[i]);
606*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(WideToUTF16(wchar_cases[i]), utf16);
607*6777b538SAndroid Build Coastguard Worker 
608*6777b538SAndroid Build Coastguard Worker     std::string ascii = UTF16ToASCII(WideToUTF16(wchar_cases[i]));
609*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(char_cases[i], ascii);
610*6777b538SAndroid Build Coastguard Worker   }
611*6777b538SAndroid Build Coastguard Worker 
612*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsStringASCII("Google \x80Video"));
613*6777b538SAndroid Build Coastguard Worker 
614*6777b538SAndroid Build Coastguard Worker   // Convert empty strings.
615*6777b538SAndroid Build Coastguard Worker   std::u16string empty16;
616*6777b538SAndroid Build Coastguard Worker   std::string empty;
617*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(empty, UTF16ToASCII(empty16));
618*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(empty16, ASCIIToUTF16(empty));
619*6777b538SAndroid Build Coastguard Worker 
620*6777b538SAndroid Build Coastguard Worker   // Convert strings with an embedded NUL character.
621*6777b538SAndroid Build Coastguard Worker   const char chars_with_nul[] = "test\0string";
622*6777b538SAndroid Build Coastguard Worker   const int length_with_nul = std::size(chars_with_nul) - 1;
623*6777b538SAndroid Build Coastguard Worker   std::string string_with_nul(chars_with_nul, length_with_nul);
624*6777b538SAndroid Build Coastguard Worker   std::u16string string16_with_nul = ASCIIToUTF16(string_with_nul);
625*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<std::u16string::size_type>(length_with_nul),
626*6777b538SAndroid Build Coastguard Worker             string16_with_nul.length());
627*6777b538SAndroid Build Coastguard Worker   std::string narrow_with_nul = UTF16ToASCII(string16_with_nul);
628*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<std::string::size_type>(length_with_nul),
629*6777b538SAndroid Build Coastguard Worker             narrow_with_nul.length());
630*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, string_with_nul.compare(narrow_with_nul));
631*6777b538SAndroid Build Coastguard Worker }
632*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ToLowerASCII)633*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ToLowerASCII) {
634*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('c', ToLowerASCII('C'));
635*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('c', ToLowerASCII('c'));
636*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('2', ToLowerASCII('2'));
637*6777b538SAndroid Build Coastguard Worker 
638*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'c', ToLowerASCII(u'C'));
639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'c', ToLowerASCII(u'c'));
640*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'2', ToLowerASCII(u'2'));
641*6777b538SAndroid Build Coastguard Worker 
642*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("cc2", ToLowerASCII("Cc2"));
643*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"cc2", ToLowerASCII(u"Cc2"));
644*6777b538SAndroid Build Coastguard Worker 
645*6777b538SAndroid Build Coastguard Worker   // Non-ASCII characters are unmodified. U+00C4 is LATIN CAPITAL LETTER A WITH
646*6777b538SAndroid Build Coastguard Worker   // DIAERESIS.
647*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('\xc4', ToLowerASCII('\xc4'));
648*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'\x00c4', ToLowerASCII(u'\x00c4'));
649*6777b538SAndroid Build Coastguard Worker }
650*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ToUpperASCII)651*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ToUpperASCII) {
652*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('C', ToUpperASCII('C'));
653*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('C', ToUpperASCII('c'));
654*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('2', ToUpperASCII('2'));
655*6777b538SAndroid Build Coastguard Worker 
656*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'C', ToUpperASCII(u'C'));
657*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'C', ToUpperASCII(u'c'));
658*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'2', ToUpperASCII(u'2'));
659*6777b538SAndroid Build Coastguard Worker 
660*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("CC2", ToUpperASCII("Cc2"));
661*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"CC2", ToUpperASCII(u"Cc2"));
662*6777b538SAndroid Build Coastguard Worker 
663*6777b538SAndroid Build Coastguard Worker   // Non-ASCII characters are unmodified. U+00E4 is LATIN SMALL LETTER A WITH
664*6777b538SAndroid Build Coastguard Worker   // DIAERESIS.
665*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ('\xe4', ToUpperASCII('\xe4'));
666*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u'\x00e4', ToUpperASCII(u'\x00e4'));
667*6777b538SAndroid Build Coastguard Worker }
668*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,FormatBytesUnlocalized)669*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, FormatBytesUnlocalized) {
670*6777b538SAndroid Build Coastguard Worker   static const struct {
671*6777b538SAndroid Build Coastguard Worker     int64_t bytes;
672*6777b538SAndroid Build Coastguard Worker     const char* expected;
673*6777b538SAndroid Build Coastguard Worker   } cases[] = {
674*6777b538SAndroid Build Coastguard Worker       // Expected behavior: we show one post-decimal digit when we have
675*6777b538SAndroid Build Coastguard Worker       // under two pre-decimal digits, except in cases where it makes no
676*6777b538SAndroid Build Coastguard Worker       // sense (zero or bytes).
677*6777b538SAndroid Build Coastguard Worker       // Since we switch units once we cross the 1000 mark, this keeps
678*6777b538SAndroid Build Coastguard Worker       // the display of file sizes or bytes consistently around three
679*6777b538SAndroid Build Coastguard Worker       // digits.
680*6777b538SAndroid Build Coastguard Worker       {0, "0 B"},
681*6777b538SAndroid Build Coastguard Worker       {512, "512 B"},
682*6777b538SAndroid Build Coastguard Worker       {1024 * 1024, "1.0 MB"},
683*6777b538SAndroid Build Coastguard Worker       {1024 * 1024 * 1024, "1.0 GB"},
684*6777b538SAndroid Build Coastguard Worker       {10LL * 1024 * 1024 * 1024, "10.0 GB"},
685*6777b538SAndroid Build Coastguard Worker       {99LL * 1024 * 1024 * 1024, "99.0 GB"},
686*6777b538SAndroid Build Coastguard Worker       {105LL * 1024 * 1024 * 1024, "105 GB"},
687*6777b538SAndroid Build Coastguard Worker       {105LL * 1024 * 1024 * 1024 + 500LL * 1024 * 1024, "105 GB"},
688*6777b538SAndroid Build Coastguard Worker       {~(bits::LeftmostBit<int64_t>()), "8192 PB"},
689*6777b538SAndroid Build Coastguard Worker 
690*6777b538SAndroid Build Coastguard Worker       {99 * 1024 + 103, "99.1 kB"},
691*6777b538SAndroid Build Coastguard Worker       {1024 * 1024 + 103, "1.0 MB"},
692*6777b538SAndroid Build Coastguard Worker       {1024 * 1024 + 205 * 1024, "1.2 MB"},
693*6777b538SAndroid Build Coastguard Worker       {1024 * 1024 * 1024 + (927 * 1024 * 1024), "1.9 GB"},
694*6777b538SAndroid Build Coastguard Worker       {10LL * 1024 * 1024 * 1024, "10.0 GB"},
695*6777b538SAndroid Build Coastguard Worker       {100LL * 1024 * 1024 * 1024, "100 GB"},
696*6777b538SAndroid Build Coastguard Worker   };
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker   for (const auto& i : cases) {
699*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ASCIIToUTF16(i.expected), FormatBytesUnlocalized(i.bytes));
700*6777b538SAndroid Build Coastguard Worker   }
701*6777b538SAndroid Build Coastguard Worker }
TEST(StringUtilTest,ReplaceSubstringsAfterOffset)702*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceSubstringsAfterOffset) {
703*6777b538SAndroid Build Coastguard Worker   static const struct {
704*6777b538SAndroid Build Coastguard Worker     StringPiece str;
705*6777b538SAndroid Build Coastguard Worker     size_t start_offset;
706*6777b538SAndroid Build Coastguard Worker     StringPiece find_this;
707*6777b538SAndroid Build Coastguard Worker     StringPiece replace_with;
708*6777b538SAndroid Build Coastguard Worker     StringPiece expected;
709*6777b538SAndroid Build Coastguard Worker   } cases[] = {
710*6777b538SAndroid Build Coastguard Worker       {"aaa", 0, "", "b", "aaa"},
711*6777b538SAndroid Build Coastguard Worker       {"aaa", 1, "", "b", "aaa"},
712*6777b538SAndroid Build Coastguard Worker       {"aaa", 0, "a", "b", "bbb"},
713*6777b538SAndroid Build Coastguard Worker       {"aaa", 0, "aa", "b", "ba"},
714*6777b538SAndroid Build Coastguard Worker       {"aaa", 0, "aa", "bbb", "bbba"},
715*6777b538SAndroid Build Coastguard Worker       {"aaaaa", 0, "aa", "b", "bba"},
716*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "", "baaba"},
717*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "_", "_baa_ba"},
718*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "__", "__baa__ba"},
719*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "___", "___baa___ba"},
720*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "____", "____baa____ba"},
721*6777b538SAndroid Build Coastguard Worker       {"ababaaababa", 0, "aba", "_____", "_____baa_____ba"},
722*6777b538SAndroid Build Coastguard Worker       {"abb", 0, "ab", "a", "ab"},
723*6777b538SAndroid Build Coastguard Worker       {"Removing some substrings inging", 0, "ing", "", "Remov some substrs "},
724*6777b538SAndroid Build Coastguard Worker       {"Not found", 0, "x", "0", "Not found"},
725*6777b538SAndroid Build Coastguard Worker       {"Not found again", 5, "x", "0", "Not found again"},
726*6777b538SAndroid Build Coastguard Worker       {" Making it much longer ", 0, " ", "Four score and seven years ago",
727*6777b538SAndroid Build Coastguard Worker        "Four score and seven years agoMakingFour score and seven years agoit"
728*6777b538SAndroid Build Coastguard Worker        "Four score and seven years agomuchFour score and seven years agolonger"
729*6777b538SAndroid Build Coastguard Worker        "Four score and seven years ago"},
730*6777b538SAndroid Build Coastguard Worker       {" Making it much much much much shorter ", 0,
731*6777b538SAndroid Build Coastguard Worker        "Making it much much much much shorter", "", "  "},
732*6777b538SAndroid Build Coastguard Worker       {"so much much much much much very much much much shorter", 0, "much ",
733*6777b538SAndroid Build Coastguard Worker        "", "so very shorter"},
734*6777b538SAndroid Build Coastguard Worker       {"Invalid offset", 9999, "t", "foobar", "Invalid offset"},
735*6777b538SAndroid Build Coastguard Worker       {"Replace me only me once", 9, "me ", "", "Replace me only once"},
736*6777b538SAndroid Build Coastguard Worker       {"abababab", 2, "ab", "c", "abccc"},
737*6777b538SAndroid Build Coastguard Worker       {"abababab", 1, "ab", "c", "abccc"},
738*6777b538SAndroid Build Coastguard Worker       {"abababab", 1, "aba", "c", "abcbab"},
739*6777b538SAndroid Build Coastguard Worker   };
740*6777b538SAndroid Build Coastguard Worker 
741*6777b538SAndroid Build Coastguard Worker   // std::u16string variant
742*6777b538SAndroid Build Coastguard Worker   for (const auto& scenario : cases) {
743*6777b538SAndroid Build Coastguard Worker     std::u16string str = ASCIIToUTF16(scenario.str);
744*6777b538SAndroid Build Coastguard Worker     ReplaceSubstringsAfterOffset(&str, scenario.start_offset,
745*6777b538SAndroid Build Coastguard Worker                                  ASCIIToUTF16(scenario.find_this),
746*6777b538SAndroid Build Coastguard Worker                                  ASCIIToUTF16(scenario.replace_with));
747*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ASCIIToUTF16(scenario.expected), str);
748*6777b538SAndroid Build Coastguard Worker   }
749*6777b538SAndroid Build Coastguard Worker 
750*6777b538SAndroid Build Coastguard Worker   // std::string with insufficient capacity: expansion must realloc the buffer.
751*6777b538SAndroid Build Coastguard Worker   for (const auto& scenario : cases) {
752*6777b538SAndroid Build Coastguard Worker     std::string str(scenario.str);
753*6777b538SAndroid Build Coastguard Worker     str.shrink_to_fit();  // This is nonbinding, but it's the best we've got.
754*6777b538SAndroid Build Coastguard Worker     ReplaceSubstringsAfterOffset(&str, scenario.start_offset,
755*6777b538SAndroid Build Coastguard Worker                                  scenario.find_this, scenario.replace_with);
756*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.expected, str);
757*6777b538SAndroid Build Coastguard Worker   }
758*6777b538SAndroid Build Coastguard Worker 
759*6777b538SAndroid Build Coastguard Worker   // std::string with ample capacity: should be possible to grow in-place.
760*6777b538SAndroid Build Coastguard Worker   for (const auto& scenario : cases) {
761*6777b538SAndroid Build Coastguard Worker     std::string str(scenario.str);
762*6777b538SAndroid Build Coastguard Worker     str.reserve(std::max(scenario.str.length(), scenario.expected.length()) *
763*6777b538SAndroid Build Coastguard Worker                 2);
764*6777b538SAndroid Build Coastguard Worker 
765*6777b538SAndroid Build Coastguard Worker     ReplaceSubstringsAfterOffset(&str, scenario.start_offset,
766*6777b538SAndroid Build Coastguard Worker                                  scenario.find_this, scenario.replace_with);
767*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.expected, str);
768*6777b538SAndroid Build Coastguard Worker   }
769*6777b538SAndroid Build Coastguard Worker }
770*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceFirstSubstringAfterOffset)771*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceFirstSubstringAfterOffset) {
772*6777b538SAndroid Build Coastguard Worker   static const struct {
773*6777b538SAndroid Build Coastguard Worker     const char* str;
774*6777b538SAndroid Build Coastguard Worker     std::u16string::size_type start_offset;
775*6777b538SAndroid Build Coastguard Worker     const char* find_this;
776*6777b538SAndroid Build Coastguard Worker     const char* replace_with;
777*6777b538SAndroid Build Coastguard Worker     const char* expected;
778*6777b538SAndroid Build Coastguard Worker   } cases[] = {
779*6777b538SAndroid Build Coastguard Worker     {"aaa", 0, "a", "b", "baa"},
780*6777b538SAndroid Build Coastguard Worker     {"abb", 0, "ab", "a", "ab"},
781*6777b538SAndroid Build Coastguard Worker     {"Removing some substrings inging", 0, "ing", "",
782*6777b538SAndroid Build Coastguard Worker       "Remov some substrings inging"},
783*6777b538SAndroid Build Coastguard Worker     {"Not found", 0, "x", "0", "Not found"},
784*6777b538SAndroid Build Coastguard Worker     {"Not found again", 5, "x", "0", "Not found again"},
785*6777b538SAndroid Build Coastguard Worker     {" Making it much longer ", 0, " ", "Four score and seven years ago",
786*6777b538SAndroid Build Coastguard Worker      "Four score and seven years agoMaking it much longer "},
787*6777b538SAndroid Build Coastguard Worker     {"Invalid offset", 9999, "t", "foobar", "Invalid offset"},
788*6777b538SAndroid Build Coastguard Worker     {"Replace me only me once", 4, "me ", "", "Replace only me once"},
789*6777b538SAndroid Build Coastguard Worker     {"abababab", 2, "ab", "c", "abcabab"},
790*6777b538SAndroid Build Coastguard Worker   };
791*6777b538SAndroid Build Coastguard Worker 
792*6777b538SAndroid Build Coastguard Worker   for (const auto& i : cases) {
793*6777b538SAndroid Build Coastguard Worker     std::u16string str = ASCIIToUTF16(i.str);
794*6777b538SAndroid Build Coastguard Worker     ReplaceFirstSubstringAfterOffset(&str, i.start_offset,
795*6777b538SAndroid Build Coastguard Worker                                      ASCIIToUTF16(i.find_this),
796*6777b538SAndroid Build Coastguard Worker                                      ASCIIToUTF16(i.replace_with));
797*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ASCIIToUTF16(i.expected), str);
798*6777b538SAndroid Build Coastguard Worker   }
799*6777b538SAndroid Build Coastguard Worker }
800*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,HexDigitToInt)801*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, HexDigitToInt) {
802*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, HexDigitToInt('0'));
803*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, HexDigitToInt('1'));
804*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, HexDigitToInt('2'));
805*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, HexDigitToInt('3'));
806*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, HexDigitToInt('4'));
807*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, HexDigitToInt('5'));
808*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(6, HexDigitToInt('6'));
809*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(7, HexDigitToInt('7'));
810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(8, HexDigitToInt('8'));
811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(9, HexDigitToInt('9'));
812*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, HexDigitToInt('A'));
813*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(11, HexDigitToInt('B'));
814*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(12, HexDigitToInt('C'));
815*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(13, HexDigitToInt('D'));
816*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(14, HexDigitToInt('E'));
817*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(15, HexDigitToInt('F'));
818*6777b538SAndroid Build Coastguard Worker 
819*6777b538SAndroid Build Coastguard Worker   // Verify the lower case as well.
820*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(10, HexDigitToInt('a'));
821*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(11, HexDigitToInt('b'));
822*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(12, HexDigitToInt('c'));
823*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(13, HexDigitToInt('d'));
824*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(14, HexDigitToInt('e'));
825*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(15, HexDigitToInt('f'));
826*6777b538SAndroid Build Coastguard Worker }
827*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinString)828*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinString) {
829*6777b538SAndroid Build Coastguard Worker   std::string separator(", ");
830*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> parts;
831*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString(parts, separator));
832*6777b538SAndroid Build Coastguard Worker 
833*6777b538SAndroid Build Coastguard Worker   parts.push_back(std::string());
834*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString(parts, separator));
835*6777b538SAndroid Build Coastguard Worker   parts.clear();
836*6777b538SAndroid Build Coastguard Worker 
837*6777b538SAndroid Build Coastguard Worker   parts.push_back("a");
838*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a", JoinString(parts, separator));
839*6777b538SAndroid Build Coastguard Worker 
840*6777b538SAndroid Build Coastguard Worker   parts.push_back("b");
841*6777b538SAndroid Build Coastguard Worker   parts.push_back("c");
842*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c", JoinString(parts, separator));
843*6777b538SAndroid Build Coastguard Worker 
844*6777b538SAndroid Build Coastguard Worker   parts.push_back(std::string());
845*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c, ", JoinString(parts, separator));
846*6777b538SAndroid Build Coastguard Worker   parts.push_back(" ");
847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a|b|c|| ", JoinString(parts, "|"));
848*6777b538SAndroid Build Coastguard Worker }
849*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinString16)850*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinString16) {
851*6777b538SAndroid Build Coastguard Worker   std::u16string separator = u", ";
852*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> parts;
853*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString(parts, separator));
854*6777b538SAndroid Build Coastguard Worker 
855*6777b538SAndroid Build Coastguard Worker   parts.push_back(std::u16string());
856*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString(parts, separator));
857*6777b538SAndroid Build Coastguard Worker   parts.clear();
858*6777b538SAndroid Build Coastguard Worker 
859*6777b538SAndroid Build Coastguard Worker   parts.push_back(u"a");
860*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a", JoinString(parts, separator));
861*6777b538SAndroid Build Coastguard Worker 
862*6777b538SAndroid Build Coastguard Worker   parts.push_back(u"b");
863*6777b538SAndroid Build Coastguard Worker   parts.push_back(u"c");
864*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c", JoinString(parts, separator));
865*6777b538SAndroid Build Coastguard Worker 
866*6777b538SAndroid Build Coastguard Worker   parts.push_back(u"");
867*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c, ", JoinString(parts, separator));
868*6777b538SAndroid Build Coastguard Worker   parts.push_back(u" ");
869*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a|b|c|| ", JoinString(parts, u"|"));
870*6777b538SAndroid Build Coastguard Worker }
871*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinStringPiece)872*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinStringPiece) {
873*6777b538SAndroid Build Coastguard Worker   std::string separator(", ");
874*6777b538SAndroid Build Coastguard Worker   std::vector<StringPiece> parts;
875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString(parts, separator));
876*6777b538SAndroid Build Coastguard Worker 
877*6777b538SAndroid Build Coastguard Worker   // Test empty first part (https://crbug.com/698073).
878*6777b538SAndroid Build Coastguard Worker   parts.push_back(StringPiece());
879*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString(parts, separator));
880*6777b538SAndroid Build Coastguard Worker   parts.clear();
881*6777b538SAndroid Build Coastguard Worker 
882*6777b538SAndroid Build Coastguard Worker   parts.push_back("a");
883*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a", JoinString(parts, separator));
884*6777b538SAndroid Build Coastguard Worker 
885*6777b538SAndroid Build Coastguard Worker   parts.push_back("b");
886*6777b538SAndroid Build Coastguard Worker   parts.push_back("c");
887*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c", JoinString(parts, separator));
888*6777b538SAndroid Build Coastguard Worker 
889*6777b538SAndroid Build Coastguard Worker   parts.push_back(StringPiece());
890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c, ", JoinString(parts, separator));
891*6777b538SAndroid Build Coastguard Worker   parts.push_back(" ");
892*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a|b|c|| ", JoinString(parts, "|"));
893*6777b538SAndroid Build Coastguard Worker }
894*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinStringPiece16)895*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinStringPiece16) {
896*6777b538SAndroid Build Coastguard Worker   std::u16string separator = u", ";
897*6777b538SAndroid Build Coastguard Worker   std::vector<StringPiece16> parts;
898*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString(parts, separator));
899*6777b538SAndroid Build Coastguard Worker 
900*6777b538SAndroid Build Coastguard Worker   // Test empty first part (https://crbug.com/698073).
901*6777b538SAndroid Build Coastguard Worker   parts.push_back(StringPiece16());
902*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString(parts, separator));
903*6777b538SAndroid Build Coastguard Worker   parts.clear();
904*6777b538SAndroid Build Coastguard Worker 
905*6777b538SAndroid Build Coastguard Worker   const std::u16string kA = u"a";
906*6777b538SAndroid Build Coastguard Worker   parts.push_back(kA);
907*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a", JoinString(parts, separator));
908*6777b538SAndroid Build Coastguard Worker 
909*6777b538SAndroid Build Coastguard Worker   const std::u16string kB = u"b";
910*6777b538SAndroid Build Coastguard Worker   parts.push_back(kB);
911*6777b538SAndroid Build Coastguard Worker   const std::u16string kC = u"c";
912*6777b538SAndroid Build Coastguard Worker   parts.push_back(kC);
913*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c", JoinString(parts, separator));
914*6777b538SAndroid Build Coastguard Worker 
915*6777b538SAndroid Build Coastguard Worker   parts.push_back(StringPiece16());
916*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c, ", JoinString(parts, separator));
917*6777b538SAndroid Build Coastguard Worker   const std::u16string kSpace = u" ";
918*6777b538SAndroid Build Coastguard Worker   parts.push_back(kSpace);
919*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a|b|c|| ", JoinString(parts, u"|"));
920*6777b538SAndroid Build Coastguard Worker }
921*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinStringInitializerList)922*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinStringInitializerList) {
923*6777b538SAndroid Build Coastguard Worker   std::string separator(", ");
924*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString({}, separator));
925*6777b538SAndroid Build Coastguard Worker 
926*6777b538SAndroid Build Coastguard Worker   // Test empty first part (https://crbug.com/698073).
927*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), JoinString({StringPiece()}, separator));
928*6777b538SAndroid Build Coastguard Worker 
929*6777b538SAndroid Build Coastguard Worker   // With const char*s.
930*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a", JoinString({"a"}, separator));
931*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c", JoinString({"a", "b", "c"}, separator));
932*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b, c, ", JoinString({"a", "b", "c", StringPiece()}, separator));
933*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a|b|c|| ", JoinString({"a", "b", "c", StringPiece(), " "}, "|"));
934*6777b538SAndroid Build Coastguard Worker 
935*6777b538SAndroid Build Coastguard Worker   // With std::strings.
936*6777b538SAndroid Build Coastguard Worker   const std::string kA = "a";
937*6777b538SAndroid Build Coastguard Worker   const std::string kB = "b";
938*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b", JoinString({kA, kB}, separator));
939*6777b538SAndroid Build Coastguard Worker 
940*6777b538SAndroid Build Coastguard Worker   // With StringPieces.
941*6777b538SAndroid Build Coastguard Worker   const StringPiece kPieceA = kA;
942*6777b538SAndroid Build Coastguard Worker   const StringPiece kPieceB = kB;
943*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("a, b", JoinString({kPieceA, kPieceB}, separator));
944*6777b538SAndroid Build Coastguard Worker }
945*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,JoinStringInitializerList16)946*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, JoinStringInitializerList16) {
947*6777b538SAndroid Build Coastguard Worker   std::u16string separator = u", ";
948*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString({}, separator));
949*6777b538SAndroid Build Coastguard Worker 
950*6777b538SAndroid Build Coastguard Worker   // Test empty first part (https://crbug.com/698073).
951*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::u16string(), JoinString({StringPiece16()}, separator));
952*6777b538SAndroid Build Coastguard Worker 
953*6777b538SAndroid Build Coastguard Worker   // With string16s.
954*6777b538SAndroid Build Coastguard Worker   const std::u16string kA = u"a";
955*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a", JoinString({kA}, separator));
956*6777b538SAndroid Build Coastguard Worker 
957*6777b538SAndroid Build Coastguard Worker   const std::u16string kB = u"b";
958*6777b538SAndroid Build Coastguard Worker   const std::u16string kC = u"c";
959*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c", JoinString({kA, kB, kC}, separator));
960*6777b538SAndroid Build Coastguard Worker 
961*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b, c, ", JoinString({kA, kB, kC, StringPiece16()}, separator));
962*6777b538SAndroid Build Coastguard Worker   const std::u16string kSpace = u" ";
963*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a|b|c|| ",
964*6777b538SAndroid Build Coastguard Worker             JoinString({kA, kB, kC, StringPiece16(), kSpace}, u"|"));
965*6777b538SAndroid Build Coastguard Worker 
966*6777b538SAndroid Build Coastguard Worker   // With StringPiece16s.
967*6777b538SAndroid Build Coastguard Worker   const StringPiece16 kPieceA = kA;
968*6777b538SAndroid Build Coastguard Worker   const StringPiece16 kPieceB = kB;
969*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"a, b", JoinString({kPieceA, kPieceB}, separator));
970*6777b538SAndroid Build Coastguard Worker }
971*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,StartsWith)972*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, StartsWith) {
973*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith("javascript:url", "javascript",
974*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::SENSITIVE));
975*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith("JavaScript:url", "javascript",
976*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::SENSITIVE));
977*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith("javascript:url", "javascript",
978*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
979*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith("JavaScript:url", "javascript",
980*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
981*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith("java", "javascript", base::CompareCase::SENSITIVE));
982*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith("java", "javascript",
983*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::INSENSITIVE_ASCII));
984*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith(std::string(), "javascript",
985*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::INSENSITIVE_ASCII));
986*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith(std::string(), "javascript",
987*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::SENSITIVE));
988*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith("java", std::string(),
989*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
990*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith("java", std::string(), base::CompareCase::SENSITIVE));
991*6777b538SAndroid Build Coastguard Worker 
992*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith(u"javascript:url", u"javascript",
993*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::SENSITIVE));
994*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith(u"JavaScript:url", u"javascript",
995*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::SENSITIVE));
996*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith(u"javascript:url", u"javascript",
997*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
998*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith(u"JavaScript:url", u"javascript",
999*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
1000*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1001*6777b538SAndroid Build Coastguard Worker       StartsWith(u"java", u"javascript", base::CompareCase::SENSITIVE));
1002*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1003*6777b538SAndroid Build Coastguard Worker       StartsWith(u"java", u"javascript", base::CompareCase::INSENSITIVE_ASCII));
1004*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith(std::u16string(), u"javascript",
1005*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::INSENSITIVE_ASCII));
1006*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StartsWith(std::u16string(), u"javascript",
1007*6777b538SAndroid Build Coastguard Worker                           base::CompareCase::SENSITIVE));
1008*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StartsWith(u"java", std::u16string(),
1009*6777b538SAndroid Build Coastguard Worker                          base::CompareCase::INSENSITIVE_ASCII));
1010*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1011*6777b538SAndroid Build Coastguard Worker       StartsWith(u"java", std::u16string(), base::CompareCase::SENSITIVE));
1012*6777b538SAndroid Build Coastguard Worker }
1013*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,EndsWith)1014*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, EndsWith) {
1015*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1016*6777b538SAndroid Build Coastguard Worker       EndsWith(u"Foo.plugin", u".plugin", base::CompareCase::SENSITIVE));
1017*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1018*6777b538SAndroid Build Coastguard Worker       EndsWith(u"Foo.Plugin", u".plugin", base::CompareCase::SENSITIVE));
1019*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(u"Foo.plugin", u".plugin",
1020*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::INSENSITIVE_ASCII));
1021*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(u"Foo.Plugin", u".plugin",
1022*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::INSENSITIVE_ASCII));
1023*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EndsWith(u".plug", u".plugin", base::CompareCase::SENSITIVE));
1024*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1025*6777b538SAndroid Build Coastguard Worker       EndsWith(u".plug", u".plugin", base::CompareCase::INSENSITIVE_ASCII));
1026*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1027*6777b538SAndroid Build Coastguard Worker       EndsWith(u"Foo.plugin Bar", u".plugin", base::CompareCase::SENSITIVE));
1028*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EndsWith(u"Foo.plugin Bar", u".plugin",
1029*6777b538SAndroid Build Coastguard Worker                         base::CompareCase::INSENSITIVE_ASCII));
1030*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EndsWith(std::u16string(), u".plugin",
1031*6777b538SAndroid Build Coastguard Worker                         base::CompareCase::INSENSITIVE_ASCII));
1032*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
1033*6777b538SAndroid Build Coastguard Worker       EndsWith(std::u16string(), u".plugin", base::CompareCase::SENSITIVE));
1034*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(u"Foo.plugin", std::u16string(),
1035*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::INSENSITIVE_ASCII));
1036*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1037*6777b538SAndroid Build Coastguard Worker       EndsWith(u"Foo.plugin", std::u16string(), base::CompareCase::SENSITIVE));
1038*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(
1039*6777b538SAndroid Build Coastguard Worker       EndsWith(u".plugin", u".plugin", base::CompareCase::INSENSITIVE_ASCII));
1040*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(u".plugin", u".plugin", base::CompareCase::SENSITIVE));
1041*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(std::u16string(), std::u16string(),
1042*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::INSENSITIVE_ASCII));
1043*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EndsWith(std::u16string(), std::u16string(),
1044*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::SENSITIVE));
1045*6777b538SAndroid Build Coastguard Worker }
1046*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,GetStringFWithOffsets)1047*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, GetStringFWithOffsets) {
1048*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1049*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"1");
1050*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"2");
1051*6777b538SAndroid Build Coastguard Worker   std::vector<size_t> offsets;
1052*6777b538SAndroid Build Coastguard Worker 
1053*6777b538SAndroid Build Coastguard Worker   ReplaceStringPlaceholders(u"Hello, $1. Your number is $2.", subst, &offsets);
1054*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, offsets.size());
1055*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(7U, offsets[0]);
1056*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25U, offsets[1]);
1057*6777b538SAndroid Build Coastguard Worker   offsets.clear();
1058*6777b538SAndroid Build Coastguard Worker 
1059*6777b538SAndroid Build Coastguard Worker   ReplaceStringPlaceholders(u"Hello, $2. Your number is $1.", subst, &offsets);
1060*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, offsets.size());
1061*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(25U, offsets[0]);
1062*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(7U, offsets[1]);
1063*6777b538SAndroid Build Coastguard Worker   offsets.clear();
1064*6777b538SAndroid Build Coastguard Worker }
1065*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersTooFew)1066*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersTooFew) {
1067*6777b538SAndroid Build Coastguard Worker   // Test whether replacestringplaceholders works as expected when there
1068*6777b538SAndroid Build Coastguard Worker   // are fewer inputs than outputs.
1069*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1070*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"9a");
1071*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"8b");
1072*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"7c");
1073*6777b538SAndroid Build Coastguard Worker 
1074*6777b538SAndroid Build Coastguard Worker   std::u16string formatted = ReplaceStringPlaceholders(
1075*6777b538SAndroid Build Coastguard Worker       u"$1a,$2b,$3c,$4d,$5e,$6f,$1g,$2h,$3i", subst, nullptr);
1076*6777b538SAndroid Build Coastguard Worker 
1077*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"9aa,8bb,7cc,d,e,f,9ag,8bh,7ci", formatted);
1078*6777b538SAndroid Build Coastguard Worker }
1079*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholders)1080*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholders) {
1081*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1082*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"9a");
1083*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"8b");
1084*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"7c");
1085*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"6d");
1086*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"5e");
1087*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"4f");
1088*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"3g");
1089*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"2h");
1090*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"1i");
1091*6777b538SAndroid Build Coastguard Worker 
1092*6777b538SAndroid Build Coastguard Worker   std::u16string formatted = ReplaceStringPlaceholders(
1093*6777b538SAndroid Build Coastguard Worker       u"$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i", subst, nullptr);
1094*6777b538SAndroid Build Coastguard Worker 
1095*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"9aa,8bb,7cc,6dd,5ee,4ff,3gg,2hh,1ii", formatted);
1096*6777b538SAndroid Build Coastguard Worker }
1097*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersNetExpansionWithContraction)1098*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersNetExpansionWithContraction) {
1099*6777b538SAndroid Build Coastguard Worker   // In this test, some of the substitutions are shorter than the placeholders,
1100*6777b538SAndroid Build Coastguard Worker   // but overall the string gets longer.
1101*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1102*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"9a____");
1103*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"B");
1104*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"7c___");
1105*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"d");
1106*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"5e____");
1107*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"F");
1108*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"3g___");
1109*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"h");
1110*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"1i_____");
1111*6777b538SAndroid Build Coastguard Worker 
1112*6777b538SAndroid Build Coastguard Worker   std::u16string original = u"$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i";
1113*6777b538SAndroid Build Coastguard Worker   std::u16string expected =
1114*6777b538SAndroid Build Coastguard Worker       u"9a____a,Bb,7c___c,dd,5e____e,Ff,3g___g,hh,1i_____i";
1115*6777b538SAndroid Build Coastguard Worker 
1116*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, ReplaceStringPlaceholders(original, subst, nullptr));
1117*6777b538SAndroid Build Coastguard Worker 
1118*6777b538SAndroid Build Coastguard Worker   std::vector<size_t> offsets;
1119*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, ReplaceStringPlaceholders(original, subst, &offsets));
1120*6777b538SAndroid Build Coastguard Worker   std::vector<size_t> expected_offsets = {0, 8, 11, 18, 21, 29, 32, 39, 42};
1121*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(offsets.size(), subst.size());
1122*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_offsets, offsets);
1123*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < offsets.size(); i++) {
1124*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected.substr(expected_offsets[i], subst[i].length()),
1125*6777b538SAndroid Build Coastguard Worker               subst[i]);
1126*6777b538SAndroid Build Coastguard Worker   }
1127*6777b538SAndroid Build Coastguard Worker }
1128*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersNetContractionWithExpansion)1129*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersNetContractionWithExpansion) {
1130*6777b538SAndroid Build Coastguard Worker   // In this test, some of the substitutions are longer than the placeholders,
1131*6777b538SAndroid Build Coastguard Worker   // but overall the string gets smaller. Additionally, the placeholders appear
1132*6777b538SAndroid Build Coastguard Worker   // in a permuted order.
1133*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1134*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"z");
1135*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"y");
1136*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"XYZW");
1137*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"x");
1138*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"w");
1139*6777b538SAndroid Build Coastguard Worker 
1140*6777b538SAndroid Build Coastguard Worker   std::u16string formatted =
1141*6777b538SAndroid Build Coastguard Worker       ReplaceStringPlaceholders(u"$3_$4$2$1$5", subst, nullptr);
1142*6777b538SAndroid Build Coastguard Worker 
1143*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"XYZW_xyzw", formatted);
1144*6777b538SAndroid Build Coastguard Worker }
1145*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersOneDigit)1146*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersOneDigit) {
1147*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1148*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"1a");
1149*6777b538SAndroid Build Coastguard Worker   std::u16string formatted =
1150*6777b538SAndroid Build Coastguard Worker       ReplaceStringPlaceholders(u" $16 ", subst, nullptr);
1151*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u" 1a6 ", formatted);
1152*6777b538SAndroid Build Coastguard Worker }
1153*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersInvalidPlaceholder)1154*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersInvalidPlaceholder) {
1155*6777b538SAndroid Build Coastguard Worker   std::vector<std::u16string> subst;
1156*6777b538SAndroid Build Coastguard Worker   subst.push_back(u"1a");
1157*6777b538SAndroid Build Coastguard Worker   std::u16string formatted =
1158*6777b538SAndroid Build Coastguard Worker       ReplaceStringPlaceholders(u"+$-+$A+$1+", subst, nullptr);
1159*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(u"+++1a+", formatted);
1160*6777b538SAndroid Build Coastguard Worker }
1161*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,StdStringReplaceStringPlaceholders)1162*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, StdStringReplaceStringPlaceholders) {
1163*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> subst;
1164*6777b538SAndroid Build Coastguard Worker   subst.push_back("9a");
1165*6777b538SAndroid Build Coastguard Worker   subst.push_back("8b");
1166*6777b538SAndroid Build Coastguard Worker   subst.push_back("7c");
1167*6777b538SAndroid Build Coastguard Worker   subst.push_back("6d");
1168*6777b538SAndroid Build Coastguard Worker   subst.push_back("5e");
1169*6777b538SAndroid Build Coastguard Worker   subst.push_back("4f");
1170*6777b538SAndroid Build Coastguard Worker   subst.push_back("3g");
1171*6777b538SAndroid Build Coastguard Worker   subst.push_back("2h");
1172*6777b538SAndroid Build Coastguard Worker   subst.push_back("1i");
1173*6777b538SAndroid Build Coastguard Worker 
1174*6777b538SAndroid Build Coastguard Worker   std::string formatted =
1175*6777b538SAndroid Build Coastguard Worker       ReplaceStringPlaceholders(
1176*6777b538SAndroid Build Coastguard Worker           "$1a,$2b,$3c,$4d,$5e,$6f,$7g,$8h,$9i", subst, nullptr);
1177*6777b538SAndroid Build Coastguard Worker 
1178*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("9aa,8bb,7cc,6dd,5ee,4ff,3gg,2hh,1ii", formatted);
1179*6777b538SAndroid Build Coastguard Worker }
1180*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,StdStringReplaceStringPlaceholdersMultipleMatches)1181*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, StdStringReplaceStringPlaceholdersMultipleMatches) {
1182*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> subst;
1183*6777b538SAndroid Build Coastguard Worker   subst.push_back("4");   // Referenced twice.
1184*6777b538SAndroid Build Coastguard Worker   subst.push_back("?");   // Unreferenced.
1185*6777b538SAndroid Build Coastguard Worker   subst.push_back("!");   // Unreferenced.
1186*6777b538SAndroid Build Coastguard Worker   subst.push_back("16");  // Referenced once.
1187*6777b538SAndroid Build Coastguard Worker 
1188*6777b538SAndroid Build Coastguard Worker   std::string original = "$1 * $1 == $4";
1189*6777b538SAndroid Build Coastguard Worker   std::string expected = "4 * 4 == 16";
1190*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, ReplaceStringPlaceholders(original, subst, nullptr));
1191*6777b538SAndroid Build Coastguard Worker   std::vector<size_t> offsets;
1192*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected, ReplaceStringPlaceholders(original, subst, &offsets));
1193*6777b538SAndroid Build Coastguard Worker   std::vector<size_t> expected_offsets = {0, 4, 9};
1194*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_offsets, offsets);
1195*6777b538SAndroid Build Coastguard Worker }
1196*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceStringPlaceholdersConsecutiveDollarSigns)1197*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceStringPlaceholdersConsecutiveDollarSigns) {
1198*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> subst;
1199*6777b538SAndroid Build Coastguard Worker   subst.push_back("a");
1200*6777b538SAndroid Build Coastguard Worker   subst.push_back("b");
1201*6777b538SAndroid Build Coastguard Worker   subst.push_back("c");
1202*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ReplaceStringPlaceholders("$$1 $$$2 $$$$3", subst, nullptr),
1203*6777b538SAndroid Build Coastguard Worker             "$1 $$2 $$$3");
1204*6777b538SAndroid Build Coastguard Worker }
1205*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,LcpyTest)1206*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, LcpyTest) {
1207*6777b538SAndroid Build Coastguard Worker   // Test the normal case where we fit in our buffer.
1208*6777b538SAndroid Build Coastguard Worker   {
1209*6777b538SAndroid Build Coastguard Worker     char dst[10];
1210*6777b538SAndroid Build Coastguard Worker     char16_t u16dst[10];
1211*6777b538SAndroid Build Coastguard Worker     wchar_t wdst[10];
1212*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
1213*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(dst, "abcdefg", sizeof(dst[0]) * 8));
1214*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
1215*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(u16dst, u"abcdefg", sizeof(u16dst[0]) * 8));
1216*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
1217*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wdst[0]) * 8));
1218*6777b538SAndroid Build Coastguard Worker   }
1219*6777b538SAndroid Build Coastguard Worker 
1220*6777b538SAndroid Build Coastguard Worker   // Test dst_size == 0, nothing should be written to |dst| and we should
1221*6777b538SAndroid Build Coastguard Worker   // have the equivalent of strlen(src).
1222*6777b538SAndroid Build Coastguard Worker   {
1223*6777b538SAndroid Build Coastguard Worker     char dst[2] = {1, 2};
1224*6777b538SAndroid Build Coastguard Worker     char16_t u16dst[2] = {1, 2};
1225*6777b538SAndroid Build Coastguard Worker     wchar_t wdst[2] = {1, 2};
1226*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", 0));
1227*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(1, dst[0]);
1228*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(2, dst[1]);
1229*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", 0));
1230*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(char16_t{1}, u16dst[0]);
1231*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(char16_t{2}, u16dst[1]);
1232*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", 0));
1233*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<wchar_t>(1), wdst[0]);
1234*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<wchar_t>(2), wdst[1]);
1235*6777b538SAndroid Build Coastguard Worker   }
1236*6777b538SAndroid Build Coastguard Worker 
1237*6777b538SAndroid Build Coastguard Worker   // Test the case were we _just_ competely fit including the null.
1238*6777b538SAndroid Build Coastguard Worker   {
1239*6777b538SAndroid Build Coastguard Worker     char dst[8];
1240*6777b538SAndroid Build Coastguard Worker     char16_t u16dst[8];
1241*6777b538SAndroid Build Coastguard Worker     wchar_t wdst[8];
1242*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
1243*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
1244*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
1245*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(u16dst, u"abcdefg", sizeof(u16dst)));
1246*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
1247*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wdst)));
1248*6777b538SAndroid Build Coastguard Worker   }
1249*6777b538SAndroid Build Coastguard Worker 
1250*6777b538SAndroid Build Coastguard Worker   // Test the case were we we are one smaller, so we can't fit the null.
1251*6777b538SAndroid Build Coastguard Worker   {
1252*6777b538SAndroid Build Coastguard Worker     char dst[7];
1253*6777b538SAndroid Build Coastguard Worker     char16_t u16dst[7];
1254*6777b538SAndroid Build Coastguard Worker     wchar_t wdst[7];
1255*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
1256*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(dst, "abcdef", sizeof(dst[0]) * 7));
1257*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
1258*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(u16dst, u"abcdef", sizeof(u16dst[0]) * 7));
1259*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
1260*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(wdst, L"abcdef", sizeof(wdst[0]) * 7));
1261*6777b538SAndroid Build Coastguard Worker   }
1262*6777b538SAndroid Build Coastguard Worker 
1263*6777b538SAndroid Build Coastguard Worker   // Test the case were we are just too small.
1264*6777b538SAndroid Build Coastguard Worker   {
1265*6777b538SAndroid Build Coastguard Worker     char dst[3];
1266*6777b538SAndroid Build Coastguard Worker     char16_t u16dst[3];
1267*6777b538SAndroid Build Coastguard Worker     wchar_t wdst[3];
1268*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
1269*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(dst, "ab", sizeof(dst)));
1270*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
1271*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(u16dst, u"ab", sizeof(u16dst)));
1272*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
1273*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(wdst, L"ab", sizeof(wdst)));
1274*6777b538SAndroid Build Coastguard Worker   }
1275*6777b538SAndroid Build Coastguard Worker }
1276*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,WprintfFormatPortabilityTest)1277*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, WprintfFormatPortabilityTest) {
1278*6777b538SAndroid Build Coastguard Worker   static const struct {
1279*6777b538SAndroid Build Coastguard Worker     const wchar_t* input;
1280*6777b538SAndroid Build Coastguard Worker     bool portable;
1281*6777b538SAndroid Build Coastguard Worker   } cases[] = {
1282*6777b538SAndroid Build Coastguard Worker     { L"%ls", true },
1283*6777b538SAndroid Build Coastguard Worker     { L"%s", false },
1284*6777b538SAndroid Build Coastguard Worker     { L"%S", false },
1285*6777b538SAndroid Build Coastguard Worker     { L"%lS", false },
1286*6777b538SAndroid Build Coastguard Worker     { L"Hello, %s", false },
1287*6777b538SAndroid Build Coastguard Worker     { L"%lc", true },
1288*6777b538SAndroid Build Coastguard Worker     { L"%c", false },
1289*6777b538SAndroid Build Coastguard Worker     { L"%C", false },
1290*6777b538SAndroid Build Coastguard Worker     { L"%lC", false },
1291*6777b538SAndroid Build Coastguard Worker     { L"%ls %s", false },
1292*6777b538SAndroid Build Coastguard Worker     { L"%s %ls", false },
1293*6777b538SAndroid Build Coastguard Worker     { L"%s %ls %s", false },
1294*6777b538SAndroid Build Coastguard Worker     { L"%f", true },
1295*6777b538SAndroid Build Coastguard Worker     { L"%f %F", false },
1296*6777b538SAndroid Build Coastguard Worker     { L"%d %D", false },
1297*6777b538SAndroid Build Coastguard Worker     { L"%o %O", false },
1298*6777b538SAndroid Build Coastguard Worker     { L"%u %U", false },
1299*6777b538SAndroid Build Coastguard Worker     { L"%f %d %o %u", true },
1300*6777b538SAndroid Build Coastguard Worker     { L"%-8d (%02.1f%)", true },
1301*6777b538SAndroid Build Coastguard Worker     { L"% 10s", false },
1302*6777b538SAndroid Build Coastguard Worker     { L"% 10ls", true }
1303*6777b538SAndroid Build Coastguard Worker   };
1304*6777b538SAndroid Build Coastguard Worker   for (const auto& i : cases)
1305*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(i.portable, IsWprintfFormatPortable(i.input));
1306*6777b538SAndroid Build Coastguard Worker }
1307*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,MakeBasicStringPieceTest)1308*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, MakeBasicStringPieceTest) {
1309*6777b538SAndroid Build Coastguard Worker   constexpr char kFoo[] = "Foo";
1310*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece(kFoo, kFoo + 3) == kFoo, "");
1311*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece(kFoo, kFoo + 3).data() == kFoo, "");
1312*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece(kFoo, kFoo + 3).size() == 3, "");
1313*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece(kFoo + 3, kFoo + 3).empty(), "");
1314*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece(kFoo + 4, kFoo + 4).empty(), "");
1315*6777b538SAndroid Build Coastguard Worker 
1316*6777b538SAndroid Build Coastguard Worker   std::string foo = kFoo;
1317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece(foo.begin(), foo.end()), foo);
1318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece(foo.begin(), foo.end()).data(), foo.data());
1319*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece(foo.begin(), foo.end()).size(), foo.size());
1320*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MakeStringPiece(foo.end(), foo.end()).empty());
1321*6777b538SAndroid Build Coastguard Worker 
1322*6777b538SAndroid Build Coastguard Worker   constexpr char16_t kBar[] = u"Bar";
1323*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece16(kBar, kBar + 3) == kBar, "");
1324*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece16(kBar, kBar + 3).data() == kBar, "");
1325*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece16(kBar, kBar + 3).size() == 3, "");
1326*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece16(kBar + 3, kBar + 3).empty(), "");
1327*6777b538SAndroid Build Coastguard Worker   static_assert(MakeStringPiece16(kBar + 4, kBar + 4).empty(), "");
1328*6777b538SAndroid Build Coastguard Worker 
1329*6777b538SAndroid Build Coastguard Worker   std::u16string bar = kBar;
1330*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece16(bar.begin(), bar.end()), bar);
1331*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece16(bar.begin(), bar.end()).data(), bar.data());
1332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeStringPiece16(bar.begin(), bar.end()).size(), bar.size());
1333*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MakeStringPiece16(bar.end(), bar.end()).empty());
1334*6777b538SAndroid Build Coastguard Worker 
1335*6777b538SAndroid Build Coastguard Worker   constexpr wchar_t kBaz[] = L"Baz";
1336*6777b538SAndroid Build Coastguard Worker   static_assert(MakeWStringView(kBaz, kBaz + 3) == kBaz, "");
1337*6777b538SAndroid Build Coastguard Worker   static_assert(MakeWStringView(kBaz, kBaz + 3).data() == kBaz, "");
1338*6777b538SAndroid Build Coastguard Worker   static_assert(MakeWStringView(kBaz, kBaz + 3).size() == 3, "");
1339*6777b538SAndroid Build Coastguard Worker   static_assert(MakeWStringView(kBaz + 3, kBaz + 3).empty(), "");
1340*6777b538SAndroid Build Coastguard Worker   static_assert(MakeWStringView(kBaz + 4, kBaz + 4).empty(), "");
1341*6777b538SAndroid Build Coastguard Worker 
1342*6777b538SAndroid Build Coastguard Worker   std::wstring baz = kBaz;
1343*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeWStringView(baz.begin(), baz.end()), baz);
1344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeWStringView(baz.begin(), baz.end()).data(), baz.data());
1345*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MakeWStringView(baz.begin(), baz.end()).size(), baz.size());
1346*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(MakeWStringView(baz.end(), baz.end()).empty());
1347*6777b538SAndroid Build Coastguard Worker }
1348*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,RemoveChars)1349*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, RemoveChars) {
1350*6777b538SAndroid Build Coastguard Worker   const char kRemoveChars[] = "-/+*";
1351*6777b538SAndroid Build Coastguard Worker   std::string input = "A-+bc/d!*";
1352*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RemoveChars(input, kRemoveChars, &input));
1353*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("Abcd!", input);
1354*6777b538SAndroid Build Coastguard Worker 
1355*6777b538SAndroid Build Coastguard Worker   // No characters match kRemoveChars.
1356*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(RemoveChars(input, kRemoveChars, &input));
1357*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("Abcd!", input);
1358*6777b538SAndroid Build Coastguard Worker 
1359*6777b538SAndroid Build Coastguard Worker   // Empty string.
1360*6777b538SAndroid Build Coastguard Worker   input.clear();
1361*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(RemoveChars(input, kRemoveChars, &input));
1362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(), input);
1363*6777b538SAndroid Build Coastguard Worker }
1364*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ReplaceChars)1365*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ReplaceChars) {
1366*6777b538SAndroid Build Coastguard Worker   struct TestData {
1367*6777b538SAndroid Build Coastguard Worker     const char* input;
1368*6777b538SAndroid Build Coastguard Worker     const char* replace_chars;
1369*6777b538SAndroid Build Coastguard Worker     const char* replace_with;
1370*6777b538SAndroid Build Coastguard Worker     const char* output;
1371*6777b538SAndroid Build Coastguard Worker     bool result;
1372*6777b538SAndroid Build Coastguard Worker   } cases[] = {
1373*6777b538SAndroid Build Coastguard Worker       {"", "", "", "", false},
1374*6777b538SAndroid Build Coastguard Worker       {"t", "t", "t", "t", true},
1375*6777b538SAndroid Build Coastguard Worker       {"a", "b", "c", "a", false},
1376*6777b538SAndroid Build Coastguard Worker       {"b", "b", "c", "c", true},
1377*6777b538SAndroid Build Coastguard Worker       {"bob", "b", "p", "pop", true},
1378*6777b538SAndroid Build Coastguard Worker       {"bob", "o", "i", "bib", true},
1379*6777b538SAndroid Build Coastguard Worker       {"test", "", "", "test", false},
1380*6777b538SAndroid Build Coastguard Worker       {"test", "", "!", "test", false},
1381*6777b538SAndroid Build Coastguard Worker       {"test", "z", "!", "test", false},
1382*6777b538SAndroid Build Coastguard Worker       {"test", "e", "!", "t!st", true},
1383*6777b538SAndroid Build Coastguard Worker       {"test", "e", "!?", "t!?st", true},
1384*6777b538SAndroid Build Coastguard Worker       {"test", "ez", "!", "t!st", true},
1385*6777b538SAndroid Build Coastguard Worker       {"test", "zed", "!?", "t!?st", true},
1386*6777b538SAndroid Build Coastguard Worker       {"test", "t", "!?", "!?es!?", true},
1387*6777b538SAndroid Build Coastguard Worker       {"test", "et", "!>", "!>!>s!>", true},
1388*6777b538SAndroid Build Coastguard Worker       {"test", "zest", "!", "!!!!", true},
1389*6777b538SAndroid Build Coastguard Worker       {"test", "szt", "!", "!e!!", true},
1390*6777b538SAndroid Build Coastguard Worker       {"test", "t", "test", "testestest", true},
1391*6777b538SAndroid Build Coastguard Worker       {"tetst", "t", "test", "testeteststest", true},
1392*6777b538SAndroid Build Coastguard Worker       {"ttttttt", "t", "-", "-------", true},
1393*6777b538SAndroid Build Coastguard Worker       {"aAaAaAAaAAa", "A", "", "aaaaa", true},
1394*6777b538SAndroid Build Coastguard Worker       {"xxxxxxxxxx", "x", "", "", true},
1395*6777b538SAndroid Build Coastguard Worker       {"xxxxxxxxxx", "x", "x", "xxxxxxxxxx", true},
1396*6777b538SAndroid Build Coastguard Worker       {"xxxxxxxxxx", "x", "y-", "y-y-y-y-y-y-y-y-y-y-", true},
1397*6777b538SAndroid Build Coastguard Worker       {"xxxxxxxxxx", "x", "xy", "xyxyxyxyxyxyxyxyxyxy", true},
1398*6777b538SAndroid Build Coastguard Worker       {"xxxxxxxxxx", "x", "zyx", "zyxzyxzyxzyxzyxzyxzyxzyxzyxzyx", true},
1399*6777b538SAndroid Build Coastguard Worker       {"xaxxaxxxaxxxax", "x", "xy", "xyaxyxyaxyxyxyaxyxyxyaxy", true},
1400*6777b538SAndroid Build Coastguard Worker       {"-xaxxaxxxaxxxax-", "x", "xy", "-xyaxyxyaxyxyxyaxyxyxyaxy-", true},
1401*6777b538SAndroid Build Coastguard Worker   };
1402*6777b538SAndroid Build Coastguard Worker 
1403*6777b538SAndroid Build Coastguard Worker   for (const TestData& scenario : cases) {
1404*6777b538SAndroid Build Coastguard Worker     // Test with separate output and input vars.
1405*6777b538SAndroid Build Coastguard Worker     std::string output;
1406*6777b538SAndroid Build Coastguard Worker     bool result = ReplaceChars(scenario.input, scenario.replace_chars,
1407*6777b538SAndroid Build Coastguard Worker                                scenario.replace_with, &output);
1408*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.result, result) << scenario.input;
1409*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.output, output);
1410*6777b538SAndroid Build Coastguard Worker   }
1411*6777b538SAndroid Build Coastguard Worker 
1412*6777b538SAndroid Build Coastguard Worker   for (const TestData& scenario : cases) {
1413*6777b538SAndroid Build Coastguard Worker     // Test with an input/output var of limited capacity.
1414*6777b538SAndroid Build Coastguard Worker     std::string input_output = scenario.input;
1415*6777b538SAndroid Build Coastguard Worker     input_output.shrink_to_fit();
1416*6777b538SAndroid Build Coastguard Worker     bool result = ReplaceChars(input_output, scenario.replace_chars,
1417*6777b538SAndroid Build Coastguard Worker                                scenario.replace_with, &input_output);
1418*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.result, result) << scenario.input;
1419*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.output, input_output);
1420*6777b538SAndroid Build Coastguard Worker   }
1421*6777b538SAndroid Build Coastguard Worker 
1422*6777b538SAndroid Build Coastguard Worker   for (const TestData& scenario : cases) {
1423*6777b538SAndroid Build Coastguard Worker     // Test with an input/output var of ample capacity; should
1424*6777b538SAndroid Build Coastguard Worker     // not realloc.
1425*6777b538SAndroid Build Coastguard Worker     std::string input_output = scenario.input;
1426*6777b538SAndroid Build Coastguard Worker     input_output.reserve(strlen(scenario.output) * 2);
1427*6777b538SAndroid Build Coastguard Worker     const void* original_buffer = input_output.data();
1428*6777b538SAndroid Build Coastguard Worker     bool result = ReplaceChars(input_output, scenario.replace_chars,
1429*6777b538SAndroid Build Coastguard Worker                                scenario.replace_with, &input_output);
1430*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.result, result) << scenario.input;
1431*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(scenario.output, input_output);
1432*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(original_buffer, input_output.data());
1433*6777b538SAndroid Build Coastguard Worker   }
1434*6777b538SAndroid Build Coastguard Worker }
1435*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,ContainsOnlyChars)1436*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, ContainsOnlyChars) {
1437*6777b538SAndroid Build Coastguard Worker   // Providing an empty list of characters should return false but for the empty
1438*6777b538SAndroid Build Coastguard Worker   // string.
1439*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(std::string(), std::string()));
1440*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars("Hello", std::string()));
1441*6777b538SAndroid Build Coastguard Worker 
1442*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(std::string(), "1234"));
1443*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars("1", "1234"));
1444*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars("1", "4321"));
1445*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars("123", "4321"));
1446*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars("123a", "4321"));
1447*6777b538SAndroid Build Coastguard Worker 
1448*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(std::string(), kWhitespaceASCII));
1449*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(" ", kWhitespaceASCII));
1450*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars("\t", kWhitespaceASCII));
1451*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars("\t \r \n  ", kWhitespaceASCII));
1452*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars("a", kWhitespaceASCII));
1453*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars("\thello\r \n  ", kWhitespaceASCII));
1454*6777b538SAndroid Build Coastguard Worker 
1455*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(std::u16string(), kWhitespaceUTF16));
1456*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(u" ", kWhitespaceUTF16));
1457*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(u"\t", kWhitespaceUTF16));
1458*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ContainsOnlyChars(u"\t \r \n  ", kWhitespaceUTF16));
1459*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars(u"a", kWhitespaceUTF16));
1460*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ContainsOnlyChars(u"\thello\r \n  ", kWhitespaceUTF16));
1461*6777b538SAndroid Build Coastguard Worker }
1462*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,CompareCaseInsensitiveASCII)1463*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, CompareCaseInsensitiveASCII) {
1464*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, CompareCaseInsensitiveASCII("", ""));
1465*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, CompareCaseInsensitiveASCII("Asdf", "aSDf"));
1466*6777b538SAndroid Build Coastguard Worker 
1467*6777b538SAndroid Build Coastguard Worker   // Differing lengths.
1468*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(-1, CompareCaseInsensitiveASCII("Asdf", "aSDfA"));
1469*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, CompareCaseInsensitiveASCII("AsdfA", "aSDf"));
1470*6777b538SAndroid Build Coastguard Worker 
1471*6777b538SAndroid Build Coastguard Worker   // Differing values.
1472*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(-1, CompareCaseInsensitiveASCII("AsdfA", "aSDfb"));
1473*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, CompareCaseInsensitiveASCII("Asdfb", "aSDfA"));
1474*6777b538SAndroid Build Coastguard Worker 
1475*6777b538SAndroid Build Coastguard Worker   // Non-ASCII bytes are permitted, but they will be compared case-sensitively.
1476*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, CompareCaseInsensitiveASCII("aaa \xc3\xa4", "AAA \xc3\xa4"));
1477*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(-1, CompareCaseInsensitiveASCII("AAA \xc3\x84", "aaa \xc3\xa4"));
1478*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, CompareCaseInsensitiveASCII("aaa \xc3\xa4", "AAA \xc3\x84"));
1479*6777b538SAndroid Build Coastguard Worker 
1480*6777b538SAndroid Build Coastguard Worker   // ASCII bytes should sort before non-ASCII ones.
1481*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(-1, CompareCaseInsensitiveASCII("a", "\xc3\xa4"));
1482*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, CompareCaseInsensitiveASCII("\xc3\xa4", "a"));
1483*6777b538SAndroid Build Coastguard Worker 
1484*6777b538SAndroid Build Coastguard Worker   // For constexpr.
1485*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("", "") == 0);
1486*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("Asdf", "aSDf") == 0);
1487*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("Asdf", "aSDfA") == -1);
1488*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("AsdfA", "aSDf") == 1);
1489*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("AsdfA", "aSDfb") == -1);
1490*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("Asdfb", "aSDfA") == 1);
1491*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("aaa \xc3\xa4", "AAA \xc3\xa4") ==
1492*6777b538SAndroid Build Coastguard Worker                 0);
1493*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("AAA \xc3\x84", "aaa \xc3\xa4") ==
1494*6777b538SAndroid Build Coastguard Worker                 -1);
1495*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("aaa \xc3\xa4", "AAA \xc3\x84") ==
1496*6777b538SAndroid Build Coastguard Worker                 1);
1497*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("a", "\xc3\xa4") == -1);
1498*6777b538SAndroid Build Coastguard Worker   static_assert(CompareCaseInsensitiveASCII("\xc3\xa4", "a") == 1);
1499*6777b538SAndroid Build Coastguard Worker }
1500*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,EqualsCaseInsensitiveASCII)1501*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, EqualsCaseInsensitiveASCII) {
1502*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("", ""));
1503*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", "aSDF"));
1504*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", "aSDF"));
1505*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", "aSDFz"));
1506*6777b538SAndroid Build Coastguard Worker 
1507*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", u""));
1508*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDF"));
1509*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", u"aSDF"));
1510*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDFz"));
1511*6777b538SAndroid Build Coastguard Worker 
1512*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", ""));
1513*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDF"));
1514*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", "aSDF"));
1515*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDFz"));
1516*6777b538SAndroid Build Coastguard Worker 
1517*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("", u""));
1518*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", u"aSDF"));
1519*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", u"aSDF"));
1520*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", u"aSDFz"));
1521*6777b538SAndroid Build Coastguard Worker 
1522*6777b538SAndroid Build Coastguard Worker   // Non-ASCII bytes are permitted, but they will be compared case-sensitively.
1523*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("aaa \xc3\xa4", "AAA \xc3\xa4"));
1524*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("aaa \xc3\x84", "AAA \xc3\xa4"));
1525*6777b538SAndroid Build Coastguard Worker 
1526*6777b538SAndroid Build Coastguard Worker   // The `std::wstring_view` overloads are only defined on Windows.
1527*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1528*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", L""));
1529*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDF"));
1530*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", L"aSDF"));
1531*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDFz"));
1532*6777b538SAndroid Build Coastguard Worker 
1533*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", ""));
1534*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDF"));
1535*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", "aSDF"));
1536*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDFz"));
1537*6777b538SAndroid Build Coastguard Worker 
1538*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("", L""));
1539*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", L"aSDF"));
1540*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", L"aSDF"));
1541*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", L"aSDFz"));
1542*6777b538SAndroid Build Coastguard Worker #endif
1543*6777b538SAndroid Build Coastguard Worker }
1544*6777b538SAndroid Build Coastguard Worker 
TEST(StringUtilTest,IsUnicodeWhitespace)1545*6777b538SAndroid Build Coastguard Worker TEST(StringUtilTest, IsUnicodeWhitespace) {
1546*6777b538SAndroid Build Coastguard Worker   // NOT unicode white space.
1547*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L'\0'));
1548*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L'A'));
1549*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L'0'));
1550*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L'.'));
1551*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L';'));
1552*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(IsUnicodeWhitespace(L'\x4100'));
1553*6777b538SAndroid Build Coastguard Worker 
1554*6777b538SAndroid Build Coastguard Worker   // Actual unicode whitespace.
1555*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L' '));
1556*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\xa0'));
1557*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\x3000'));
1558*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\t'));
1559*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\r'));
1560*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\v'));
1561*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\f'));
1562*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IsUnicodeWhitespace(L'\n'));
1563*6777b538SAndroid Build Coastguard Worker }
1564*6777b538SAndroid Build Coastguard Worker 
1565*6777b538SAndroid Build Coastguard Worker class WriteIntoTest : public testing::Test {
1566*6777b538SAndroid Build Coastguard Worker  protected:
WritesCorrectly(size_t num_chars)1567*6777b538SAndroid Build Coastguard Worker   static void WritesCorrectly(size_t num_chars) {
1568*6777b538SAndroid Build Coastguard Worker     std::string buffer;
1569*6777b538SAndroid Build Coastguard Worker     char kOriginal[] = "supercali";
1570*6777b538SAndroid Build Coastguard Worker     strncpy(WriteInto(&buffer, num_chars + 1), kOriginal, num_chars);
1571*6777b538SAndroid Build Coastguard Worker     // Using std::string(buffer.c_str()) instead of |buffer| truncates the
1572*6777b538SAndroid Build Coastguard Worker     // string at the first \0.
1573*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
1574*6777b538SAndroid Build Coastguard Worker         std::string(kOriginal, std::min(num_chars, std::size(kOriginal) - 1)),
1575*6777b538SAndroid Build Coastguard Worker         std::string(buffer.c_str()));
1576*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(num_chars, buffer.size());
1577*6777b538SAndroid Build Coastguard Worker   }
1578*6777b538SAndroid Build Coastguard Worker };
1579*6777b538SAndroid Build Coastguard Worker 
TEST_F(WriteIntoTest,WriteInto)1580*6777b538SAndroid Build Coastguard Worker TEST_F(WriteIntoTest, WriteInto) {
1581*6777b538SAndroid Build Coastguard Worker   // Validate that WriteInto reserves enough space and
1582*6777b538SAndroid Build Coastguard Worker   // sizes a string correctly.
1583*6777b538SAndroid Build Coastguard Worker   WritesCorrectly(1);
1584*6777b538SAndroid Build Coastguard Worker   WritesCorrectly(2);
1585*6777b538SAndroid Build Coastguard Worker   WritesCorrectly(5000);
1586*6777b538SAndroid Build Coastguard Worker 
1587*6777b538SAndroid Build Coastguard Worker   // Validate that WriteInto handles 0-length strings
1588*6777b538SAndroid Build Coastguard Worker   std::string empty;
1589*6777b538SAndroid Build Coastguard Worker   const char kOriginal[] = "original";
1590*6777b538SAndroid Build Coastguard Worker   strncpy(WriteInto(&empty, 1), kOriginal, 0);
1591*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("", empty.c_str());
1592*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, empty.size());
1593*6777b538SAndroid Build Coastguard Worker 
1594*6777b538SAndroid Build Coastguard Worker   // Validate that WriteInto doesn't modify other strings
1595*6777b538SAndroid Build Coastguard Worker   // when using a Copy-on-Write implementation.
1596*6777b538SAndroid Build Coastguard Worker   const char kLive[] = "live";
1597*6777b538SAndroid Build Coastguard Worker   const char kDead[] = "dead";
1598*6777b538SAndroid Build Coastguard Worker   const std::string live = kLive;
1599*6777b538SAndroid Build Coastguard Worker   std::string dead = live;
1600*6777b538SAndroid Build Coastguard Worker   strncpy(WriteInto(&dead, 5), kDead, 4);
1601*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kDead, dead);
1602*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4u, dead.size());
1603*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kLive, live);
1604*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4u, live.size());
1605*6777b538SAndroid Build Coastguard Worker }
1606*6777b538SAndroid Build Coastguard Worker 
1607*6777b538SAndroid Build Coastguard Worker }  // namespace
1608*6777b538SAndroid Build Coastguard Worker 
1609*6777b538SAndroid Build Coastguard Worker }  // namespace base
1610