1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/string_split.h"
7 #include "base/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using ::testing::ElementsAre
;
16 class SplitStringIntoKeyValuePairsTest
: public testing::Test
{
18 base::StringPairs kv_pairs
;
21 TEST_F(SplitStringIntoKeyValuePairsTest
, EmptyString
) {
22 EXPECT_TRUE(SplitStringIntoKeyValuePairs(std::string(),
23 ':', // Key-value delimiter
24 ',', // Key-value pair delimiter
26 EXPECT_TRUE(kv_pairs
.empty());
29 TEST_F(SplitStringIntoKeyValuePairsTest
, MissingKeyValueDelimiter
) {
30 EXPECT_FALSE(SplitStringIntoKeyValuePairs("key1,key2:value2",
31 ':', // Key-value delimiter
32 ',', // Key-value pair delimiter
34 ASSERT_EQ(2U, kv_pairs
.size());
35 EXPECT_TRUE(kv_pairs
[0].first
.empty());
36 EXPECT_TRUE(kv_pairs
[0].second
.empty());
37 EXPECT_EQ("key2", kv_pairs
[1].first
);
38 EXPECT_EQ("value2", kv_pairs
[1].second
);
41 TEST_F(SplitStringIntoKeyValuePairsTest
, EmptyKeyWithKeyValueDelimiter
) {
42 EXPECT_TRUE(SplitStringIntoKeyValuePairs(":value1,key2:value2",
43 ':', // Key-value delimiter
44 ',', // Key-value pair delimiter
46 ASSERT_EQ(2U, kv_pairs
.size());
47 EXPECT_TRUE(kv_pairs
[0].first
.empty());
48 EXPECT_EQ("value1", kv_pairs
[0].second
);
49 EXPECT_EQ("key2", kv_pairs
[1].first
);
50 EXPECT_EQ("value2", kv_pairs
[1].second
);
53 TEST_F(SplitStringIntoKeyValuePairsTest
, TrailingAndLeadingPairDelimiter
) {
54 EXPECT_TRUE(SplitStringIntoKeyValuePairs(",key1:value1,key2:value2,",
55 ':', // Key-value delimiter
56 ',', // Key-value pair delimiter
58 ASSERT_EQ(2U, kv_pairs
.size());
59 EXPECT_EQ("key1", kv_pairs
[0].first
);
60 EXPECT_EQ("value1", kv_pairs
[0].second
);
61 EXPECT_EQ("key2", kv_pairs
[1].first
);
62 EXPECT_EQ("value2", kv_pairs
[1].second
);
65 TEST_F(SplitStringIntoKeyValuePairsTest
, EmptyPair
) {
66 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:value1,,key3:value3",
67 ':', // Key-value delimiter
68 ',', // Key-value pair delimiter
70 ASSERT_EQ(2U, kv_pairs
.size());
71 EXPECT_EQ("key1", kv_pairs
[0].first
);
72 EXPECT_EQ("value1", kv_pairs
[0].second
);
73 EXPECT_EQ("key3", kv_pairs
[1].first
);
74 EXPECT_EQ("value3", kv_pairs
[1].second
);
77 TEST_F(SplitStringIntoKeyValuePairsTest
, EmptyValue
) {
78 EXPECT_FALSE(SplitStringIntoKeyValuePairs("key1:,key2:value2",
79 ':', // Key-value delimiter
80 ',', // Key-value pair delimiter
82 ASSERT_EQ(2U, kv_pairs
.size());
83 EXPECT_EQ("key1", kv_pairs
[0].first
);
84 EXPECT_EQ("", kv_pairs
[0].second
);
85 EXPECT_EQ("key2", kv_pairs
[1].first
);
86 EXPECT_EQ("value2", kv_pairs
[1].second
);
89 TEST_F(SplitStringIntoKeyValuePairsTest
, UntrimmedWhitespace
) {
90 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1 : value1",
91 ':', // Key-value delimiter
92 ',', // Key-value pair delimiter
94 ASSERT_EQ(1U, kv_pairs
.size());
95 EXPECT_EQ("key1 ", kv_pairs
[0].first
);
96 EXPECT_EQ(" value1", kv_pairs
[0].second
);
99 TEST_F(SplitStringIntoKeyValuePairsTest
, TrimmedWhitespace
) {
100 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:value1 , key2:value2",
101 ':', // Key-value delimiter
102 ',', // Key-value pair delimiter
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("key2", kv_pairs
[1].first
);
108 EXPECT_EQ("value2", kv_pairs
[1].second
);
111 TEST_F(SplitStringIntoKeyValuePairsTest
, MultipleKeyValueDelimiters
) {
112 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:::value1,key2:value2",
113 ':', // Key-value delimiter
114 ',', // Key-value pair delimiter
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("value2", kv_pairs
[1].second
);
123 TEST_F(SplitStringIntoKeyValuePairsTest
, OnlySplitAtGivenSeparator
) {
124 std::string
a("a ?!@#$%^&*()_+:/{}\\\t\nb");
125 EXPECT_TRUE(SplitStringIntoKeyValuePairs(a
+ "X" + a
+ "Y" + a
+ "X" + a
,
126 'X', // Key-value delimiter
127 'Y', // Key-value pair delimiter
129 ASSERT_EQ(2U, kv_pairs
.size());
130 EXPECT_EQ(a
, kv_pairs
[0].first
);
131 EXPECT_EQ(a
, kv_pairs
[0].second
);
132 EXPECT_EQ(a
, kv_pairs
[1].first
);
133 EXPECT_EQ(a
, kv_pairs
[1].second
);
137 TEST_F(SplitStringIntoKeyValuePairsTest
, DelimiterInValue
) {
138 EXPECT_TRUE(SplitStringIntoKeyValuePairs("key1:va:ue1,key2:value2",
139 ':', // Key-value delimiter
140 ',', // Key-value pair delimiter
142 ASSERT_EQ(2U, kv_pairs
.size());
143 EXPECT_EQ("key1", kv_pairs
[0].first
);
144 EXPECT_EQ("va:ue1", kv_pairs
[0].second
);
145 EXPECT_EQ("key2", kv_pairs
[1].first
);
146 EXPECT_EQ("value2", kv_pairs
[1].second
);
149 TEST(SplitStringUsingSubstrTest
, EmptyString
) {
150 std::vector
<std::string
> results
;
151 SplitStringUsingSubstr(std::string(), "DELIMITER", &results
);
152 ASSERT_EQ(1u, results
.size());
153 EXPECT_THAT(results
, ElementsAre(""));
156 TEST(StringUtilTest
, SplitString_Basics
) {
157 std::vector
<std::string
> r
;
159 r
= SplitString(std::string(), ",:;", KEEP_WHITESPACE
, SPLIT_WANT_ALL
);
160 EXPECT_TRUE(r
.empty());
162 // Empty separator list
163 r
= SplitString("hello, world", "", KEEP_WHITESPACE
, SPLIT_WANT_ALL
);
164 ASSERT_EQ(1u, r
.size());
165 EXPECT_EQ("hello, world", r
[0]);
167 // Should split on any of the separators.
168 r
= SplitString("::,,;;", ",:;", KEEP_WHITESPACE
, SPLIT_WANT_ALL
);
169 ASSERT_EQ(7u, r
.size());
171 ASSERT_TRUE(str
.empty());
173 r
= SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE
,
174 SPLIT_WANT_NONEMPTY
);
175 ASSERT_EQ(3u, r
.size());
176 EXPECT_EQ("red", r
[0]);
177 EXPECT_EQ("green", r
[1]);
178 EXPECT_EQ("blue", r
[2]);
180 // Want to split a string along whitespace sequences.
181 r
= SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE
,
182 SPLIT_WANT_NONEMPTY
);
183 ASSERT_EQ(3u, r
.size());
184 EXPECT_EQ("red", r
[0]);
185 EXPECT_EQ("green", r
[1]);
186 EXPECT_EQ("blue", r
[2]);
188 // Weird case of splitting on spaces but not trimming.
189 r
= SplitString(" red ", " ", TRIM_WHITESPACE
, SPLIT_WANT_ALL
);
190 ASSERT_EQ(3u, r
.size());
191 EXPECT_EQ("", r
[0]); // Before the first space.
192 EXPECT_EQ("red", r
[1]);
193 EXPECT_EQ("", r
[2]); // After the last space.
196 TEST(StringUtilTest
, SplitString_WhitespaceAndResultType
) {
197 std::vector
<std::string
> r
;
199 // Empty input handling.
200 r
= SplitString(std::string(), ",", KEEP_WHITESPACE
, SPLIT_WANT_ALL
);
201 EXPECT_TRUE(r
.empty());
202 r
= SplitString(std::string(), ",", KEEP_WHITESPACE
, SPLIT_WANT_NONEMPTY
);
203 EXPECT_TRUE(r
.empty());
205 // Input string is space and we're trimming.
206 r
= SplitString(" ", ",", TRIM_WHITESPACE
, SPLIT_WANT_ALL
);
207 ASSERT_EQ(1u, r
.size());
209 r
= SplitString(" ", ",", TRIM_WHITESPACE
, SPLIT_WANT_NONEMPTY
);
210 EXPECT_TRUE(r
.empty());
212 // Test all 4 combinations of flags on ", ,".
213 r
= SplitString(", ,", ",", KEEP_WHITESPACE
, SPLIT_WANT_ALL
);
214 ASSERT_EQ(3u, r
.size());
216 EXPECT_EQ(" ", r
[1]);
218 r
= SplitString(", ,", ",", KEEP_WHITESPACE
, SPLIT_WANT_NONEMPTY
);
219 ASSERT_EQ(1u, r
.size());
220 ASSERT_EQ(" ", r
[0]);
221 r
= SplitString(", ,", ",", TRIM_WHITESPACE
, SPLIT_WANT_ALL
);
222 ASSERT_EQ(3u, r
.size());
226 r
= SplitString(", ,", ",", TRIM_WHITESPACE
, SPLIT_WANT_NONEMPTY
);
227 ASSERT_TRUE(r
.empty());
230 TEST(SplitStringUsingSubstrTest
, StringWithNoDelimiter
) {
231 std::vector
<std::string
> results
;
232 SplitStringUsingSubstr("alongwordwithnodelimiter", "DELIMITER", &results
);
233 ASSERT_EQ(1u, results
.size());
234 EXPECT_THAT(results
, ElementsAre("alongwordwithnodelimiter"));
237 TEST(SplitStringUsingSubstrTest
, LeadingDelimitersSkipped
) {
238 std::vector
<std::string
> results
;
239 SplitStringUsingSubstr(
240 "DELIMITERDELIMITERDELIMITERoneDELIMITERtwoDELIMITERthree",
243 ASSERT_EQ(6u, results
.size());
244 EXPECT_THAT(results
, ElementsAre("", "", "", "one", "two", "three"));
247 TEST(SplitStringUsingSubstrTest
, ConsecutiveDelimitersSkipped
) {
248 std::vector
<std::string
> results
;
249 SplitStringUsingSubstr(
250 "unoDELIMITERDELIMITERDELIMITERdosDELIMITERtresDELIMITERDELIMITERcuatro",
253 ASSERT_EQ(7u, results
.size());
254 EXPECT_THAT(results
, ElementsAre("uno", "", "", "dos", "tres", "", "cuatro"));
257 TEST(SplitStringUsingSubstrTest
, TrailingDelimitersSkipped
) {
258 std::vector
<std::string
> results
;
259 SplitStringUsingSubstr(
260 "unDELIMITERdeuxDELIMITERtroisDELIMITERquatreDELIMITERDELIMITERDELIMITER",
263 ASSERT_EQ(7u, results
.size());
265 results
, ElementsAre("un", "deux", "trois", "quatre", "", "", ""));
268 TEST(StringSplitTest
, StringSplitKeepWhitespace
) {
269 std::vector
<std::string
> r
;
271 r
= SplitString(" ", "*", base::KEEP_WHITESPACE
, base::SPLIT_WANT_ALL
);
272 ASSERT_EQ(1U, r
.size());
273 EXPECT_EQ(r
[0], " ");
275 r
= SplitString("\t \ta\t ", "\t", base::KEEP_WHITESPACE
,
276 base::SPLIT_WANT_ALL
);
277 ASSERT_EQ(4U, r
.size());
279 EXPECT_EQ(r
[1], " ");
280 EXPECT_EQ(r
[2], "a");
281 EXPECT_EQ(r
[3], " ");
283 r
= SplitString("\ta\t\nb\tcc", "\n", base::KEEP_WHITESPACE
,
284 base::SPLIT_WANT_ALL
);
285 ASSERT_EQ(2U, r
.size());
286 EXPECT_EQ(r
[0], "\ta\t");
287 EXPECT_EQ(r
[1], "b\tcc");
290 TEST(StringSplitTest
, SplitStringAlongWhitespace
) {
293 const size_t expected_result_count
;
299 { " a", 1, "a", "" },
300 { " ab ", 1, "ab", "" },
301 { " ab c", 2, "ab", "c" },
302 { " ab c ", 2, "ab", "c" },
303 { " ab cd", 2, "ab", "cd" },
304 { " ab cd ", 2, "ab", "cd" },
305 { " \ta\t", 1, "a", "" },
306 { " b\ta\t", 2, "b", "a" },
307 { " b\tat", 2, "b", "at" },
308 { "b\tat", 2, "b", "at" },
309 { "b\t at", 2, "b", "at" },
311 for (size_t i
= 0; i
< arraysize(data
); ++i
) {
312 std::vector
<std::string
> results
= base::SplitString(
313 data
[i
].input
, kWhitespaceASCII
, base::KEEP_WHITESPACE
,
314 base::SPLIT_WANT_NONEMPTY
);
315 ASSERT_EQ(data
[i
].expected_result_count
, results
.size());
316 if (data
[i
].expected_result_count
> 0)
317 ASSERT_EQ(data
[i
].output1
, results
[0]);
318 if (data
[i
].expected_result_count
> 1)
319 ASSERT_EQ(data
[i
].output2
, results
[1]);