1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/string_split.h"
6 #include "testing/gmock/include/gmock/gmock.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 using ::testing::ElementsAre;
10
11 namespace base {
12
13 class SplitStringIntoKeyValuesTest : public testing::Test {
14 protected:
15 std::string key;
16 std::vector<std::string> values;
17 };
18
TEST_F(SplitStringIntoKeyValuesTest,EmptyInputMultipleValues)19 TEST_F(SplitStringIntoKeyValuesTest, EmptyInputMultipleValues) {
20 EXPECT_FALSE(SplitStringIntoKeyValues("", // Empty input
21 '\t', // Key separators
22 &key, &values));
23 EXPECT_TRUE(key.empty());
24 EXPECT_TRUE(values.empty());
25 }
26
TEST_F(SplitStringIntoKeyValuesTest,EmptyValueInputMultipleValues)27 TEST_F(SplitStringIntoKeyValuesTest, EmptyValueInputMultipleValues) {
28 EXPECT_FALSE(SplitStringIntoKeyValues("key_with_no_value\t",
29 '\t', // Key separators
30 &key, &values));
31 EXPECT_EQ("key_with_no_value", key);
32 EXPECT_TRUE(values.empty());
33 }
34
TEST_F(SplitStringIntoKeyValuesTest,EmptyKeyInputMultipleValues)35 TEST_F(SplitStringIntoKeyValuesTest, EmptyKeyInputMultipleValues) {
36 EXPECT_TRUE(SplitStringIntoKeyValues("\tvalue for empty key",
37 '\t', // Key separators
38 &key, &values));
39 EXPECT_TRUE(key.empty());
40 ASSERT_EQ(1U, values.size());
41 }
42
TEST_F(SplitStringIntoKeyValuesTest,KeyWithMultipleValues)43 TEST_F(SplitStringIntoKeyValuesTest, KeyWithMultipleValues) {
44 EXPECT_TRUE(SplitStringIntoKeyValues("key1\tvalue1, value2 value3",
45 '\t', // Key separators
46 &key, &values));
47 EXPECT_EQ("key1", key);
48 ASSERT_EQ(1U, values.size());
49 EXPECT_EQ("value1, value2 value3", values[0]);
50 }
51
TEST_F(SplitStringIntoKeyValuesTest,EmptyInputSingleValue)52 TEST_F(SplitStringIntoKeyValuesTest, EmptyInputSingleValue) {
53 EXPECT_FALSE(SplitStringIntoKeyValues("", // Empty input
54 '\t', // Key separators
55 &key, &values));
56 EXPECT_TRUE(key.empty());
57 EXPECT_TRUE(values.empty());
58 }
59
TEST_F(SplitStringIntoKeyValuesTest,EmptyValueInputSingleValue)60 TEST_F(SplitStringIntoKeyValuesTest, EmptyValueInputSingleValue) {
61 EXPECT_FALSE(SplitStringIntoKeyValues("key_with_no_value\t",
62 '\t', // Key separators
63 &key, &values));
64 EXPECT_EQ("key_with_no_value", key);
65 EXPECT_TRUE(values.empty());
66 }
67
TEST_F(SplitStringIntoKeyValuesTest,EmptyKeyInputSingleValue)68 TEST_F(SplitStringIntoKeyValuesTest, EmptyKeyInputSingleValue) {
69 EXPECT_TRUE(SplitStringIntoKeyValues("\tvalue for empty key",
70 '\t', // Key separators
71 &key, &values));
72 EXPECT_TRUE(key.empty());
73 ASSERT_EQ(1U, values.size());
74 EXPECT_EQ("value for empty key", values[0]);
75 }
76
TEST_F(SplitStringIntoKeyValuesTest,KeyWithSingleValue)77 TEST_F(SplitStringIntoKeyValuesTest, KeyWithSingleValue) {
78 EXPECT_TRUE(SplitStringIntoKeyValues("key1\tvalue1, value2 value3",
79 '\t', // Key separators
80 &key, &values));
81 EXPECT_EQ("key1", key);
82 ASSERT_EQ(1U, values.size());
83 EXPECT_EQ("value1, value2 value3", values[0]);
84 }
85
86 class SplitStringIntoKeyValuePairsTest : public testing::Test {
87 protected:
88 std::vector<std::pair<std::string, std::string> > kv_pairs;
89 };
90
TEST_F(SplitStringIntoKeyValuePairsTest,EmptyString)91 TEST_F(SplitStringIntoKeyValuePairsTest, EmptyString) {
92 EXPECT_TRUE(SplitStringIntoKeyValuePairs("",
93 ':', // Key-value delimiters
94 ',', // Key-value pair delims
95 &kv_pairs));
96 EXPECT_TRUE(kv_pairs.empty());
97 }
98
TEST_F(SplitStringIntoKeyValuePairsTest,EmptySecondPair)99 TEST_F(SplitStringIntoKeyValuePairsTest, EmptySecondPair) {
100 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:value1,,key3:value3",
101 ':', // Key-value delimiters
102 ',', // Key-value pair delims
103 &kv_pairs));
104 ASSERT_EQ(2U, kv_pairs.size());
105 EXPECT_EQ("key1", kv_pairs[0].first);
106 EXPECT_EQ("value1", kv_pairs[0].second);
107 EXPECT_EQ("key3", kv_pairs[1].first);
108 EXPECT_EQ("value3", kv_pairs[1].second);
109 }
110
TEST_F(SplitStringIntoKeyValuePairsTest,EmptySecondValue)111 TEST_F(SplitStringIntoKeyValuePairsTest, EmptySecondValue) {
112 EXPECT_FALSE(SplitStringIntoKeyValuePairs("key1:value1 , key2:",
113 ':', // Key-value delimiters
114 ',', // Key-value pair delims
115 &kv_pairs));
116 ASSERT_EQ(2U, kv_pairs.size());
117 EXPECT_EQ("key1", kv_pairs[0].first);
118 EXPECT_EQ("value1", kv_pairs[0].second);
119 EXPECT_EQ("key2", kv_pairs[1].first);
120 EXPECT_EQ("", kv_pairs[1].second);
121 }
122
TEST_F(SplitStringIntoKeyValuePairsTest,DelimiterInValue)123 TEST_F(SplitStringIntoKeyValuePairsTest, DelimiterInValue) {
124 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:va:ue1 , key2:value2",
125 ':', // Key-value delimiters
126 ',', // Key-value pair delims
127 &kv_pairs));
128 ASSERT_EQ(2U, kv_pairs.size());
129 EXPECT_EQ("key1", kv_pairs[0].first);
130 EXPECT_EQ("va:ue1", kv_pairs[0].second);
131 EXPECT_EQ("key2", kv_pairs[1].first);
132 EXPECT_EQ("value2", kv_pairs[1].second);
133 }
134
TEST(SplitStringUsingSubstrTest,EmptyString)135 TEST(SplitStringUsingSubstrTest, EmptyString) {
136 std::vector<std::string> results;
137 SplitStringUsingSubstr("", "DELIMITER", &results);
138 ASSERT_EQ(1u, results.size());
139 EXPECT_THAT(results, ElementsAre(""));
140 }
141
142 // Test for SplitString
TEST(StringUtilTest,SplitString)143 TEST(StringUtilTest, SplitString) {
144 std::vector<std::wstring> r;
145
146 SplitString(L"", L',', &r);
147 ASSERT_EQ(1U, r.size());
148 EXPECT_EQ(r[0], L"");
149 r.clear();
150
151 SplitString(L"a,b,c", L',', &r);
152 ASSERT_EQ(3U, r.size());
153 EXPECT_EQ(r[0], L"a");
154 EXPECT_EQ(r[1], L"b");
155 EXPECT_EQ(r[2], L"c");
156 r.clear();
157
158 SplitString(L"a, b, c", L',', &r);
159 ASSERT_EQ(3U, r.size());
160 EXPECT_EQ(r[0], L"a");
161 EXPECT_EQ(r[1], L"b");
162 EXPECT_EQ(r[2], L"c");
163 r.clear();
164
165 SplitString(L"a,,c", L',', &r);
166 ASSERT_EQ(3U, r.size());
167 EXPECT_EQ(r[0], L"a");
168 EXPECT_EQ(r[1], L"");
169 EXPECT_EQ(r[2], L"c");
170 r.clear();
171
172 SplitString(L"", L'*', &r);
173 ASSERT_EQ(1U, r.size());
174 EXPECT_EQ(r[0], L"");
175 r.clear();
176
177 SplitString(L"foo", L'*', &r);
178 ASSERT_EQ(1U, r.size());
179 EXPECT_EQ(r[0], L"foo");
180 r.clear();
181
182 SplitString(L"foo ,", L',', &r);
183 ASSERT_EQ(2U, r.size());
184 EXPECT_EQ(r[0], L"foo");
185 EXPECT_EQ(r[1], L"");
186 r.clear();
187
188 SplitString(L",", L',', &r);
189 ASSERT_EQ(2U, r.size());
190 EXPECT_EQ(r[0], L"");
191 EXPECT_EQ(r[1], L"");
192 r.clear();
193
194 SplitString(L"\t\ta\t", L'\t', &r);
195 ASSERT_EQ(4U, r.size());
196 EXPECT_EQ(r[0], L"");
197 EXPECT_EQ(r[1], L"");
198 EXPECT_EQ(r[2], L"a");
199 EXPECT_EQ(r[3], L"");
200 r.clear();
201
202 SplitString(L"\ta\t\nb\tcc", L'\n', &r);
203 ASSERT_EQ(2U, r.size());
204 EXPECT_EQ(r[0], L"a");
205 EXPECT_EQ(r[1], L"b\tcc");
206 r.clear();
207 }
208
TEST(SplitStringUsingSubstrTest,StringWithNoDelimiter)209 TEST(SplitStringUsingSubstrTest, StringWithNoDelimiter) {
210 std::vector<std::string> results;
211 SplitStringUsingSubstr("alongwordwithnodelimiter", "DELIMITER", &results);
212 ASSERT_EQ(1u, results.size());
213 EXPECT_THAT(results, ElementsAre("alongwordwithnodelimiter"));
214 }
215
TEST(SplitStringUsingSubstrTest,LeadingDelimitersSkipped)216 TEST(SplitStringUsingSubstrTest, LeadingDelimitersSkipped) {
217 std::vector<std::string> results;
218 SplitStringUsingSubstr(
219 "DELIMITERDELIMITERDELIMITERoneDELIMITERtwoDELIMITERthree",
220 "DELIMITER",
221 &results);
222 ASSERT_EQ(6u, results.size());
223 EXPECT_THAT(results, ElementsAre("", "", "", "one", "two", "three"));
224 }
225
TEST(SplitStringUsingSubstrTest,ConsecutiveDelimitersSkipped)226 TEST(SplitStringUsingSubstrTest, ConsecutiveDelimitersSkipped) {
227 std::vector<std::string> results;
228 SplitStringUsingSubstr(
229 "unoDELIMITERDELIMITERDELIMITERdosDELIMITERtresDELIMITERDELIMITERcuatro",
230 "DELIMITER",
231 &results);
232 ASSERT_EQ(7u, results.size());
233 EXPECT_THAT(results, ElementsAre("uno", "", "", "dos", "tres", "", "cuatro"));
234 }
235
TEST(SplitStringUsingSubstrTest,TrailingDelimitersSkipped)236 TEST(SplitStringUsingSubstrTest, TrailingDelimitersSkipped) {
237 std::vector<std::string> results;
238 SplitStringUsingSubstr(
239 "unDELIMITERdeuxDELIMITERtroisDELIMITERquatreDELIMITERDELIMITERDELIMITER",
240 "DELIMITER",
241 &results);
242 ASSERT_EQ(7u, results.size());
243 EXPECT_THAT(
244 results, ElementsAre("un", "deux", "trois", "quatre", "", "", ""));
245 }
246
TEST(StringSplitTest,StringSplitDontTrim)247 TEST(StringSplitTest, StringSplitDontTrim) {
248 std::vector<std::string> r;
249
250 SplitStringDontTrim("\t\ta\t", '\t', &r);
251 ASSERT_EQ(4U, r.size());
252 EXPECT_EQ(r[0], "");
253 EXPECT_EQ(r[1], "");
254 EXPECT_EQ(r[2], "a");
255 EXPECT_EQ(r[3], "");
256 r.clear();
257
258 SplitStringDontTrim("\ta\t\nb\tcc", '\n', &r);
259 ASSERT_EQ(2U, r.size());
260 EXPECT_EQ(r[0], "\ta\t");
261 EXPECT_EQ(r[1], "b\tcc");
262 r.clear();
263 }
264
TEST(StringSplitTest,SplitStringAlongWhitespace)265 TEST(StringSplitTest, SplitStringAlongWhitespace) {
266 struct TestData {
267 const std::wstring input;
268 const size_t expected_result_count;
269 const std::wstring output1;
270 const std::wstring output2;
271 } data[] = {
272 { L"a", 1, L"a", L"" },
273 { L" ", 0, L"", L"" },
274 { L" a", 1, L"a", L"" },
275 { L" ab ", 1, L"ab", L"" },
276 { L" ab c", 2, L"ab", L"c" },
277 { L" ab c ", 2, L"ab", L"c" },
278 { L" ab cd", 2, L"ab", L"cd" },
279 { L" ab cd ", 2, L"ab", L"cd" },
280 { L" \ta\t", 1, L"a", L"" },
281 { L" b\ta\t", 2, L"b", L"a" },
282 { L" b\tat", 2, L"b", L"at" },
283 { L"b\tat", 2, L"b", L"at" },
284 { L"b\t at", 2, L"b", L"at" },
285 };
286 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
287 std::vector<std::wstring> results;
288 SplitStringAlongWhitespace(data[i].input, &results);
289 ASSERT_EQ(data[i].expected_result_count, results.size());
290 if (data[i].expected_result_count > 0)
291 ASSERT_EQ(data[i].output1, results[0]);
292 if (data[i].expected_result_count > 1)
293 ASSERT_EQ(data[i].output2, results[1]);
294 }
295 }
296
297 } // namespace base
298