xref: /aosp_15_r20/external/abseil-cpp/absl/strings/str_split_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_split.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <cstddef>
18*9356374aSAndroid Build Coastguard Worker #include <cstdint>
19*9356374aSAndroid Build Coastguard Worker #include <deque>
20*9356374aSAndroid Build Coastguard Worker #include <initializer_list>
21*9356374aSAndroid Build Coastguard Worker #include <list>
22*9356374aSAndroid Build Coastguard Worker #include <map>
23*9356374aSAndroid Build Coastguard Worker #include <memory>
24*9356374aSAndroid Build Coastguard Worker #include <set>
25*9356374aSAndroid Build Coastguard Worker #include <string>
26*9356374aSAndroid Build Coastguard Worker #include <unordered_map>
27*9356374aSAndroid Build Coastguard Worker #include <unordered_set>
28*9356374aSAndroid Build Coastguard Worker #include <utility>
29*9356374aSAndroid Build Coastguard Worker #include <vector>
30*9356374aSAndroid Build Coastguard Worker 
31*9356374aSAndroid Build Coastguard Worker #include "gmock/gmock.h"
32*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
33*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h"
34*9356374aSAndroid Build Coastguard Worker #include "absl/container/btree_map.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/container/btree_set.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/container/flat_hash_map.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/container/node_hash_map.h"
38*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
39*9356374aSAndroid Build Coastguard Worker 
40*9356374aSAndroid Build Coastguard Worker namespace {
41*9356374aSAndroid Build Coastguard Worker 
42*9356374aSAndroid Build Coastguard Worker using ::testing::ElementsAre;
43*9356374aSAndroid Build Coastguard Worker using ::testing::IsEmpty;
44*9356374aSAndroid Build Coastguard Worker using ::testing::Pair;
45*9356374aSAndroid Build Coastguard Worker using ::testing::UnorderedElementsAre;
46*9356374aSAndroid Build Coastguard Worker 
TEST(Split,TraitsTest)47*9356374aSAndroid Build Coastguard Worker TEST(Split, TraitsTest) {
48*9356374aSAndroid Build Coastguard Worker   static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value,
49*9356374aSAndroid Build Coastguard Worker                 "");
50*9356374aSAndroid Build Coastguard Worker   static_assert(
51*9356374aSAndroid Build Coastguard Worker       !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, "");
52*9356374aSAndroid Build Coastguard Worker   static_assert(absl::strings_internal::SplitterIsConvertibleTo<
53*9356374aSAndroid Build Coastguard Worker                     std::vector<std::string>>::value,
54*9356374aSAndroid Build Coastguard Worker                 "");
55*9356374aSAndroid Build Coastguard Worker   static_assert(
56*9356374aSAndroid Build Coastguard Worker       !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value,
57*9356374aSAndroid Build Coastguard Worker       "");
58*9356374aSAndroid Build Coastguard Worker   static_assert(absl::strings_internal::SplitterIsConvertibleTo<
59*9356374aSAndroid Build Coastguard Worker                     std::vector<absl::string_view>>::value,
60*9356374aSAndroid Build Coastguard Worker                 "");
61*9356374aSAndroid Build Coastguard Worker   static_assert(absl::strings_internal::SplitterIsConvertibleTo<
62*9356374aSAndroid Build Coastguard Worker                     std::map<std::string, std::string>>::value,
63*9356374aSAndroid Build Coastguard Worker                 "");
64*9356374aSAndroid Build Coastguard Worker   static_assert(absl::strings_internal::SplitterIsConvertibleTo<
65*9356374aSAndroid Build Coastguard Worker                     std::map<absl::string_view, absl::string_view>>::value,
66*9356374aSAndroid Build Coastguard Worker                 "");
67*9356374aSAndroid Build Coastguard Worker   static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
68*9356374aSAndroid Build Coastguard Worker                     std::map<int, std::string>>::value,
69*9356374aSAndroid Build Coastguard Worker                 "");
70*9356374aSAndroid Build Coastguard Worker   static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
71*9356374aSAndroid Build Coastguard Worker                     std::map<std::string, int>>::value,
72*9356374aSAndroid Build Coastguard Worker                 "");
73*9356374aSAndroid Build Coastguard Worker }
74*9356374aSAndroid Build Coastguard Worker 
75*9356374aSAndroid Build Coastguard Worker // This tests the overall split API, which is made up of the absl::StrSplit()
76*9356374aSAndroid Build Coastguard Worker // function and the Delimiter objects in the absl:: namespace.
77*9356374aSAndroid Build Coastguard Worker // This TEST macro is outside of any namespace to require full specification of
78*9356374aSAndroid Build Coastguard Worker // namespaces just like callers will need to use.
TEST(Split,APIExamples)79*9356374aSAndroid Build Coastguard Worker TEST(Split, APIExamples) {
80*9356374aSAndroid Build Coastguard Worker   {
81*9356374aSAndroid Build Coastguard Worker     // Passes string delimiter. Assumes the default of ByString.
82*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a,b,c", ",");  // NOLINT
83*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
84*9356374aSAndroid Build Coastguard Worker 
85*9356374aSAndroid Build Coastguard Worker     // Equivalent to...
86*9356374aSAndroid Build Coastguard Worker     using absl::ByString;
87*9356374aSAndroid Build Coastguard Worker     v = absl::StrSplit("a,b,c", ByString(","));
88*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
89*9356374aSAndroid Build Coastguard Worker 
90*9356374aSAndroid Build Coastguard Worker     // Equivalent to...
91*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(absl::StrSplit("a,b,c", ByString(",")),
92*9356374aSAndroid Build Coastguard Worker                 ElementsAre("a", "b", "c"));
93*9356374aSAndroid Build Coastguard Worker   }
94*9356374aSAndroid Build Coastguard Worker 
95*9356374aSAndroid Build Coastguard Worker   {
96*9356374aSAndroid Build Coastguard Worker     // Same as above, but using a single character as the delimiter.
97*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
98*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
99*9356374aSAndroid Build Coastguard Worker 
100*9356374aSAndroid Build Coastguard Worker     // Equivalent to...
101*9356374aSAndroid Build Coastguard Worker     using absl::ByChar;
102*9356374aSAndroid Build Coastguard Worker     v = absl::StrSplit("a,b,c", ByChar(','));
103*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
104*9356374aSAndroid Build Coastguard Worker   }
105*9356374aSAndroid Build Coastguard Worker 
106*9356374aSAndroid Build Coastguard Worker   {
107*9356374aSAndroid Build Coastguard Worker     // Uses the Literal string "=>" as the delimiter.
108*9356374aSAndroid Build Coastguard Worker     const std::vector<std::string> v = absl::StrSplit("a=>b=>c", "=>");
109*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
110*9356374aSAndroid Build Coastguard Worker   }
111*9356374aSAndroid Build Coastguard Worker 
112*9356374aSAndroid Build Coastguard Worker   {
113*9356374aSAndroid Build Coastguard Worker     // The substrings are returned as string_views, eliminating copying.
114*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ',');
115*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
116*9356374aSAndroid Build Coastguard Worker   }
117*9356374aSAndroid Build Coastguard Worker 
118*9356374aSAndroid Build Coastguard Worker   {
119*9356374aSAndroid Build Coastguard Worker     // Leading and trailing empty substrings.
120*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit(",a,b,c,", ',');
121*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("", "a", "b", "c", ""));
122*9356374aSAndroid Build Coastguard Worker   }
123*9356374aSAndroid Build Coastguard Worker 
124*9356374aSAndroid Build Coastguard Worker   {
125*9356374aSAndroid Build Coastguard Worker     // Splits on a delimiter that is not found.
126*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("abc", ',');
127*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("abc"));
128*9356374aSAndroid Build Coastguard Worker   }
129*9356374aSAndroid Build Coastguard Worker 
130*9356374aSAndroid Build Coastguard Worker   {
131*9356374aSAndroid Build Coastguard Worker     // Splits the input string into individual characters by using an empty
132*9356374aSAndroid Build Coastguard Worker     // string as the delimiter.
133*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("abc", "");
134*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
135*9356374aSAndroid Build Coastguard Worker   }
136*9356374aSAndroid Build Coastguard Worker 
137*9356374aSAndroid Build Coastguard Worker   {
138*9356374aSAndroid Build Coastguard Worker     // Splits string data with embedded NUL characters, using NUL as the
139*9356374aSAndroid Build Coastguard Worker     // delimiter. A simple delimiter of "\0" doesn't work because strlen() will
140*9356374aSAndroid Build Coastguard Worker     // say that's the empty string when constructing the absl::string_view
141*9356374aSAndroid Build Coastguard Worker     // delimiter. Instead, a non-empty string containing NUL can be used as the
142*9356374aSAndroid Build Coastguard Worker     // delimiter.
143*9356374aSAndroid Build Coastguard Worker     std::string embedded_nulls("a\0b\0c", 5);
144*9356374aSAndroid Build Coastguard Worker     std::string null_delim("\0", 1);
145*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit(embedded_nulls, null_delim);
146*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
147*9356374aSAndroid Build Coastguard Worker   }
148*9356374aSAndroid Build Coastguard Worker 
149*9356374aSAndroid Build Coastguard Worker   {
150*9356374aSAndroid Build Coastguard Worker     // Stores first two split strings as the members in a std::pair.
151*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ',');
152*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("a", p.first);
153*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("b", p.second);
154*9356374aSAndroid Build Coastguard Worker     // "c" is omitted because std::pair can hold only two elements.
155*9356374aSAndroid Build Coastguard Worker   }
156*9356374aSAndroid Build Coastguard Worker 
157*9356374aSAndroid Build Coastguard Worker   {
158*9356374aSAndroid Build Coastguard Worker     // Results stored in std::set<std::string>
159*9356374aSAndroid Build Coastguard Worker     std::set<std::string> v = absl::StrSplit("a,b,c,a,b,c,a,b,c", ',');
160*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
161*9356374aSAndroid Build Coastguard Worker   }
162*9356374aSAndroid Build Coastguard Worker 
163*9356374aSAndroid Build Coastguard Worker   {
164*9356374aSAndroid Build Coastguard Worker     // Uses a non-const char* delimiter.
165*9356374aSAndroid Build Coastguard Worker     char a[] = ",";
166*9356374aSAndroid Build Coastguard Worker     char* d = a + 0;
167*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a,b,c", d);
168*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
169*9356374aSAndroid Build Coastguard Worker   }
170*9356374aSAndroid Build Coastguard Worker 
171*9356374aSAndroid Build Coastguard Worker   {
172*9356374aSAndroid Build Coastguard Worker     // Results split using either of , or ;
173*9356374aSAndroid Build Coastguard Worker     using absl::ByAnyChar;
174*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a,b;c", ByAnyChar(",;"));
175*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
176*9356374aSAndroid Build Coastguard Worker   }
177*9356374aSAndroid Build Coastguard Worker 
178*9356374aSAndroid Build Coastguard Worker   {
179*9356374aSAndroid Build Coastguard Worker     // Uses the SkipWhitespace predicate.
180*9356374aSAndroid Build Coastguard Worker     using absl::SkipWhitespace;
181*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v =
182*9356374aSAndroid Build Coastguard Worker         absl::StrSplit(" a , ,,b,", ',', SkipWhitespace());
183*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre(" a ", "b"));
184*9356374aSAndroid Build Coastguard Worker   }
185*9356374aSAndroid Build Coastguard Worker 
186*9356374aSAndroid Build Coastguard Worker   {
187*9356374aSAndroid Build Coastguard Worker     // Uses the ByLength delimiter.
188*9356374aSAndroid Build Coastguard Worker     using absl::ByLength;
189*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("abcdefg", ByLength(3));
190*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("abc", "def", "g"));
191*9356374aSAndroid Build Coastguard Worker   }
192*9356374aSAndroid Build Coastguard Worker 
193*9356374aSAndroid Build Coastguard Worker   {
194*9356374aSAndroid Build Coastguard Worker     // Different forms of initialization / conversion.
195*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v1 = absl::StrSplit("a,b,c", ',');
196*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v1, ElementsAre("a", "b", "c"));
197*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v2(absl::StrSplit("a,b,c", ','));
198*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v2, ElementsAre("a", "b", "c"));
199*9356374aSAndroid Build Coastguard Worker     auto v3 = std::vector<std::string>(absl::StrSplit("a,b,c", ','));
200*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v3, ElementsAre("a", "b", "c"));
201*9356374aSAndroid Build Coastguard Worker     v3 = absl::StrSplit("a,b,c", ',');
202*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v3, ElementsAre("a", "b", "c"));
203*9356374aSAndroid Build Coastguard Worker   }
204*9356374aSAndroid Build Coastguard Worker 
205*9356374aSAndroid Build Coastguard Worker   {
206*9356374aSAndroid Build Coastguard Worker     // Results stored in a std::map.
207*9356374aSAndroid Build Coastguard Worker     std::map<std::string, std::string> m = absl::StrSplit("a,1,b,2,a,3", ',');
208*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, m.size());
209*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("3", m["a"]);
210*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("2", m["b"]);
211*9356374aSAndroid Build Coastguard Worker   }
212*9356374aSAndroid Build Coastguard Worker 
213*9356374aSAndroid Build Coastguard Worker   {
214*9356374aSAndroid Build Coastguard Worker     // Results stored in a std::multimap.
215*9356374aSAndroid Build Coastguard Worker     std::multimap<std::string, std::string> m =
216*9356374aSAndroid Build Coastguard Worker         absl::StrSplit("a,1,b,2,a,3", ',');
217*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(3, m.size());
218*9356374aSAndroid Build Coastguard Worker     auto it = m.find("a");
219*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("1", it->second);
220*9356374aSAndroid Build Coastguard Worker     ++it;
221*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("3", it->second);
222*9356374aSAndroid Build Coastguard Worker     it = m.find("b");
223*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("2", it->second);
224*9356374aSAndroid Build Coastguard Worker   }
225*9356374aSAndroid Build Coastguard Worker 
226*9356374aSAndroid Build Coastguard Worker   {
227*9356374aSAndroid Build Coastguard Worker     // Demonstrates use in a range-based for loop in C++11.
228*9356374aSAndroid Build Coastguard Worker     std::string s = "x,x,x,x,x,x,x";
229*9356374aSAndroid Build Coastguard Worker     for (absl::string_view sp : absl::StrSplit(s, ',')) {
230*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ("x", sp);
231*9356374aSAndroid Build Coastguard Worker     }
232*9356374aSAndroid Build Coastguard Worker   }
233*9356374aSAndroid Build Coastguard Worker 
234*9356374aSAndroid Build Coastguard Worker   {
235*9356374aSAndroid Build Coastguard Worker     // Demonstrates use with a Predicate in a range-based for loop.
236*9356374aSAndroid Build Coastguard Worker     using absl::SkipWhitespace;
237*9356374aSAndroid Build Coastguard Worker     std::string s = " ,x,,x,,x,x,x,,";
238*9356374aSAndroid Build Coastguard Worker     for (absl::string_view sp : absl::StrSplit(s, ',', SkipWhitespace())) {
239*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ("x", sp);
240*9356374aSAndroid Build Coastguard Worker     }
241*9356374aSAndroid Build Coastguard Worker   }
242*9356374aSAndroid Build Coastguard Worker 
243*9356374aSAndroid Build Coastguard Worker   {
244*9356374aSAndroid Build Coastguard Worker     // Demonstrates a "smart" split to std::map using two separate calls to
245*9356374aSAndroid Build Coastguard Worker     // absl::StrSplit. One call to split the records, and another call to split
246*9356374aSAndroid Build Coastguard Worker     // the keys and values. This also uses the Limit delimiter so that the
247*9356374aSAndroid Build Coastguard Worker     // std::string "a=b=c" will split to "a" -> "b=c".
248*9356374aSAndroid Build Coastguard Worker     std::map<std::string, std::string> m;
249*9356374aSAndroid Build Coastguard Worker     for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) {
250*9356374aSAndroid Build Coastguard Worker       m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1)));
251*9356374aSAndroid Build Coastguard Worker     }
252*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("b=c", m.find("a")->second);
253*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("e", m.find("d")->second);
254*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", m.find("f")->second);
255*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", m.find("g")->second);
256*9356374aSAndroid Build Coastguard Worker   }
257*9356374aSAndroid Build Coastguard Worker }
258*9356374aSAndroid Build Coastguard Worker 
259*9356374aSAndroid Build Coastguard Worker //
260*9356374aSAndroid Build Coastguard Worker // Tests for SplitIterator
261*9356374aSAndroid Build Coastguard Worker //
262*9356374aSAndroid Build Coastguard Worker 
TEST(SplitIterator,Basics)263*9356374aSAndroid Build Coastguard Worker TEST(SplitIterator, Basics) {
264*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit("a,b", ',');
265*9356374aSAndroid Build Coastguard Worker   auto it = splitter.begin();
266*9356374aSAndroid Build Coastguard Worker   auto end = splitter.end();
267*9356374aSAndroid Build Coastguard Worker 
268*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, end);
269*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("a", *it);  // tests dereference
270*9356374aSAndroid Build Coastguard Worker   ++it;                 // tests preincrement
271*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, end);
272*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("b",
273*9356374aSAndroid Build Coastguard Worker             std::string(it->data(), it->size()));  // tests dereference as ptr
274*9356374aSAndroid Build Coastguard Worker   it++;                                            // tests postincrement
275*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, end);
276*9356374aSAndroid Build Coastguard Worker }
277*9356374aSAndroid Build Coastguard Worker 
278*9356374aSAndroid Build Coastguard Worker // Simple Predicate to skip a particular string.
279*9356374aSAndroid Build Coastguard Worker class Skip {
280*9356374aSAndroid Build Coastguard Worker  public:
Skip(const std::string & s)281*9356374aSAndroid Build Coastguard Worker   explicit Skip(const std::string& s) : s_(s) {}
operator ()(absl::string_view sp)282*9356374aSAndroid Build Coastguard Worker   bool operator()(absl::string_view sp) { return sp != s_; }
283*9356374aSAndroid Build Coastguard Worker 
284*9356374aSAndroid Build Coastguard Worker  private:
285*9356374aSAndroid Build Coastguard Worker   std::string s_;
286*9356374aSAndroid Build Coastguard Worker };
287*9356374aSAndroid Build Coastguard Worker 
TEST(SplitIterator,Predicate)288*9356374aSAndroid Build Coastguard Worker TEST(SplitIterator, Predicate) {
289*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit("a,b,c", ',', Skip("b"));
290*9356374aSAndroid Build Coastguard Worker   auto it = splitter.begin();
291*9356374aSAndroid Build Coastguard Worker   auto end = splitter.end();
292*9356374aSAndroid Build Coastguard Worker 
293*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, end);
294*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("a", *it);  // tests dereference
295*9356374aSAndroid Build Coastguard Worker   ++it;                 // tests preincrement -- "b" should be skipped here.
296*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, end);
297*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("c",
298*9356374aSAndroid Build Coastguard Worker             std::string(it->data(), it->size()));  // tests dereference as ptr
299*9356374aSAndroid Build Coastguard Worker   it++;                                            // tests postincrement
300*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, end);
301*9356374aSAndroid Build Coastguard Worker }
302*9356374aSAndroid Build Coastguard Worker 
TEST(SplitIterator,EdgeCases)303*9356374aSAndroid Build Coastguard Worker TEST(SplitIterator, EdgeCases) {
304*9356374aSAndroid Build Coastguard Worker   // Expected input and output, assuming a delimiter of ','
305*9356374aSAndroid Build Coastguard Worker   struct {
306*9356374aSAndroid Build Coastguard Worker     std::string in;
307*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> expect;
308*9356374aSAndroid Build Coastguard Worker   } specs[] = {
309*9356374aSAndroid Build Coastguard Worker       {"", {""}},
310*9356374aSAndroid Build Coastguard Worker       {"foo", {"foo"}},
311*9356374aSAndroid Build Coastguard Worker       {",", {"", ""}},
312*9356374aSAndroid Build Coastguard Worker       {",foo", {"", "foo"}},
313*9356374aSAndroid Build Coastguard Worker       {"foo,", {"foo", ""}},
314*9356374aSAndroid Build Coastguard Worker       {",foo,", {"", "foo", ""}},
315*9356374aSAndroid Build Coastguard Worker       {"foo,bar", {"foo", "bar"}},
316*9356374aSAndroid Build Coastguard Worker   };
317*9356374aSAndroid Build Coastguard Worker 
318*9356374aSAndroid Build Coastguard Worker   for (const auto& spec : specs) {
319*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(spec.in);
320*9356374aSAndroid Build Coastguard Worker     auto splitter = absl::StrSplit(spec.in, ',');
321*9356374aSAndroid Build Coastguard Worker     auto it = splitter.begin();
322*9356374aSAndroid Build Coastguard Worker     auto end = splitter.end();
323*9356374aSAndroid Build Coastguard Worker     for (const auto& expected : spec.expect) {
324*9356374aSAndroid Build Coastguard Worker       EXPECT_NE(it, end);
325*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(expected, *it++);
326*9356374aSAndroid Build Coastguard Worker     }
327*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(it, end);
328*9356374aSAndroid Build Coastguard Worker   }
329*9356374aSAndroid Build Coastguard Worker }
330*9356374aSAndroid Build Coastguard Worker 
TEST(Splitter,Const)331*9356374aSAndroid Build Coastguard Worker TEST(Splitter, Const) {
332*9356374aSAndroid Build Coastguard Worker   const auto splitter = absl::StrSplit("a,b,c", ',');
333*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(splitter, ElementsAre("a", "b", "c"));
334*9356374aSAndroid Build Coastguard Worker }
335*9356374aSAndroid Build Coastguard Worker 
TEST(Split,EmptyAndNull)336*9356374aSAndroid Build Coastguard Worker TEST(Split, EmptyAndNull) {
337*9356374aSAndroid Build Coastguard Worker   // Attention: Splitting a null absl::string_view is different than splitting
338*9356374aSAndroid Build Coastguard Worker   // an empty absl::string_view even though both string_views are considered
339*9356374aSAndroid Build Coastguard Worker   // equal. This behavior is likely surprising and undesirable. However, to
340*9356374aSAndroid Build Coastguard Worker   // maintain backward compatibility, there is a small "hack" in
341*9356374aSAndroid Build Coastguard Worker   // str_split_internal.h that preserves this behavior. If that behavior is ever
342*9356374aSAndroid Build Coastguard Worker   // changed/fixed, this test will need to be updated.
343*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::StrSplit(absl::string_view(""), '-'), ElementsAre(""));
344*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::StrSplit(absl::string_view(), '-'), ElementsAre());
345*9356374aSAndroid Build Coastguard Worker }
346*9356374aSAndroid Build Coastguard Worker 
TEST(SplitIterator,EqualityAsEndCondition)347*9356374aSAndroid Build Coastguard Worker TEST(SplitIterator, EqualityAsEndCondition) {
348*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit("a,b,c", ',');
349*9356374aSAndroid Build Coastguard Worker   auto it = splitter.begin();
350*9356374aSAndroid Build Coastguard Worker   auto it2 = it;
351*9356374aSAndroid Build Coastguard Worker 
352*9356374aSAndroid Build Coastguard Worker   // Increments it2 twice to point to "c" in the input text.
353*9356374aSAndroid Build Coastguard Worker   ++it2;
354*9356374aSAndroid Build Coastguard Worker   ++it2;
355*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("c", *it2);
356*9356374aSAndroid Build Coastguard Worker 
357*9356374aSAndroid Build Coastguard Worker   // This test uses a non-end SplitIterator as the terminating condition in a
358*9356374aSAndroid Build Coastguard Worker   // for loop. This relies on SplitIterator equality for non-end SplitIterators
359*9356374aSAndroid Build Coastguard Worker   // working correctly. At this point it2 points to "c", and we use that as the
360*9356374aSAndroid Build Coastguard Worker   // "end" condition in this test.
361*9356374aSAndroid Build Coastguard Worker   std::vector<absl::string_view> v;
362*9356374aSAndroid Build Coastguard Worker   for (; it != it2; ++it) {
363*9356374aSAndroid Build Coastguard Worker     v.push_back(*it);
364*9356374aSAndroid Build Coastguard Worker   }
365*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(v, ElementsAre("a", "b"));
366*9356374aSAndroid Build Coastguard Worker }
367*9356374aSAndroid Build Coastguard Worker 
368*9356374aSAndroid Build Coastguard Worker //
369*9356374aSAndroid Build Coastguard Worker // Tests for Splitter
370*9356374aSAndroid Build Coastguard Worker //
371*9356374aSAndroid Build Coastguard Worker 
TEST(Splitter,RangeIterators)372*9356374aSAndroid Build Coastguard Worker TEST(Splitter, RangeIterators) {
373*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit("a,b,c", ',');
374*9356374aSAndroid Build Coastguard Worker   std::vector<absl::string_view> output;
375*9356374aSAndroid Build Coastguard Worker   for (absl::string_view p : splitter) {
376*9356374aSAndroid Build Coastguard Worker     output.push_back(p);
377*9356374aSAndroid Build Coastguard Worker   }
378*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(output, ElementsAre("a", "b", "c"));
379*9356374aSAndroid Build Coastguard Worker }
380*9356374aSAndroid Build Coastguard Worker 
381*9356374aSAndroid Build Coastguard Worker // Some template functions for use in testing conversion operators
382*9356374aSAndroid Build Coastguard Worker template <typename ContainerType, typename Splitter>
TestConversionOperator(const Splitter & splitter)383*9356374aSAndroid Build Coastguard Worker void TestConversionOperator(const Splitter& splitter) {
384*9356374aSAndroid Build Coastguard Worker   ContainerType output = splitter;
385*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(output, UnorderedElementsAre("a", "b", "c", "d"));
386*9356374aSAndroid Build Coastguard Worker }
387*9356374aSAndroid Build Coastguard Worker 
388*9356374aSAndroid Build Coastguard Worker template <typename MapType, typename Splitter>
TestMapConversionOperator(const Splitter & splitter)389*9356374aSAndroid Build Coastguard Worker void TestMapConversionOperator(const Splitter& splitter) {
390*9356374aSAndroid Build Coastguard Worker   MapType m = splitter;
391*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m, UnorderedElementsAre(Pair("a", "b"), Pair("c", "d")));
392*9356374aSAndroid Build Coastguard Worker }
393*9356374aSAndroid Build Coastguard Worker 
394*9356374aSAndroid Build Coastguard Worker template <typename FirstType, typename SecondType, typename Splitter>
TestPairConversionOperator(const Splitter & splitter)395*9356374aSAndroid Build Coastguard Worker void TestPairConversionOperator(const Splitter& splitter) {
396*9356374aSAndroid Build Coastguard Worker   std::pair<FirstType, SecondType> p = splitter;
397*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(p, (std::pair<FirstType, SecondType>("a", "b")));
398*9356374aSAndroid Build Coastguard Worker }
399*9356374aSAndroid Build Coastguard Worker 
TEST(Splitter,ConversionOperator)400*9356374aSAndroid Build Coastguard Worker TEST(Splitter, ConversionOperator) {
401*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit("a,b,c,d", ',');
402*9356374aSAndroid Build Coastguard Worker 
403*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::vector<absl::string_view>>(splitter);
404*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::vector<std::string>>(splitter);
405*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::list<absl::string_view>>(splitter);
406*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::list<std::string>>(splitter);
407*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::deque<absl::string_view>>(splitter);
408*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::deque<std::string>>(splitter);
409*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::set<absl::string_view>>(splitter);
410*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::set<std::string>>(splitter);
411*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::multiset<absl::string_view>>(splitter);
412*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::multiset<std::string>>(splitter);
413*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<absl::btree_set<absl::string_view>>(splitter);
414*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<absl::btree_set<std::string>>(splitter);
415*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<absl::btree_multiset<absl::string_view>>(splitter);
416*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<absl::btree_multiset<std::string>>(splitter);
417*9356374aSAndroid Build Coastguard Worker   TestConversionOperator<std::unordered_set<std::string>>(splitter);
418*9356374aSAndroid Build Coastguard Worker 
419*9356374aSAndroid Build Coastguard Worker   // Tests conversion to map-like objects.
420*9356374aSAndroid Build Coastguard Worker 
421*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::map<absl::string_view, absl::string_view>>(
422*9356374aSAndroid Build Coastguard Worker       splitter);
423*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::map<absl::string_view, std::string>>(splitter);
424*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::map<std::string, absl::string_view>>(splitter);
425*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::map<std::string, std::string>>(splitter);
426*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
427*9356374aSAndroid Build Coastguard Worker       std::multimap<absl::string_view, absl::string_view>>(splitter);
428*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::multimap<absl::string_view, std::string>>(
429*9356374aSAndroid Build Coastguard Worker       splitter);
430*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::multimap<std::string, absl::string_view>>(
431*9356374aSAndroid Build Coastguard Worker       splitter);
432*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::multimap<std::string, std::string>>(splitter);
433*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
434*9356374aSAndroid Build Coastguard Worker       absl::btree_map<absl::string_view, absl::string_view>>(splitter);
435*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<absl::btree_map<absl::string_view, std::string>>(
436*9356374aSAndroid Build Coastguard Worker       splitter);
437*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<absl::btree_map<std::string, absl::string_view>>(
438*9356374aSAndroid Build Coastguard Worker       splitter);
439*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<absl::btree_map<std::string, std::string>>(
440*9356374aSAndroid Build Coastguard Worker       splitter);
441*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
442*9356374aSAndroid Build Coastguard Worker       absl::btree_multimap<absl::string_view, absl::string_view>>(splitter);
443*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
444*9356374aSAndroid Build Coastguard Worker       absl::btree_multimap<absl::string_view, std::string>>(splitter);
445*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
446*9356374aSAndroid Build Coastguard Worker       absl::btree_multimap<std::string, absl::string_view>>(splitter);
447*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<absl::btree_multimap<std::string, std::string>>(
448*9356374aSAndroid Build Coastguard Worker       splitter);
449*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<std::unordered_map<std::string, std::string>>(
450*9356374aSAndroid Build Coastguard Worker       splitter);
451*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
452*9356374aSAndroid Build Coastguard Worker       absl::node_hash_map<absl::string_view, absl::string_view>>(splitter);
453*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
454*9356374aSAndroid Build Coastguard Worker       absl::node_hash_map<absl::string_view, std::string>>(splitter);
455*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
456*9356374aSAndroid Build Coastguard Worker       absl::node_hash_map<std::string, absl::string_view>>(splitter);
457*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
458*9356374aSAndroid Build Coastguard Worker       absl::flat_hash_map<absl::string_view, absl::string_view>>(splitter);
459*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
460*9356374aSAndroid Build Coastguard Worker       absl::flat_hash_map<absl::string_view, std::string>>(splitter);
461*9356374aSAndroid Build Coastguard Worker   TestMapConversionOperator<
462*9356374aSAndroid Build Coastguard Worker       absl::flat_hash_map<std::string, absl::string_view>>(splitter);
463*9356374aSAndroid Build Coastguard Worker 
464*9356374aSAndroid Build Coastguard Worker   // Tests conversion to std::pair
465*9356374aSAndroid Build Coastguard Worker 
466*9356374aSAndroid Build Coastguard Worker   TestPairConversionOperator<absl::string_view, absl::string_view>(splitter);
467*9356374aSAndroid Build Coastguard Worker   TestPairConversionOperator<absl::string_view, std::string>(splitter);
468*9356374aSAndroid Build Coastguard Worker   TestPairConversionOperator<std::string, absl::string_view>(splitter);
469*9356374aSAndroid Build Coastguard Worker   TestPairConversionOperator<std::string, std::string>(splitter);
470*9356374aSAndroid Build Coastguard Worker }
471*9356374aSAndroid Build Coastguard Worker 
472*9356374aSAndroid Build Coastguard Worker // A few additional tests for conversion to std::pair. This conversion is
473*9356374aSAndroid Build Coastguard Worker // different from others because a std::pair always has exactly two elements:
474*9356374aSAndroid Build Coastguard Worker // .first and .second. The split has to work even when the split has
475*9356374aSAndroid Build Coastguard Worker // less-than, equal-to, and more-than 2 strings.
TEST(Splitter,ToPair)476*9356374aSAndroid Build Coastguard Worker TEST(Splitter, ToPair) {
477*9356374aSAndroid Build Coastguard Worker   {
478*9356374aSAndroid Build Coastguard Worker     // Empty string
479*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit("", ',');
480*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", p.first);
481*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", p.second);
482*9356374aSAndroid Build Coastguard Worker   }
483*9356374aSAndroid Build Coastguard Worker 
484*9356374aSAndroid Build Coastguard Worker   {
485*9356374aSAndroid Build Coastguard Worker     // Only first
486*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit("a", ',');
487*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("a", p.first);
488*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", p.second);
489*9356374aSAndroid Build Coastguard Worker   }
490*9356374aSAndroid Build Coastguard Worker 
491*9356374aSAndroid Build Coastguard Worker   {
492*9356374aSAndroid Build Coastguard Worker     // Only second
493*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit(",b", ',');
494*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", p.first);
495*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("b", p.second);
496*9356374aSAndroid Build Coastguard Worker   }
497*9356374aSAndroid Build Coastguard Worker 
498*9356374aSAndroid Build Coastguard Worker   {
499*9356374aSAndroid Build Coastguard Worker     // First and second.
500*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit("a,b", ',');
501*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("a", p.first);
502*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("b", p.second);
503*9356374aSAndroid Build Coastguard Worker   }
504*9356374aSAndroid Build Coastguard Worker 
505*9356374aSAndroid Build Coastguard Worker   {
506*9356374aSAndroid Build Coastguard Worker     // First and second and then more stuff that will be ignored.
507*9356374aSAndroid Build Coastguard Worker     std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ',');
508*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("a", p.first);
509*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("b", p.second);
510*9356374aSAndroid Build Coastguard Worker     // "c" is omitted.
511*9356374aSAndroid Build Coastguard Worker   }
512*9356374aSAndroid Build Coastguard Worker }
513*9356374aSAndroid Build Coastguard Worker 
TEST(Splitter,Predicates)514*9356374aSAndroid Build Coastguard Worker TEST(Splitter, Predicates) {
515*9356374aSAndroid Build Coastguard Worker   static const char kTestChars[] = ",a, ,b,";
516*9356374aSAndroid Build Coastguard Worker   using absl::AllowEmpty;
517*9356374aSAndroid Build Coastguard Worker   using absl::SkipEmpty;
518*9356374aSAndroid Build Coastguard Worker   using absl::SkipWhitespace;
519*9356374aSAndroid Build Coastguard Worker 
520*9356374aSAndroid Build Coastguard Worker   {
521*9356374aSAndroid Build Coastguard Worker     // No predicate. Does not skip empties.
522*9356374aSAndroid Build Coastguard Worker     auto splitter = absl::StrSplit(kTestChars, ',');
523*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = splitter;
524*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("", "a", " ", "b", ""));
525*9356374aSAndroid Build Coastguard Worker   }
526*9356374aSAndroid Build Coastguard Worker 
527*9356374aSAndroid Build Coastguard Worker   {
528*9356374aSAndroid Build Coastguard Worker     // Allows empty strings. Same behavior as no predicate at all.
529*9356374aSAndroid Build Coastguard Worker     auto splitter = absl::StrSplit(kTestChars, ',', AllowEmpty());
530*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v_allowempty = splitter;
531*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v_allowempty, ElementsAre("", "a", " ", "b", ""));
532*9356374aSAndroid Build Coastguard Worker 
533*9356374aSAndroid Build Coastguard Worker     // Ensures AllowEmpty equals the behavior with no predicate.
534*9356374aSAndroid Build Coastguard Worker     auto splitter_nopredicate = absl::StrSplit(kTestChars, ',');
535*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v_nopredicate = splitter_nopredicate;
536*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(v_allowempty, v_nopredicate);
537*9356374aSAndroid Build Coastguard Worker   }
538*9356374aSAndroid Build Coastguard Worker 
539*9356374aSAndroid Build Coastguard Worker   {
540*9356374aSAndroid Build Coastguard Worker     // Skips empty strings.
541*9356374aSAndroid Build Coastguard Worker     auto splitter = absl::StrSplit(kTestChars, ',', SkipEmpty());
542*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = splitter;
543*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", " ", "b"));
544*9356374aSAndroid Build Coastguard Worker   }
545*9356374aSAndroid Build Coastguard Worker 
546*9356374aSAndroid Build Coastguard Worker   {
547*9356374aSAndroid Build Coastguard Worker     // Skips empty and all-whitespace strings.
548*9356374aSAndroid Build Coastguard Worker     auto splitter = absl::StrSplit(kTestChars, ',', SkipWhitespace());
549*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = splitter;
550*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
551*9356374aSAndroid Build Coastguard Worker   }
552*9356374aSAndroid Build Coastguard Worker }
553*9356374aSAndroid Build Coastguard Worker 
554*9356374aSAndroid Build Coastguard Worker //
555*9356374aSAndroid Build Coastguard Worker // Tests for StrSplit()
556*9356374aSAndroid Build Coastguard Worker //
557*9356374aSAndroid Build Coastguard Worker 
TEST(Split,Basics)558*9356374aSAndroid Build Coastguard Worker TEST(Split, Basics) {
559*9356374aSAndroid Build Coastguard Worker   {
560*9356374aSAndroid Build Coastguard Worker     // Doesn't really do anything useful because the return value is ignored,
561*9356374aSAndroid Build Coastguard Worker     // but it should work.
562*9356374aSAndroid Build Coastguard Worker     absl::StrSplit("a,b,c", ',');
563*9356374aSAndroid Build Coastguard Worker   }
564*9356374aSAndroid Build Coastguard Worker 
565*9356374aSAndroid Build Coastguard Worker   {
566*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ',');
567*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
568*9356374aSAndroid Build Coastguard Worker   }
569*9356374aSAndroid Build Coastguard Worker 
570*9356374aSAndroid Build Coastguard Worker   {
571*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
572*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
573*9356374aSAndroid Build Coastguard Worker   }
574*9356374aSAndroid Build Coastguard Worker 
575*9356374aSAndroid Build Coastguard Worker   {
576*9356374aSAndroid Build Coastguard Worker     // Ensures that assignment works. This requires a little extra work with
577*9356374aSAndroid Build Coastguard Worker     // C++11 because of overloads with initializer_list.
578*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v;
579*9356374aSAndroid Build Coastguard Worker     v = absl::StrSplit("a,b,c", ',');
580*9356374aSAndroid Build Coastguard Worker 
581*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b", "c"));
582*9356374aSAndroid Build Coastguard Worker     std::map<std::string, std::string> m;
583*9356374aSAndroid Build Coastguard Worker     m = absl::StrSplit("a,b,c", ',');
584*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, m.size());
585*9356374aSAndroid Build Coastguard Worker     std::unordered_map<std::string, std::string> hm;
586*9356374aSAndroid Build Coastguard Worker     hm = absl::StrSplit("a,b,c", ',');
587*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, hm.size());
588*9356374aSAndroid Build Coastguard Worker   }
589*9356374aSAndroid Build Coastguard Worker }
590*9356374aSAndroid Build Coastguard Worker 
ReturnStringView()591*9356374aSAndroid Build Coastguard Worker absl::string_view ReturnStringView() { return "Hello World"; }
ReturnConstCharP()592*9356374aSAndroid Build Coastguard Worker const char* ReturnConstCharP() { return "Hello World"; }
ReturnCharP()593*9356374aSAndroid Build Coastguard Worker char* ReturnCharP() { return const_cast<char*>("Hello World"); }
594*9356374aSAndroid Build Coastguard Worker 
TEST(Split,AcceptsCertainTemporaries)595*9356374aSAndroid Build Coastguard Worker TEST(Split, AcceptsCertainTemporaries) {
596*9356374aSAndroid Build Coastguard Worker   std::vector<std::string> v;
597*9356374aSAndroid Build Coastguard Worker   v = absl::StrSplit(ReturnStringView(), ' ');
598*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(v, ElementsAre("Hello", "World"));
599*9356374aSAndroid Build Coastguard Worker   v = absl::StrSplit(ReturnConstCharP(), ' ');
600*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(v, ElementsAre("Hello", "World"));
601*9356374aSAndroid Build Coastguard Worker   v = absl::StrSplit(ReturnCharP(), ' ');
602*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(v, ElementsAre("Hello", "World"));
603*9356374aSAndroid Build Coastguard Worker }
604*9356374aSAndroid Build Coastguard Worker 
TEST(Split,Temporary)605*9356374aSAndroid Build Coastguard Worker TEST(Split, Temporary) {
606*9356374aSAndroid Build Coastguard Worker   // Use a std::string longer than the SSO length, so that when the temporary is
607*9356374aSAndroid Build Coastguard Worker   // destroyed, if the splitter keeps a reference to the string's contents,
608*9356374aSAndroid Build Coastguard Worker   // it'll reference freed memory instead of just dead on-stack memory.
609*9356374aSAndroid Build Coastguard Worker   const char input[] = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u";
610*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(sizeof(std::string), ABSL_ARRAYSIZE(input))
611*9356374aSAndroid Build Coastguard Worker       << "Input should be larger than fits on the stack.";
612*9356374aSAndroid Build Coastguard Worker 
613*9356374aSAndroid Build Coastguard Worker   // This happens more often in C++11 as part of a range-based for loop.
614*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit(std::string(input), ',');
615*9356374aSAndroid Build Coastguard Worker   std::string expected = "a";
616*9356374aSAndroid Build Coastguard Worker   for (absl::string_view letter : splitter) {
617*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, letter);
618*9356374aSAndroid Build Coastguard Worker     ++expected[0];
619*9356374aSAndroid Build Coastguard Worker   }
620*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("v", expected);
621*9356374aSAndroid Build Coastguard Worker 
622*9356374aSAndroid Build Coastguard Worker   // This happens more often in C++11 as part of a range-based for loop.
623*9356374aSAndroid Build Coastguard Worker   auto std_splitter = absl::StrSplit(std::string(input), ',');
624*9356374aSAndroid Build Coastguard Worker   expected = "a";
625*9356374aSAndroid Build Coastguard Worker   for (absl::string_view letter : std_splitter) {
626*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, letter);
627*9356374aSAndroid Build Coastguard Worker     ++expected[0];
628*9356374aSAndroid Build Coastguard Worker   }
629*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("v", expected);
630*9356374aSAndroid Build Coastguard Worker }
631*9356374aSAndroid Build Coastguard Worker 
632*9356374aSAndroid Build Coastguard Worker template <typename T>
CopyToHeap(const T & value)633*9356374aSAndroid Build Coastguard Worker static std::unique_ptr<T> CopyToHeap(const T& value) {
634*9356374aSAndroid Build Coastguard Worker   return std::unique_ptr<T>(new T(value));
635*9356374aSAndroid Build Coastguard Worker }
636*9356374aSAndroid Build Coastguard Worker 
TEST(Split,LvalueCaptureIsCopyable)637*9356374aSAndroid Build Coastguard Worker TEST(Split, LvalueCaptureIsCopyable) {
638*9356374aSAndroid Build Coastguard Worker   std::string input = "a,b";
639*9356374aSAndroid Build Coastguard Worker   auto heap_splitter = CopyToHeap(absl::StrSplit(input, ','));
640*9356374aSAndroid Build Coastguard Worker   auto stack_splitter = *heap_splitter;
641*9356374aSAndroid Build Coastguard Worker   heap_splitter.reset();
642*9356374aSAndroid Build Coastguard Worker   std::vector<std::string> result = stack_splitter;
643*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(result, testing::ElementsAre("a", "b"));
644*9356374aSAndroid Build Coastguard Worker }
645*9356374aSAndroid Build Coastguard Worker 
TEST(Split,TemporaryCaptureIsCopyable)646*9356374aSAndroid Build Coastguard Worker TEST(Split, TemporaryCaptureIsCopyable) {
647*9356374aSAndroid Build Coastguard Worker   auto heap_splitter = CopyToHeap(absl::StrSplit(std::string("a,b"), ','));
648*9356374aSAndroid Build Coastguard Worker   auto stack_splitter = *heap_splitter;
649*9356374aSAndroid Build Coastguard Worker   heap_splitter.reset();
650*9356374aSAndroid Build Coastguard Worker   std::vector<std::string> result = stack_splitter;
651*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(result, testing::ElementsAre("a", "b"));
652*9356374aSAndroid Build Coastguard Worker }
653*9356374aSAndroid Build Coastguard Worker 
TEST(Split,SplitterIsCopyableAndMoveable)654*9356374aSAndroid Build Coastguard Worker TEST(Split, SplitterIsCopyableAndMoveable) {
655*9356374aSAndroid Build Coastguard Worker   auto a = absl::StrSplit("foo", '-');
656*9356374aSAndroid Build Coastguard Worker 
657*9356374aSAndroid Build Coastguard Worker   // Ensures that the following expressions compile.
658*9356374aSAndroid Build Coastguard Worker   auto b = a;             // Copy construct
659*9356374aSAndroid Build Coastguard Worker   auto c = std::move(a);  // Move construct
660*9356374aSAndroid Build Coastguard Worker   b = c;                  // Copy assign
661*9356374aSAndroid Build Coastguard Worker   c = std::move(b);       // Move assign
662*9356374aSAndroid Build Coastguard Worker 
663*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(c, ElementsAre("foo"));
664*9356374aSAndroid Build Coastguard Worker }
665*9356374aSAndroid Build Coastguard Worker 
TEST(Split,StringDelimiter)666*9356374aSAndroid Build Coastguard Worker TEST(Split, StringDelimiter) {
667*9356374aSAndroid Build Coastguard Worker   {
668*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit("a,b", ',');
669*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
670*9356374aSAndroid Build Coastguard Worker   }
671*9356374aSAndroid Build Coastguard Worker 
672*9356374aSAndroid Build Coastguard Worker   {
673*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit("a,b", std::string(","));
674*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
675*9356374aSAndroid Build Coastguard Worker   }
676*9356374aSAndroid Build Coastguard Worker 
677*9356374aSAndroid Build Coastguard Worker   {
678*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v =
679*9356374aSAndroid Build Coastguard Worker         absl::StrSplit("a,b", absl::string_view(","));
680*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
681*9356374aSAndroid Build Coastguard Worker   }
682*9356374aSAndroid Build Coastguard Worker }
683*9356374aSAndroid Build Coastguard Worker 
684*9356374aSAndroid Build Coastguard Worker #if !defined(__cpp_char8_t)
685*9356374aSAndroid Build Coastguard Worker #if defined(__clang__)
686*9356374aSAndroid Build Coastguard Worker #pragma clang diagnostic push
687*9356374aSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wc++2a-compat"
688*9356374aSAndroid Build Coastguard Worker #endif
TEST(Split,UTF8)689*9356374aSAndroid Build Coastguard Worker TEST(Split, UTF8) {
690*9356374aSAndroid Build Coastguard Worker   // Tests splitting utf8 strings and utf8 delimiters.
691*9356374aSAndroid Build Coastguard Worker   std::string utf8_string = u8"\u03BA\u1F79\u03C3\u03BC\u03B5";
692*9356374aSAndroid Build Coastguard Worker   {
693*9356374aSAndroid Build Coastguard Worker     // A utf8 input string with an ascii delimiter.
694*9356374aSAndroid Build Coastguard Worker     std::string to_split = "a," + utf8_string;
695*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit(to_split, ',');
696*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", utf8_string));
697*9356374aSAndroid Build Coastguard Worker   }
698*9356374aSAndroid Build Coastguard Worker 
699*9356374aSAndroid Build Coastguard Worker   {
700*9356374aSAndroid Build Coastguard Worker     // A utf8 input string and a utf8 delimiter.
701*9356374aSAndroid Build Coastguard Worker     std::string to_split = "a," + utf8_string + ",b";
702*9356374aSAndroid Build Coastguard Worker     std::string unicode_delimiter = "," + utf8_string + ",";
703*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v =
704*9356374aSAndroid Build Coastguard Worker         absl::StrSplit(to_split, unicode_delimiter);
705*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
706*9356374aSAndroid Build Coastguard Worker   }
707*9356374aSAndroid Build Coastguard Worker 
708*9356374aSAndroid Build Coastguard Worker   {
709*9356374aSAndroid Build Coastguard Worker     // A utf8 input string and ByAnyChar with ascii chars.
710*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v =
711*9356374aSAndroid Build Coastguard Worker         absl::StrSplit(u8"Foo h\u00E4llo th\u4E1Ere", absl::ByAnyChar(" \t"));
712*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("Foo", u8"h\u00E4llo", u8"th\u4E1Ere"));
713*9356374aSAndroid Build Coastguard Worker   }
714*9356374aSAndroid Build Coastguard Worker }
715*9356374aSAndroid Build Coastguard Worker #if defined(__clang__)
716*9356374aSAndroid Build Coastguard Worker #pragma clang diagnostic pop
717*9356374aSAndroid Build Coastguard Worker #endif
718*9356374aSAndroid Build Coastguard Worker #endif  // !defined(__cpp_char8_t)
719*9356374aSAndroid Build Coastguard Worker 
TEST(Split,EmptyStringDelimiter)720*9356374aSAndroid Build Coastguard Worker TEST(Split, EmptyStringDelimiter) {
721*9356374aSAndroid Build Coastguard Worker   {
722*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("", "");
723*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre(""));
724*9356374aSAndroid Build Coastguard Worker   }
725*9356374aSAndroid Build Coastguard Worker 
726*9356374aSAndroid Build Coastguard Worker   {
727*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a", "");
728*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a"));
729*9356374aSAndroid Build Coastguard Worker   }
730*9356374aSAndroid Build Coastguard Worker 
731*9356374aSAndroid Build Coastguard Worker   {
732*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("ab", "");
733*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", "b"));
734*9356374aSAndroid Build Coastguard Worker   }
735*9356374aSAndroid Build Coastguard Worker 
736*9356374aSAndroid Build Coastguard Worker   {
737*9356374aSAndroid Build Coastguard Worker     std::vector<std::string> v = absl::StrSplit("a b", "");
738*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(v, ElementsAre("a", " ", "b"));
739*9356374aSAndroid Build Coastguard Worker   }
740*9356374aSAndroid Build Coastguard Worker }
741*9356374aSAndroid Build Coastguard Worker 
TEST(Split,SubstrDelimiter)742*9356374aSAndroid Build Coastguard Worker TEST(Split, SubstrDelimiter) {
743*9356374aSAndroid Build Coastguard Worker   std::vector<absl::string_view> results;
744*9356374aSAndroid Build Coastguard Worker   absl::string_view delim("//");
745*9356374aSAndroid Build Coastguard Worker 
746*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("", delim);
747*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre(""));
748*9356374aSAndroid Build Coastguard Worker 
749*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("//", delim);
750*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("", ""));
751*9356374aSAndroid Build Coastguard Worker 
752*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab", delim);
753*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab"));
754*9356374aSAndroid Build Coastguard Worker 
755*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab//", delim);
756*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab", ""));
757*9356374aSAndroid Build Coastguard Worker 
758*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab/", delim);
759*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab/"));
760*9356374aSAndroid Build Coastguard Worker 
761*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a/b", delim);
762*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a/b"));
763*9356374aSAndroid Build Coastguard Worker 
764*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a//b", delim);
765*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "b"));
766*9356374aSAndroid Build Coastguard Worker 
767*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a///b", delim);
768*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "/b"));
769*9356374aSAndroid Build Coastguard Worker 
770*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a////b", delim);
771*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "", "b"));
772*9356374aSAndroid Build Coastguard Worker }
773*9356374aSAndroid Build Coastguard Worker 
TEST(Split,EmptyResults)774*9356374aSAndroid Build Coastguard Worker TEST(Split, EmptyResults) {
775*9356374aSAndroid Build Coastguard Worker   std::vector<absl::string_view> results;
776*9356374aSAndroid Build Coastguard Worker 
777*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("", '#');
778*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre(""));
779*9356374aSAndroid Build Coastguard Worker 
780*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("#", '#');
781*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("", ""));
782*9356374aSAndroid Build Coastguard Worker 
783*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("#cd", '#');
784*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("", "cd"));
785*9356374aSAndroid Build Coastguard Worker 
786*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab#cd#", '#');
787*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab", "cd", ""));
788*9356374aSAndroid Build Coastguard Worker 
789*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab##cd", '#');
790*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab", "", "cd"));
791*9356374aSAndroid Build Coastguard Worker 
792*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab##", '#');
793*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab", "", ""));
794*9356374aSAndroid Build Coastguard Worker 
795*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("ab#ab#", '#');
796*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("ab", "ab", ""));
797*9356374aSAndroid Build Coastguard Worker 
798*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("aaaa", 'a');
799*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("", "", "", "", ""));
800*9356374aSAndroid Build Coastguard Worker 
801*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("", '#', absl::SkipEmpty());
802*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre());
803*9356374aSAndroid Build Coastguard Worker }
804*9356374aSAndroid Build Coastguard Worker 
805*9356374aSAndroid Build Coastguard Worker template <typename Delimiter>
IsFoundAtStartingPos(absl::string_view text,Delimiter d,size_t starting_pos,int expected_pos)806*9356374aSAndroid Build Coastguard Worker static bool IsFoundAtStartingPos(absl::string_view text, Delimiter d,
807*9356374aSAndroid Build Coastguard Worker                                  size_t starting_pos, int expected_pos) {
808*9356374aSAndroid Build Coastguard Worker   absl::string_view found = d.Find(text, starting_pos);
809*9356374aSAndroid Build Coastguard Worker   return found.data() != text.data() + text.size() &&
810*9356374aSAndroid Build Coastguard Worker          expected_pos == found.data() - text.data();
811*9356374aSAndroid Build Coastguard Worker }
812*9356374aSAndroid Build Coastguard Worker 
813*9356374aSAndroid Build Coastguard Worker // Helper function for testing Delimiter objects. Returns true if the given
814*9356374aSAndroid Build Coastguard Worker // Delimiter is found in the given string at the given position. This function
815*9356374aSAndroid Build Coastguard Worker // tests two cases:
816*9356374aSAndroid Build Coastguard Worker //   1. The actual text given, staring at position 0
817*9356374aSAndroid Build Coastguard Worker //   2. The text given with leading padding that should be ignored
818*9356374aSAndroid Build Coastguard Worker template <typename Delimiter>
IsFoundAt(absl::string_view text,Delimiter d,int expected_pos)819*9356374aSAndroid Build Coastguard Worker static bool IsFoundAt(absl::string_view text, Delimiter d, int expected_pos) {
820*9356374aSAndroid Build Coastguard Worker   const std::string leading_text = ",x,y,z,";
821*9356374aSAndroid Build Coastguard Worker   return IsFoundAtStartingPos(text, d, 0, expected_pos) &&
822*9356374aSAndroid Build Coastguard Worker          IsFoundAtStartingPos(leading_text + std::string(text), d,
823*9356374aSAndroid Build Coastguard Worker                               leading_text.length(),
824*9356374aSAndroid Build Coastguard Worker                               expected_pos + leading_text.length());
825*9356374aSAndroid Build Coastguard Worker }
826*9356374aSAndroid Build Coastguard Worker 
827*9356374aSAndroid Build Coastguard Worker //
828*9356374aSAndroid Build Coastguard Worker // Tests for ByString
829*9356374aSAndroid Build Coastguard Worker //
830*9356374aSAndroid Build Coastguard Worker 
831*9356374aSAndroid Build Coastguard Worker // Tests using any delimiter that represents a single comma.
832*9356374aSAndroid Build Coastguard Worker template <typename Delimiter>
TestComma(Delimiter d)833*9356374aSAndroid Build Coastguard Worker void TestComma(Delimiter d) {
834*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",", d, 0));
835*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,", d, 1));
836*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",b", d, 0));
837*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,b", d, 1));
838*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,b,", d, 1));
839*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,b,c", d, 1));
840*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", d, -1));
841*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt(" ", d, -1));
842*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", d, -1));
843*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a b c", d, -1));
844*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a;b;c", d, -1));
845*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt(";", d, -1));
846*9356374aSAndroid Build Coastguard Worker }
847*9356374aSAndroid Build Coastguard Worker 
TEST(Delimiter,ByString)848*9356374aSAndroid Build Coastguard Worker TEST(Delimiter, ByString) {
849*9356374aSAndroid Build Coastguard Worker   using absl::ByString;
850*9356374aSAndroid Build Coastguard Worker   TestComma(ByString(","));
851*9356374aSAndroid Build Coastguard Worker 
852*9356374aSAndroid Build Coastguard Worker   // Works as named variable.
853*9356374aSAndroid Build Coastguard Worker   ByString comma_string(",");
854*9356374aSAndroid Build Coastguard Worker   TestComma(comma_string);
855*9356374aSAndroid Build Coastguard Worker 
856*9356374aSAndroid Build Coastguard Worker   // The first occurrence of empty string ("") in a string is at position 0.
857*9356374aSAndroid Build Coastguard Worker   // There is a test below that demonstrates this for absl::string_view::find().
858*9356374aSAndroid Build Coastguard Worker   // If the ByString delimiter returned position 0 for this, there would
859*9356374aSAndroid Build Coastguard Worker   // be an infinite loop in the SplitIterator code. To avoid this, empty string
860*9356374aSAndroid Build Coastguard Worker   // is a special case in that it always returns the item at position 1.
861*9356374aSAndroid Build Coastguard Worker   absl::string_view abc("abc");
862*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, abc.find(""));  // "" is found at position 0
863*9356374aSAndroid Build Coastguard Worker   ByString empty("");
864*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", empty, 0));
865*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", empty, 0));
866*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("ab", empty, 1));
867*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("abc", empty, 1));
868*9356374aSAndroid Build Coastguard Worker }
869*9356374aSAndroid Build Coastguard Worker 
TEST(Split,ByChar)870*9356374aSAndroid Build Coastguard Worker TEST(Split, ByChar) {
871*9356374aSAndroid Build Coastguard Worker   using absl::ByChar;
872*9356374aSAndroid Build Coastguard Worker   TestComma(ByChar(','));
873*9356374aSAndroid Build Coastguard Worker 
874*9356374aSAndroid Build Coastguard Worker   // Works as named variable.
875*9356374aSAndroid Build Coastguard Worker   ByChar comma_char(',');
876*9356374aSAndroid Build Coastguard Worker   TestComma(comma_char);
877*9356374aSAndroid Build Coastguard Worker }
878*9356374aSAndroid Build Coastguard Worker 
879*9356374aSAndroid Build Coastguard Worker //
880*9356374aSAndroid Build Coastguard Worker // Tests for ByAnyChar
881*9356374aSAndroid Build Coastguard Worker //
882*9356374aSAndroid Build Coastguard Worker 
TEST(Delimiter,ByAnyChar)883*9356374aSAndroid Build Coastguard Worker TEST(Delimiter, ByAnyChar) {
884*9356374aSAndroid Build Coastguard Worker   using absl::ByAnyChar;
885*9356374aSAndroid Build Coastguard Worker   ByAnyChar one_delim(",");
886*9356374aSAndroid Build Coastguard Worker   // Found
887*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",", one_delim, 0));
888*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,", one_delim, 1));
889*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,b", one_delim, 1));
890*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",b", one_delim, 0));
891*9356374aSAndroid Build Coastguard Worker   // Not found
892*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", one_delim, -1));
893*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt(" ", one_delim, -1));
894*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", one_delim, -1));
895*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a;b;c", one_delim, -1));
896*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt(";", one_delim, -1));
897*9356374aSAndroid Build Coastguard Worker 
898*9356374aSAndroid Build Coastguard Worker   ByAnyChar two_delims(",;");
899*9356374aSAndroid Build Coastguard Worker   // Found
900*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",", two_delims, 0));
901*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(";", two_delims, 0));
902*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",;", two_delims, 0));
903*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(";,", two_delims, 0));
904*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(",;b", two_delims, 0));
905*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt(";,b", two_delims, 0));
906*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a;,", two_delims, 1));
907*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,;", two_delims, 1));
908*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a;,b", two_delims, 1));
909*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a,;b", two_delims, 1));
910*9356374aSAndroid Build Coastguard Worker   // Not found
911*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", two_delims, -1));
912*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt(" ", two_delims, -1));
913*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", two_delims, -1));
914*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a=b=c", two_delims, -1));
915*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("=", two_delims, -1));
916*9356374aSAndroid Build Coastguard Worker 
917*9356374aSAndroid Build Coastguard Worker   // ByAnyChar behaves just like ByString when given a delimiter of empty
918*9356374aSAndroid Build Coastguard Worker   // string. That is, it always returns a zero-length absl::string_view
919*9356374aSAndroid Build Coastguard Worker   // referring to the item at position 1, not position 0.
920*9356374aSAndroid Build Coastguard Worker   ByAnyChar empty("");
921*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", empty, 0));
922*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", empty, 0));
923*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("ab", empty, 1));
924*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("abc", empty, 1));
925*9356374aSAndroid Build Coastguard Worker }
926*9356374aSAndroid Build Coastguard Worker 
927*9356374aSAndroid Build Coastguard Worker //
928*9356374aSAndroid Build Coastguard Worker // Tests for ByAsciiWhitespace
929*9356374aSAndroid Build Coastguard Worker //
TEST(Split,ByAsciiWhitespace)930*9356374aSAndroid Build Coastguard Worker TEST(Split, ByAsciiWhitespace) {
931*9356374aSAndroid Build Coastguard Worker   using absl::ByAsciiWhitespace;
932*9356374aSAndroid Build Coastguard Worker   using absl::SkipEmpty;
933*9356374aSAndroid Build Coastguard Worker   std::vector<absl::string_view> results;
934*9356374aSAndroid Build Coastguard Worker 
935*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("aaaa\n", ByAsciiWhitespace());
936*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("aaaa", ""));
937*9356374aSAndroid Build Coastguard Worker 
938*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("aaaa\n", ByAsciiWhitespace(), SkipEmpty());
939*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("aaaa"));
940*9356374aSAndroid Build Coastguard Worker 
941*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit(" ", ByAsciiWhitespace());
942*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("", ""));
943*9356374aSAndroid Build Coastguard Worker 
944*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit(" ", ByAsciiWhitespace(), SkipEmpty());
945*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, IsEmpty());
946*9356374aSAndroid Build Coastguard Worker 
947*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a", ByAsciiWhitespace());
948*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a"));
949*9356374aSAndroid Build Coastguard Worker 
950*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("", ByAsciiWhitespace());
951*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre(""));
952*9356374aSAndroid Build Coastguard Worker 
953*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("", ByAsciiWhitespace(), SkipEmpty());
954*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, IsEmpty());
955*9356374aSAndroid Build Coastguard Worker 
956*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a b\tc\n  d\n", ByAsciiWhitespace());
957*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "b", "c", "", "", "d", ""));
958*9356374aSAndroid Build Coastguard Worker 
959*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a b\tc\n  d  \n", ByAsciiWhitespace(), SkipEmpty());
960*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "b", "c", "d"));
961*9356374aSAndroid Build Coastguard Worker 
962*9356374aSAndroid Build Coastguard Worker   results = absl::StrSplit("a\t\n\v\f\r b", ByAsciiWhitespace(), SkipEmpty());
963*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(results, ElementsAre("a", "b"));
964*9356374aSAndroid Build Coastguard Worker }
965*9356374aSAndroid Build Coastguard Worker 
966*9356374aSAndroid Build Coastguard Worker //
967*9356374aSAndroid Build Coastguard Worker // Tests for ByLength
968*9356374aSAndroid Build Coastguard Worker //
969*9356374aSAndroid Build Coastguard Worker 
TEST(Delimiter,ByLength)970*9356374aSAndroid Build Coastguard Worker TEST(Delimiter, ByLength) {
971*9356374aSAndroid Build Coastguard Worker   using absl::ByLength;
972*9356374aSAndroid Build Coastguard Worker 
973*9356374aSAndroid Build Coastguard Worker   ByLength four_char_delim(4);
974*9356374aSAndroid Build Coastguard Worker 
975*9356374aSAndroid Build Coastguard Worker   // Found
976*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("abcde", four_char_delim, 4));
977*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("abcdefghijklmnopqrstuvwxyz", four_char_delim, 4));
978*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(IsFoundAt("a b,c\nd", four_char_delim, 4));
979*9356374aSAndroid Build Coastguard Worker   // Not found
980*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("", four_char_delim, 0));
981*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("a", four_char_delim, 0));
982*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("ab", four_char_delim, 0));
983*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("abc", four_char_delim, 0));
984*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(IsFoundAt("abcd", four_char_delim, 0));
985*9356374aSAndroid Build Coastguard Worker }
986*9356374aSAndroid Build Coastguard Worker 
TEST(Split,WorksWithLargeStrings)987*9356374aSAndroid Build Coastguard Worker TEST(Split, WorksWithLargeStrings) {
988*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
989*9356374aSAndroid Build Coastguard Worker     defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
990*9356374aSAndroid Build Coastguard Worker   constexpr size_t kSize = (uint32_t{1} << 26) + 1;  // 64M + 1 byte
991*9356374aSAndroid Build Coastguard Worker #else
992*9356374aSAndroid Build Coastguard Worker   constexpr size_t kSize = (uint32_t{1} << 31) + 1;  // 2G + 1 byte
993*9356374aSAndroid Build Coastguard Worker #endif
994*9356374aSAndroid Build Coastguard Worker   if (sizeof(size_t) > 4) {
995*9356374aSAndroid Build Coastguard Worker     std::string s(kSize, 'x');
996*9356374aSAndroid Build Coastguard Worker     s.back() = '-';
997*9356374aSAndroid Build Coastguard Worker     std::vector<absl::string_view> v = absl::StrSplit(s, '-');
998*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, v.size());
999*9356374aSAndroid Build Coastguard Worker     // The first element will contain 2G of 'x's.
1000*9356374aSAndroid Build Coastguard Worker     // testing::StartsWith is too slow with a 2G string.
1001*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ('x', v[0][0]);
1002*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ('x', v[0][1]);
1003*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ('x', v[0][3]);
1004*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("", v[1]);
1005*9356374aSAndroid Build Coastguard Worker   }
1006*9356374aSAndroid Build Coastguard Worker }
1007*9356374aSAndroid Build Coastguard Worker 
TEST(SplitInternalTest,TypeTraits)1008*9356374aSAndroid Build Coastguard Worker TEST(SplitInternalTest, TypeTraits) {
1009*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::strings_internal::HasMappedType<int>::value);
1010*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
1011*9356374aSAndroid Build Coastguard Worker       (absl::strings_internal::HasMappedType<std::map<int, int>>::value));
1012*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::strings_internal::HasValueType<int>::value);
1013*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
1014*9356374aSAndroid Build Coastguard Worker       (absl::strings_internal::HasValueType<std::map<int, int>>::value));
1015*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::strings_internal::HasConstIterator<int>::value);
1016*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
1017*9356374aSAndroid Build Coastguard Worker       (absl::strings_internal::HasConstIterator<std::map<int, int>>::value));
1018*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::strings_internal::IsInitializerList<int>::value);
1019*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((absl::strings_internal::IsInitializerList<
1020*9356374aSAndroid Build Coastguard Worker                std::initializer_list<int>>::value));
1021*9356374aSAndroid Build Coastguard Worker }
1022*9356374aSAndroid Build Coastguard Worker 
1023*9356374aSAndroid Build Coastguard Worker }  // namespace
1024