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