tor-browser

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

substitute_test.cc (11145B)


      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/substitute.h"
     16 
     17 #include <cstdint>
     18 #include <cstring>
     19 #include <string>
     20 #include <vector>
     21 
     22 #include "gtest/gtest.h"
     23 #include "absl/strings/str_cat.h"
     24 #include "absl/strings/string_view.h"
     25 
     26 namespace {
     27 
     28 struct MyStruct {
     29  template <typename Sink>
     30  friend void AbslStringify(Sink& sink, const MyStruct& s) {
     31    sink.Append("MyStruct{.value = ");
     32    sink.Append(absl::StrCat(s.value));
     33    sink.Append("}");
     34  }
     35  int value;
     36 };
     37 
     38 TEST(SubstituteTest, Substitute) {
     39  // Basic.
     40  EXPECT_EQ("Hello, world!", absl::Substitute("$0, $1!", "Hello", "world"));
     41 
     42  // Non-char* types.
     43  EXPECT_EQ("123 0.2 0.1 foo true false x",
     44            absl::Substitute("$0 $1 $2 $3 $4 $5 $6", 123, 0.2, 0.1f,
     45                             std::string("foo"), true, false, 'x'));
     46 
     47  // All int types.
     48  EXPECT_EQ(
     49      "-32767 65535 "
     50      "-1234567890 3234567890 "
     51      "-1234567890 3234567890 "
     52      "-1234567890123456789 9234567890123456789",
     53      absl::Substitute(
     54          "$0 $1 $2 $3 $4 $5 $6 $7",
     55          static_cast<short>(-32767),          // NOLINT(runtime/int)
     56          static_cast<unsigned short>(65535),  // NOLINT(runtime/int)
     57          -1234567890, 3234567890U, -1234567890L, 3234567890UL,
     58          -int64_t{1234567890123456789}, uint64_t{9234567890123456789u}));
     59 
     60  // Hex format
     61  EXPECT_EQ("0 1 f ffff0ffff 0123456789abcdef",
     62            absl::Substitute("$0$1$2$3$4 $5",  //
     63                             absl::Hex(0), absl::Hex(1, absl::kSpacePad2),
     64                             absl::Hex(0xf, absl::kSpacePad2),
     65                             absl::Hex(int16_t{-1}, absl::kSpacePad5),
     66                             absl::Hex(int16_t{-1}, absl::kZeroPad5),
     67                             absl::Hex(0x123456789abcdef, absl::kZeroPad16)));
     68 
     69  // Dec format
     70  EXPECT_EQ("0 115   -1-0001 81985529216486895",
     71            absl::Substitute("$0$1$2$3$4 $5",  //
     72                             absl::Dec(0), absl::Dec(1, absl::kSpacePad2),
     73                             absl::Dec(0xf, absl::kSpacePad2),
     74                             absl::Dec(int16_t{-1}, absl::kSpacePad5),
     75                             absl::Dec(int16_t{-1}, absl::kZeroPad5),
     76                             absl::Dec(0x123456789abcdef, absl::kZeroPad16)));
     77 
     78  // Pointer.
     79  const int* int_p = reinterpret_cast<const int*>(0x12345);
     80  std::string str = absl::Substitute("$0", int_p);
     81  EXPECT_EQ(absl::StrCat("0x", absl::Hex(int_p)), str);
     82 
     83  // Volatile Pointer.
     84  // Like C++ streamed I/O, such pointers implicitly become bool
     85  volatile int vol = 237;
     86  volatile int* volatile volptr = &vol;
     87  str = absl::Substitute("$0", volptr);
     88  EXPECT_EQ("true", str);
     89 
     90  // null is special. StrCat prints 0x0. Substitute prints NULL.
     91  const uint64_t* null_p = nullptr;
     92  str = absl::Substitute("$0", null_p);
     93  EXPECT_EQ("NULL", str);
     94 
     95  // char* is also special.
     96  const char* char_p = "print me";
     97  str = absl::Substitute("$0", char_p);
     98  EXPECT_EQ("print me", str);
     99 
    100  char char_buf[16];
    101  strncpy(char_buf, "print me too", sizeof(char_buf));
    102  str = absl::Substitute("$0", char_buf);
    103  EXPECT_EQ("print me too", str);
    104 
    105  // null char* is "doubly" special. Represented as the empty string.
    106  char_p = nullptr;
    107  str = absl::Substitute("$0", char_p);
    108  EXPECT_EQ("", str);
    109 
    110  // Out-of-order.
    111  EXPECT_EQ("b, a, c, b", absl::Substitute("$1, $0, $2, $1", "a", "b", "c"));
    112 
    113  // Literal $
    114  EXPECT_EQ("$", absl::Substitute("$$"));
    115 
    116  EXPECT_EQ("$1", absl::Substitute("$$1"));
    117 
    118  // Test all overloads.
    119  EXPECT_EQ("a", absl::Substitute("$0", "a"));
    120  EXPECT_EQ("a b", absl::Substitute("$0 $1", "a", "b"));
    121  EXPECT_EQ("a b c", absl::Substitute("$0 $1 $2", "a", "b", "c"));
    122  EXPECT_EQ("a b c d", absl::Substitute("$0 $1 $2 $3", "a", "b", "c", "d"));
    123  EXPECT_EQ("a b c d e",
    124            absl::Substitute("$0 $1 $2 $3 $4", "a", "b", "c", "d", "e"));
    125  EXPECT_EQ("a b c d e f", absl::Substitute("$0 $1 $2 $3 $4 $5", "a", "b", "c",
    126                                            "d", "e", "f"));
    127  EXPECT_EQ("a b c d e f g", absl::Substitute("$0 $1 $2 $3 $4 $5 $6", "a", "b",
    128                                              "c", "d", "e", "f", "g"));
    129  EXPECT_EQ("a b c d e f g h",
    130            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d", "e",
    131                             "f", "g", "h"));
    132  EXPECT_EQ("a b c d e f g h i",
    133            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c", "d",
    134                             "e", "f", "g", "h", "i"));
    135  EXPECT_EQ("a b c d e f g h i j",
    136            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b", "c",
    137                             "d", "e", "f", "g", "h", "i", "j"));
    138  EXPECT_EQ("a b c d e f g h i j b0",
    139            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10", "a", "b", "c",
    140                             "d", "e", "f", "g", "h", "i", "j"));
    141 
    142  const char* null_cstring = nullptr;
    143  EXPECT_EQ("Text: ''", absl::Substitute("Text: '$0'", null_cstring));
    144 
    145  MyStruct s1 = MyStruct{17};
    146  MyStruct s2 = MyStruct{1043};
    147  EXPECT_EQ("MyStruct{.value = 17}, MyStruct{.value = 1043}",
    148            absl::Substitute("$0, $1", s1, s2));
    149 }
    150 
    151 TEST(SubstituteTest, SubstituteAndAppend) {
    152  std::string str = "Hello";
    153  absl::SubstituteAndAppend(&str, ", $0!", "world");
    154  EXPECT_EQ("Hello, world!", str);
    155 
    156  // Test all overloads.
    157  str.clear();
    158  absl::SubstituteAndAppend(&str, "$0", "a");
    159  EXPECT_EQ("a", str);
    160  str.clear();
    161  absl::SubstituteAndAppend(&str, "$0 $1", "a", "b");
    162  EXPECT_EQ("a b", str);
    163  str.clear();
    164  absl::SubstituteAndAppend(&str, "$0 $1 $2", "a", "b", "c");
    165  EXPECT_EQ("a b c", str);
    166  str.clear();
    167  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3", "a", "b", "c", "d");
    168  EXPECT_EQ("a b c d", str);
    169  str.clear();
    170  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4", "a", "b", "c", "d", "e");
    171  EXPECT_EQ("a b c d e", str);
    172  str.clear();
    173  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5", "a", "b", "c", "d", "e",
    174                            "f");
    175  EXPECT_EQ("a b c d e f", str);
    176  str.clear();
    177  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6", "a", "b", "c", "d",
    178                            "e", "f", "g");
    179  EXPECT_EQ("a b c d e f g", str);
    180  str.clear();
    181  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d",
    182                            "e", "f", "g", "h");
    183  EXPECT_EQ("a b c d e f g h", str);
    184  str.clear();
    185  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c",
    186                            "d", "e", "f", "g", "h", "i");
    187  EXPECT_EQ("a b c d e f g h i", str);
    188  str.clear();
    189  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b",
    190                            "c", "d", "e", "f", "g", "h", "i", "j");
    191  EXPECT_EQ("a b c d e f g h i j", str);
    192 
    193  str.clear();
    194  MyStruct s1 = MyStruct{17};
    195  MyStruct s2 = MyStruct{1043};
    196  absl::SubstituteAndAppend(&str, "$0, $1", s1, s2);
    197  EXPECT_EQ("MyStruct{.value = 17}, MyStruct{.value = 1043}", str);
    198 }
    199 
    200 TEST(SubstituteTest, VectorBoolRef) {
    201  std::vector<bool> v = {true, false};
    202  const auto& cv = v;
    203  EXPECT_EQ("true false true false",
    204            absl::Substitute("$0 $1 $2 $3", v[0], v[1], cv[0], cv[1]));
    205 
    206  std::string str = "Logic be like: ";
    207  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3", v[0], v[1], cv[0], cv[1]);
    208  EXPECT_EQ("Logic be like: true false true false", str);
    209 }
    210 
    211 TEST(SubstituteTest, Enums) {
    212  enum UnscopedEnum { kEnum0 = 0, kEnum1 = 1 };
    213  EXPECT_EQ("0 1", absl::Substitute("$0 $1", UnscopedEnum::kEnum0,
    214                                    UnscopedEnum::kEnum1));
    215 
    216  enum class ScopedEnum { kEnum0 = 0, kEnum1 = 1 };
    217  EXPECT_EQ("0 1",
    218            absl::Substitute("$0 $1", ScopedEnum::kEnum0, ScopedEnum::kEnum1));
    219 
    220  enum class ScopedEnumInt32 : int32_t { kEnum0 = 989, kEnum1 = INT32_MIN };
    221  EXPECT_EQ("989 -2147483648",
    222            absl::Substitute("$0 $1", ScopedEnumInt32::kEnum0,
    223                             ScopedEnumInt32::kEnum1));
    224 
    225  enum class ScopedEnumUInt32 : uint32_t { kEnum0 = 1, kEnum1 = UINT32_MAX };
    226  EXPECT_EQ("1 4294967295", absl::Substitute("$0 $1", ScopedEnumUInt32::kEnum0,
    227                                             ScopedEnumUInt32::kEnum1));
    228 
    229  enum class ScopedEnumInt64 : int64_t { kEnum0 = -1, kEnum1 = 42949672950 };
    230  EXPECT_EQ("-1 42949672950", absl::Substitute("$0 $1", ScopedEnumInt64::kEnum0,
    231                                               ScopedEnumInt64::kEnum1));
    232 
    233  enum class ScopedEnumUInt64 : uint64_t { kEnum0 = 1, kEnum1 = 42949672950 };
    234  EXPECT_EQ("1 42949672950", absl::Substitute("$0 $1", ScopedEnumUInt64::kEnum0,
    235                                              ScopedEnumUInt64::kEnum1));
    236 
    237  enum class ScopedEnumChar : signed char { kEnum0 = -1, kEnum1 = 1 };
    238  EXPECT_EQ("-1 1", absl::Substitute("$0 $1", ScopedEnumChar::kEnum0,
    239                                     ScopedEnumChar::kEnum1));
    240 
    241  enum class ScopedEnumUChar : unsigned char {
    242    kEnum0 = 0,
    243    kEnum1 = 1,
    244    kEnumMax = 255
    245  };
    246  EXPECT_EQ("0 1 255", absl::Substitute("$0 $1 $2", ScopedEnumUChar::kEnum0,
    247                                        ScopedEnumUChar::kEnum1,
    248                                        ScopedEnumUChar::kEnumMax));
    249 
    250  enum class ScopedEnumInt16 : int16_t { kEnum0 = -100, kEnum1 = 10000 };
    251  EXPECT_EQ("-100 10000", absl::Substitute("$0 $1", ScopedEnumInt16::kEnum0,
    252                                           ScopedEnumInt16::kEnum1));
    253 
    254  enum class ScopedEnumUInt16 : uint16_t { kEnum0 = 0, kEnum1 = 10000 };
    255  EXPECT_EQ("0 10000", absl::Substitute("$0 $1", ScopedEnumUInt16::kEnum0,
    256                                        ScopedEnumUInt16::kEnum1));
    257 }
    258 
    259 enum class EnumWithStringify { Many = 0, Choices = 1 };
    260 
    261 template <typename Sink>
    262 void AbslStringify(Sink& sink, EnumWithStringify e) {
    263  sink.Append(e == EnumWithStringify::Many ? "Many" : "Choices");
    264 }
    265 
    266 TEST(SubstituteTest, AbslStringifyWithEnum) {
    267  const auto e = EnumWithStringify::Choices;
    268  EXPECT_EQ(absl::Substitute("$0", e), "Choices");
    269 }
    270 
    271 #if GTEST_HAS_DEATH_TEST
    272 
    273 TEST(SubstituteDeathTest, SubstituteDeath) {
    274  EXPECT_DEBUG_DEATH(
    275      static_cast<void>(absl::Substitute(absl::string_view("-$2"), "a", "b")),
    276      "Invalid absl::Substitute\\(\\) format string: asked for \"\\$2\", "
    277      "but only 2 args were given.");
    278  EXPECT_DEBUG_DEATH(
    279      static_cast<void>(absl::Substitute(absl::string_view("-$z-"))),
    280      "Invalid absl::Substitute\\(\\) format string: \"-\\$z-\"");
    281  EXPECT_DEBUG_DEATH(
    282      static_cast<void>(absl::Substitute(absl::string_view("-$"))),
    283      "Invalid absl::Substitute\\(\\) format string: \"-\\$\"");
    284 }
    285 
    286 #endif  // GTEST_HAS_DEATH_TEST
    287 
    288 }  // namespace