xref: /aosp_15_r20/external/abseil-cpp/absl/strings/str_replace_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_replace.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <list>
18*9356374aSAndroid Build Coastguard Worker #include <map>
19*9356374aSAndroid Build Coastguard Worker #include <string>
20*9356374aSAndroid Build Coastguard Worker #include <tuple>
21*9356374aSAndroid Build Coastguard Worker #include <utility>
22*9356374aSAndroid Build Coastguard Worker #include <vector>
23*9356374aSAndroid Build Coastguard Worker 
24*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
25*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
26*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_split.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
28*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,OneReplacement)29*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, OneReplacement) {
30*9356374aSAndroid Build Coastguard Worker   std::string s;
31*9356374aSAndroid Build Coastguard Worker 
32*9356374aSAndroid Build Coastguard Worker   // Empty string.
33*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(s, {{"", ""}});
34*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
35*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(s, {{"x", ""}});
36*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
37*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(s, {{"", "y"}});
38*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
39*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(s, {{"x", "y"}});
40*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
41*9356374aSAndroid Build Coastguard Worker 
42*9356374aSAndroid Build Coastguard Worker   // Empty substring.
43*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"", ""}});
44*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
45*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"", "y"}});
46*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
47*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"x", ""}});
48*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
49*9356374aSAndroid Build Coastguard Worker 
50*9356374aSAndroid Build Coastguard Worker   // Substring not found.
51*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"xyz", "123"}});
52*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
53*9356374aSAndroid Build Coastguard Worker 
54*9356374aSAndroid Build Coastguard Worker   // Replace entire string.
55*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"abc", "xyz"}});
56*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
57*9356374aSAndroid Build Coastguard Worker 
58*9356374aSAndroid Build Coastguard Worker   // Replace once at the start.
59*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"a", "x"}});
60*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xbc");
61*9356374aSAndroid Build Coastguard Worker 
62*9356374aSAndroid Build Coastguard Worker   // Replace once in the middle.
63*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"b", "x"}});
64*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "axc");
65*9356374aSAndroid Build Coastguard Worker 
66*9356374aSAndroid Build Coastguard Worker   // Replace once at the end.
67*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"c", "x"}});
68*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abx");
69*9356374aSAndroid Build Coastguard Worker 
70*9356374aSAndroid Build Coastguard Worker   // Replace multiple times with varying lengths of original/replacement.
71*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("ababa", {{"a", "xxx"}});
72*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xxxbxxxbxxx");
73*9356374aSAndroid Build Coastguard Worker 
74*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("ababa", {{"b", "xxx"}});
75*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "axxxaxxxa");
76*9356374aSAndroid Build Coastguard Worker 
77*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("aaabaaabaaa", {{"aaa", "x"}});
78*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xbxbx");
79*9356374aSAndroid Build Coastguard Worker 
80*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abbbabbba", {{"bbb", "x"}});
81*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "axaxa");
82*9356374aSAndroid Build Coastguard Worker 
83*9356374aSAndroid Build Coastguard Worker   // Overlapping matches are replaced greedily.
84*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("aaa", {{"aa", "x"}});
85*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xa");
86*9356374aSAndroid Build Coastguard Worker 
87*9356374aSAndroid Build Coastguard Worker   // The replacements are not recursive.
88*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("aaa", {{"aa", "a"}});
89*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "aa");
90*9356374aSAndroid Build Coastguard Worker }
91*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,ManyReplacements)92*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, ManyReplacements) {
93*9356374aSAndroid Build Coastguard Worker   std::string s;
94*9356374aSAndroid Build Coastguard Worker 
95*9356374aSAndroid Build Coastguard Worker   // Empty string.
96*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("", {{"", ""}, {"x", ""}, {"", "y"}, {"x", "y"}});
97*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
98*9356374aSAndroid Build Coastguard Worker 
99*9356374aSAndroid Build Coastguard Worker   // Empty substring.
100*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"", ""}, {"", "y"}, {"x", ""}});
101*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
102*9356374aSAndroid Build Coastguard Worker 
103*9356374aSAndroid Build Coastguard Worker   // Replace entire string, one char at a time
104*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"a", "x"}, {"b", "y"}, {"c", "z"}});
105*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
106*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("zxy", {{"z", "x"}, {"x", "y"}, {"y", "z"}});
107*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
108*9356374aSAndroid Build Coastguard Worker 
109*9356374aSAndroid Build Coastguard Worker   // Replace once at the start (longer matches take precedence)
110*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("abc", {{"a", "x"}, {"ab", "xy"}, {"abc", "xyz"}});
111*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
112*9356374aSAndroid Build Coastguard Worker 
113*9356374aSAndroid Build Coastguard Worker   // Replace once in the middle.
114*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(
115*9356374aSAndroid Build Coastguard Worker       "Abc!", {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc", "yz"}, {"c", "z"}});
116*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "Ayz!");
117*9356374aSAndroid Build Coastguard Worker 
118*9356374aSAndroid Build Coastguard Worker   // Replace once at the end.
119*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll(
120*9356374aSAndroid Build Coastguard Worker       "Abc!",
121*9356374aSAndroid Build Coastguard Worker       {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc!", "yz?"}, {"c!", "z;"}});
122*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "Ayz?");
123*9356374aSAndroid Build Coastguard Worker 
124*9356374aSAndroid Build Coastguard Worker   // Replace multiple times with varying lengths of original/replacement.
125*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("ababa", {{"a", "xxx"}, {"b", "XXXX"}});
126*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xxxXXXXxxxXXXXxxx");
127*9356374aSAndroid Build Coastguard Worker 
128*9356374aSAndroid Build Coastguard Worker   // Overlapping matches are replaced greedily.
129*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("aaa", {{"aa", "x"}, {"a", "X"}});
130*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xX");
131*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("aaa", {{"a", "X"}, {"aa", "x"}});
132*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xX");
133*9356374aSAndroid Build Coastguard Worker 
134*9356374aSAndroid Build Coastguard Worker   // Two well-known sentences
135*9356374aSAndroid Build Coastguard Worker   s = absl::StrReplaceAll("the quick brown fox jumped over the lazy dogs",
136*9356374aSAndroid Build Coastguard Worker                           {
137*9356374aSAndroid Build Coastguard Worker                               {"brown", "box"},
138*9356374aSAndroid Build Coastguard Worker                               {"dogs", "jugs"},
139*9356374aSAndroid Build Coastguard Worker                               {"fox", "with"},
140*9356374aSAndroid Build Coastguard Worker                               {"jumped", "five"},
141*9356374aSAndroid Build Coastguard Worker                               {"over", "dozen"},
142*9356374aSAndroid Build Coastguard Worker                               {"quick", "my"},
143*9356374aSAndroid Build Coastguard Worker                               {"the", "pack"},
144*9356374aSAndroid Build Coastguard Worker                               {"the lazy", "liquor"},
145*9356374aSAndroid Build Coastguard Worker                           });
146*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "pack my box with five dozen liquor jugs");
147*9356374aSAndroid Build Coastguard Worker }
148*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,ManyReplacementsInMap)149*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, ManyReplacementsInMap) {
150*9356374aSAndroid Build Coastguard Worker   std::map<const char *, const char *> replacements;
151*9356374aSAndroid Build Coastguard Worker   replacements["$who"] = "Bob";
152*9356374aSAndroid Build Coastguard Worker   replacements["$count"] = "5";
153*9356374aSAndroid Build Coastguard Worker   replacements["#Noun"] = "Apples";
154*9356374aSAndroid Build Coastguard Worker   std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!",
155*9356374aSAndroid Build Coastguard Worker                                       replacements);
156*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
157*9356374aSAndroid Build Coastguard Worker }
158*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,ReplacementsInPlace)159*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, ReplacementsInPlace) {
160*9356374aSAndroid Build Coastguard Worker   std::string s = std::string("$who bought $count #Noun. Thanks $who!");
161*9356374aSAndroid Build Coastguard Worker   int count;
162*9356374aSAndroid Build Coastguard Worker   count = absl::StrReplaceAll({{"$count", absl::StrCat(5)},
163*9356374aSAndroid Build Coastguard Worker                               {"$who", "Bob"},
164*9356374aSAndroid Build Coastguard Worker                               {"#Noun", "Apples"}}, &s);
165*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(count, 4);
166*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
167*9356374aSAndroid Build Coastguard Worker }
168*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,ReplacementsInPlaceInMap)169*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, ReplacementsInPlaceInMap) {
170*9356374aSAndroid Build Coastguard Worker   std::string s = std::string("$who bought $count #Noun. Thanks $who!");
171*9356374aSAndroid Build Coastguard Worker   std::map<absl::string_view, absl::string_view> replacements;
172*9356374aSAndroid Build Coastguard Worker   replacements["$who"] = "Bob";
173*9356374aSAndroid Build Coastguard Worker   replacements["$count"] = "5";
174*9356374aSAndroid Build Coastguard Worker   replacements["#Noun"] = "Apples";
175*9356374aSAndroid Build Coastguard Worker   int count;
176*9356374aSAndroid Build Coastguard Worker   count = absl::StrReplaceAll(replacements, &s);
177*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(count, 4);
178*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
179*9356374aSAndroid Build Coastguard Worker }
180*9356374aSAndroid Build Coastguard Worker 
181*9356374aSAndroid Build Coastguard Worker struct Cont {
182*9356374aSAndroid Build Coastguard Worker   Cont() = default;
ContCont183*9356374aSAndroid Build Coastguard Worker   explicit Cont(absl::string_view src) : data(src) {}
184*9356374aSAndroid Build Coastguard Worker 
185*9356374aSAndroid Build Coastguard Worker   absl::string_view data;
186*9356374aSAndroid Build Coastguard Worker };
187*9356374aSAndroid Build Coastguard Worker 
188*9356374aSAndroid Build Coastguard Worker template <int index>
get(const Cont & c)189*9356374aSAndroid Build Coastguard Worker absl::string_view get(const Cont& c) {
190*9356374aSAndroid Build Coastguard Worker   auto splitter = absl::StrSplit(c.data, ':');
191*9356374aSAndroid Build Coastguard Worker   auto it = splitter.begin();
192*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < index; ++i) ++it;
193*9356374aSAndroid Build Coastguard Worker 
194*9356374aSAndroid Build Coastguard Worker   return *it;
195*9356374aSAndroid Build Coastguard Worker }
196*9356374aSAndroid Build Coastguard Worker 
TEST(StrReplaceAll,VariableNumber)197*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, VariableNumber) {
198*9356374aSAndroid Build Coastguard Worker   std::string s;
199*9356374aSAndroid Build Coastguard Worker   {
200*9356374aSAndroid Build Coastguard Worker     std::vector<std::pair<std::string, std::string>> replacements;
201*9356374aSAndroid Build Coastguard Worker 
202*9356374aSAndroid Build Coastguard Worker     s = "abc";
203*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(0, absl::StrReplaceAll(replacements, &s));
204*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("abc", s);
205*9356374aSAndroid Build Coastguard Worker 
206*9356374aSAndroid Build Coastguard Worker     s = "abc";
207*9356374aSAndroid Build Coastguard Worker     replacements.push_back({"a", "A"});
208*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(1, absl::StrReplaceAll(replacements, &s));
209*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("Abc", s);
210*9356374aSAndroid Build Coastguard Worker 
211*9356374aSAndroid Build Coastguard Worker     s = "abc";
212*9356374aSAndroid Build Coastguard Worker     replacements.push_back({"b", "B"});
213*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s));
214*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("ABc", s);
215*9356374aSAndroid Build Coastguard Worker 
216*9356374aSAndroid Build Coastguard Worker     s = "abc";
217*9356374aSAndroid Build Coastguard Worker     replacements.push_back({"d", "D"});
218*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s));
219*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("ABc", s);
220*9356374aSAndroid Build Coastguard Worker 
221*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("ABcABc", absl::StrReplaceAll("abcabc", replacements));
222*9356374aSAndroid Build Coastguard Worker   }
223*9356374aSAndroid Build Coastguard Worker 
224*9356374aSAndroid Build Coastguard Worker   {
225*9356374aSAndroid Build Coastguard Worker     std::map<const char*, const char*> replacements;
226*9356374aSAndroid Build Coastguard Worker     replacements["aa"] = "x";
227*9356374aSAndroid Build Coastguard Worker     replacements["a"] = "X";
228*9356374aSAndroid Build Coastguard Worker     s = "aaa";
229*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(2, absl::StrReplaceAll(replacements, &s));
230*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("xX", s);
231*9356374aSAndroid Build Coastguard Worker 
232*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ("xxX", absl::StrReplaceAll("aaaaa", replacements));
233*9356374aSAndroid Build Coastguard Worker   }
234*9356374aSAndroid Build Coastguard Worker 
235*9356374aSAndroid Build Coastguard Worker   {
236*9356374aSAndroid Build Coastguard Worker     std::list<std::pair<absl::string_view, absl::string_view>> replacements = {
237*9356374aSAndroid Build Coastguard Worker         {"a", "x"}, {"b", "y"}, {"c", "z"}};
238*9356374aSAndroid Build Coastguard Worker 
239*9356374aSAndroid Build Coastguard Worker     std::string s = absl::StrReplaceAll("abc", replacements);
240*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(s, "xyz");
241*9356374aSAndroid Build Coastguard Worker   }
242*9356374aSAndroid Build Coastguard Worker 
243*9356374aSAndroid Build Coastguard Worker   {
244*9356374aSAndroid Build Coastguard Worker     using X = std::tuple<absl::string_view, std::string, int>;
245*9356374aSAndroid Build Coastguard Worker     std::vector<X> replacements(3);
246*9356374aSAndroid Build Coastguard Worker     replacements[0] = X{"a", "x", 1};
247*9356374aSAndroid Build Coastguard Worker     replacements[1] = X{"b", "y", 0};
248*9356374aSAndroid Build Coastguard Worker     replacements[2] = X{"c", "z", -1};
249*9356374aSAndroid Build Coastguard Worker 
250*9356374aSAndroid Build Coastguard Worker     std::string s = absl::StrReplaceAll("abc", replacements);
251*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(s, "xyz");
252*9356374aSAndroid Build Coastguard Worker   }
253*9356374aSAndroid Build Coastguard Worker 
254*9356374aSAndroid Build Coastguard Worker   {
255*9356374aSAndroid Build Coastguard Worker     std::vector<Cont> replacements(3);
256*9356374aSAndroid Build Coastguard Worker     replacements[0] = Cont{"a:x"};
257*9356374aSAndroid Build Coastguard Worker     replacements[1] = Cont{"b:y"};
258*9356374aSAndroid Build Coastguard Worker     replacements[2] = Cont{"c:z"};
259*9356374aSAndroid Build Coastguard Worker 
260*9356374aSAndroid Build Coastguard Worker     std::string s = absl::StrReplaceAll("abc", replacements);
261*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(s, "xyz");
262*9356374aSAndroid Build Coastguard Worker   }
263*9356374aSAndroid Build Coastguard Worker }
264*9356374aSAndroid Build Coastguard Worker 
265*9356374aSAndroid Build Coastguard Worker // Same as above, but using the in-place variant of absl::StrReplaceAll,
266*9356374aSAndroid Build Coastguard Worker // that returns the # of replacements performed.
TEST(StrReplaceAll,Inplace)267*9356374aSAndroid Build Coastguard Worker TEST(StrReplaceAll, Inplace) {
268*9356374aSAndroid Build Coastguard Worker   std::string s;
269*9356374aSAndroid Build Coastguard Worker   int reps;
270*9356374aSAndroid Build Coastguard Worker 
271*9356374aSAndroid Build Coastguard Worker   // Empty string.
272*9356374aSAndroid Build Coastguard Worker   s = "";
273*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"", ""}, {"x", ""}, {"", "y"}, {"x", "y"}}, &s);
274*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 0);
275*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "");
276*9356374aSAndroid Build Coastguard Worker 
277*9356374aSAndroid Build Coastguard Worker   // Empty substring.
278*9356374aSAndroid Build Coastguard Worker   s = "abc";
279*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"", ""}, {"", "y"}, {"x", ""}}, &s);
280*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 0);
281*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "abc");
282*9356374aSAndroid Build Coastguard Worker 
283*9356374aSAndroid Build Coastguard Worker   // Replace entire string, one char at a time
284*9356374aSAndroid Build Coastguard Worker   s = "abc";
285*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"a", "x"}, {"b", "y"}, {"c", "z"}}, &s);
286*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 3);
287*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
288*9356374aSAndroid Build Coastguard Worker   s = "zxy";
289*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"z", "x"}, {"x", "y"}, {"y", "z"}}, &s);
290*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 3);
291*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
292*9356374aSAndroid Build Coastguard Worker 
293*9356374aSAndroid Build Coastguard Worker   // Replace once at the start (longer matches take precedence)
294*9356374aSAndroid Build Coastguard Worker   s = "abc";
295*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"a", "x"}, {"ab", "xy"}, {"abc", "xyz"}}, &s);
296*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 1);
297*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xyz");
298*9356374aSAndroid Build Coastguard Worker 
299*9356374aSAndroid Build Coastguard Worker   // Replace once in the middle.
300*9356374aSAndroid Build Coastguard Worker   s = "Abc!";
301*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll(
302*9356374aSAndroid Build Coastguard Worker       {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc", "yz"}, {"c", "z"}}, &s);
303*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 1);
304*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "Ayz!");
305*9356374aSAndroid Build Coastguard Worker 
306*9356374aSAndroid Build Coastguard Worker   // Replace once at the end.
307*9356374aSAndroid Build Coastguard Worker   s = "Abc!";
308*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll(
309*9356374aSAndroid Build Coastguard Worker       {{"a", "x"}, {"ab", "xy"}, {"b", "y"}, {"bc!", "yz?"}, {"c!", "z;"}}, &s);
310*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 1);
311*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "Ayz?");
312*9356374aSAndroid Build Coastguard Worker 
313*9356374aSAndroid Build Coastguard Worker   // Replace multiple times with varying lengths of original/replacement.
314*9356374aSAndroid Build Coastguard Worker   s = "ababa";
315*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"a", "xxx"}, {"b", "XXXX"}}, &s);
316*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 5);
317*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xxxXXXXxxxXXXXxxx");
318*9356374aSAndroid Build Coastguard Worker 
319*9356374aSAndroid Build Coastguard Worker   // Overlapping matches are replaced greedily.
320*9356374aSAndroid Build Coastguard Worker   s = "aaa";
321*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"aa", "x"}, {"a", "X"}}, &s);
322*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 2);
323*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xX");
324*9356374aSAndroid Build Coastguard Worker   s = "aaa";
325*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll({{"a", "X"}, {"aa", "x"}}, &s);
326*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 2);
327*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "xX");
328*9356374aSAndroid Build Coastguard Worker 
329*9356374aSAndroid Build Coastguard Worker   // Two well-known sentences
330*9356374aSAndroid Build Coastguard Worker   s = "the quick brown fox jumped over the lazy dogs";
331*9356374aSAndroid Build Coastguard Worker   reps = absl::StrReplaceAll(
332*9356374aSAndroid Build Coastguard Worker       {
333*9356374aSAndroid Build Coastguard Worker           {"brown", "box"},
334*9356374aSAndroid Build Coastguard Worker           {"dogs", "jugs"},
335*9356374aSAndroid Build Coastguard Worker           {"fox", "with"},
336*9356374aSAndroid Build Coastguard Worker           {"jumped", "five"},
337*9356374aSAndroid Build Coastguard Worker           {"over", "dozen"},
338*9356374aSAndroid Build Coastguard Worker           {"quick", "my"},
339*9356374aSAndroid Build Coastguard Worker           {"the", "pack"},
340*9356374aSAndroid Build Coastguard Worker           {"the lazy", "liquor"},
341*9356374aSAndroid Build Coastguard Worker       },
342*9356374aSAndroid Build Coastguard Worker       &s);
343*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(reps, 8);
344*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s, "pack my box with five dozen liquor jugs");
345*9356374aSAndroid Build Coastguard Worker }
346