tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

str_replace_test.cc (10255B)


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