2 * Copyright 2014 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <glog/logging.h>
18 #include <gtest/gtest.h>
23 #include <folly/gen/String.h>
25 using namespace folly::gen;
26 using namespace folly;
27 using std::make_tuple;
32 using std::unique_ptr;
35 TEST(StringGen, EmptySplit) {
36 auto collect = eachTo<std::string>() | as<vector>();
38 auto pieces = split("", ',') | collect;
39 EXPECT_EQ(0, pieces.size());
42 // The last delimiter is eaten, just like std::getline
44 auto pieces = split(",", ',') | collect;
45 EXPECT_EQ(1, pieces.size());
46 EXPECT_EQ("", pieces[0]);
50 auto pieces = split(",,", ',') | collect;
51 EXPECT_EQ(2, pieces.size());
52 EXPECT_EQ("", pieces[0]);
53 EXPECT_EQ("", pieces[1]);
57 auto pieces = split(",,", ',') | take(1) | collect;
58 EXPECT_EQ(1, pieces.size());
59 EXPECT_EQ("", pieces[0]);
63 TEST(StringGen, Split) {
64 auto collect = eachTo<std::string>() | as<vector>();
66 auto pieces = split("hello,, world, goodbye, meow", ',') | collect;
67 EXPECT_EQ(5, pieces.size());
68 EXPECT_EQ("hello", pieces[0]);
69 EXPECT_EQ("", pieces[1]);
70 EXPECT_EQ(" world", pieces[2]);
71 EXPECT_EQ(" goodbye", pieces[3]);
72 EXPECT_EQ(" meow", pieces[4]);
76 auto pieces = split("hello,, world, goodbye, meow", ',')
78 EXPECT_EQ(3, pieces.size());
79 EXPECT_EQ("hello", pieces[0]);
80 EXPECT_EQ("", pieces[1]);
81 EXPECT_EQ(" world", pieces[2]);
85 auto pieces = split("hello,, world, goodbye, meow", ",")
87 EXPECT_EQ(5, pieces.size());
88 EXPECT_EQ("hello", pieces[0]);
89 EXPECT_EQ("", pieces[1]);
90 EXPECT_EQ(" world", pieces[2]);
94 auto pieces = split("hello,, world, goodbye, meow", ", ")
96 EXPECT_EQ(4, pieces.size());
97 EXPECT_EQ("hello,", pieces[0]);
98 EXPECT_EQ("world", pieces[1]);
99 EXPECT_EQ("goodbye", pieces[2]);
100 EXPECT_EQ("meow", pieces[3]);
104 TEST(StringGen, SplitByNewLine) {
105 auto collect = eachTo<std::string>() | as<vector>();
107 auto pieces = lines("hello\n\n world\r\n goodbye\r meow") | collect;
108 EXPECT_EQ(5, pieces.size());
109 EXPECT_EQ("hello", pieces[0]);
110 EXPECT_EQ("", pieces[1]);
111 EXPECT_EQ(" world", pieces[2]);
112 EXPECT_EQ(" goodbye", pieces[3]);
113 EXPECT_EQ(" meow", pieces[4]);
117 TEST(StringGen, EmptyResplit) {
118 auto collect = eachTo<std::string>() | as<vector>();
120 auto pieces = from({""}) | resplit(',') | collect;
121 EXPECT_EQ(0, pieces.size());
124 // The last delimiter is eaten, just like std::getline
126 auto pieces = from({","}) | resplit(',') | collect;
127 EXPECT_EQ(1, pieces.size());
128 EXPECT_EQ("", pieces[0]);
132 auto pieces = from({",,"}) | resplit(',') | collect;
133 EXPECT_EQ(2, pieces.size());
134 EXPECT_EQ("", pieces[0]);
135 EXPECT_EQ("", pieces[1]);
139 TEST(StringGen, EachToTuple) {
141 auto lines = "2:1.414:yo 3:1.732:hi";
144 | eachToTuple<int, double, std::string>(':')
146 vector<tuple<int, double, std::string>> expected {
147 make_tuple(2, 1.414, "yo"),
148 make_tuple(3, 1.732, "hi"),
150 EXPECT_EQ(expected, actual);
156 | eachToTuple<int>(',')
158 vector<tuple<int>> expected {
162 EXPECT_EQ(expected, actual);
165 // StringPiece target
166 auto lines = "1:cat 2:dog";
169 | eachToTuple<int, StringPiece>(':')
171 vector<tuple<int, StringPiece>> expected {
172 make_tuple(1, "cat"),
173 make_tuple(2, "dog"),
175 EXPECT_EQ(expected, actual);
179 auto lines = "2:tjackson:4 3::5";
182 | eachToTuple<int, fbstring, int>(':')
184 vector<tuple<int, fbstring, int>> expected {
185 make_tuple(2, "tjackson", 4),
186 make_tuple(3, "", 5),
188 EXPECT_EQ(expected, actual);
192 auto lines = "1:2 3:4:5";
193 EXPECT_THROW((split(lines, ' ')
194 | eachToTuple<int, int>(':')
200 auto lines = "1:2:3 4:5";
201 EXPECT_THROW((split(lines, ' ')
202 | eachToTuple<int, int, int>(':')
208 TEST(StringGen, EachToPair) {
211 auto lines = "2:1.414 3:1.732";
214 | eachToPair<int, double>(':')
215 | as<std::map<int, double>>();
216 std::map<int, double> expected {
220 EXPECT_EQ(expected, actual);
224 auto lines = "ab=>cd ef=>gh";
227 | eachToPair<string, string>("=>")
228 | as<std::map<string, string>>();
229 std::map<string, string> expected {
233 EXPECT_EQ(expected, actual);
237 TEST(StringGen, Resplit) {
238 auto collect = eachTo<std::string>() | as<vector>();
240 auto pieces = from({"hello,, world, goodbye, meow"}) |
241 resplit(',') | collect;
242 EXPECT_EQ(5, pieces.size());
243 EXPECT_EQ("hello", pieces[0]);
244 EXPECT_EQ("", pieces[1]);
245 EXPECT_EQ(" world", pieces[2]);
246 EXPECT_EQ(" goodbye", pieces[3]);
247 EXPECT_EQ(" meow", pieces[4]);
250 auto pieces = from({"hel", "lo,", ", world", ", goodbye, m", "eow"}) |
251 resplit(',') | collect;
252 EXPECT_EQ(5, pieces.size());
253 EXPECT_EQ("hello", pieces[0]);
254 EXPECT_EQ("", pieces[1]);
255 EXPECT_EQ(" world", pieces[2]);
256 EXPECT_EQ(" goodbye", pieces[3]);
257 EXPECT_EQ(" meow", pieces[4]);
262 void runUnsplitSuite(F fn) {
264 fn("hello,world,goodbye");
271 TEST(StringGen, Unsplit) {
273 auto basicFn = [](StringPiece s) {
274 EXPECT_EQ(split(s, ',') | unsplit(','), s);
277 auto existingBuffer = [](StringPiece s) {
278 folly::fbstring buffer("asdf");
279 split(s, ',') | unsplit(',', &buffer);
280 auto expected = folly::to<folly::fbstring>(
281 "asdf", s.empty() ? "" : ",", s);
282 EXPECT_EQ(expected, buffer);
285 auto emptyBuffer = [](StringPiece s) {
287 split(s, ',') | unsplit(',', &buffer);
288 EXPECT_EQ(s, buffer);
291 auto stringDelim = [](StringPiece s) {
292 EXPECT_EQ(s, split(s, ',') | unsplit(","));
294 split(s, ',') | unsplit(",", &buffer);
295 EXPECT_EQ(buffer, s);
298 runUnsplitSuite(basicFn);
299 runUnsplitSuite(existingBuffer);
300 runUnsplitSuite(emptyBuffer);
301 runUnsplitSuite(stringDelim);
302 EXPECT_EQ("1, 2, 3", seq(1, 3) | unsplit(", "));
305 int main(int argc, char *argv[]) {
306 testing::InitGoogleTest(&argc, argv);
307 gflags::ParseCommandLineFlags(&argc, &argv, true);
308 return RUN_ALL_TESTS();