checker_test.cc (6480B)
1 // Copyright 2020 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 <string> 16 17 #include "gmock/gmock.h" 18 #include "gtest/gtest.h" 19 #include "absl/strings/str_format.h" 20 21 namespace absl { 22 ABSL_NAMESPACE_BEGIN 23 namespace str_format_internal { 24 namespace { 25 26 std::string ConvToString(FormatConversionCharSet conv) { 27 std::string out; 28 #define CONV_SET_CASE(c) \ 29 if (Contains(conv, FormatConversionCharSetInternal::c)) { \ 30 out += #c; \ 31 } 32 ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) 33 #undef CONV_SET_CASE 34 if (Contains(conv, FormatConversionCharSetInternal::kStar)) { 35 out += "*"; 36 } 37 return out; 38 } 39 40 TEST(StrFormatChecker, ArgumentToConv) { 41 FormatConversionCharSet conv = ArgumentToConv<std::string>(); 42 EXPECT_EQ(ConvToString(conv), "sv"); 43 44 conv = ArgumentToConv<const char*>(); 45 EXPECT_EQ(ConvToString(conv), "sp"); 46 47 conv = ArgumentToConv<double>(); 48 EXPECT_EQ(ConvToString(conv), "fFeEgGaAv"); 49 50 conv = ArgumentToConv<int>(); 51 EXPECT_EQ(ConvToString(conv), "cdiouxXfFeEgGaAv*"); 52 53 conv = ArgumentToConv<std::string*>(); 54 EXPECT_EQ(ConvToString(conv), "p"); 55 } 56 57 #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 58 59 struct Case { 60 bool result; 61 const char* format; 62 }; 63 64 template <typename... Args> 65 constexpr Case ValidFormat(const char* format) { 66 return {ValidFormatImpl<ArgumentToConv<Args>()...>(format), format}; 67 } 68 69 TEST(StrFormatChecker, ValidFormat) { 70 // We want to make sure these expressions are constexpr and they have the 71 // expected value. 72 // If they are not constexpr the attribute will just ignore them and not give 73 // a compile time error. 74 enum e {}; 75 enum class e2 {}; 76 constexpr Case trues[] = { 77 ValidFormat<>("abc"), // 78 79 ValidFormat<e>("%d"), // 80 ValidFormat<e2>("%d"), // 81 ValidFormat<int>("%% %d"), // 82 ValidFormat<int>("%ld"), // 83 ValidFormat<int>("%lld"), // 84 ValidFormat<std::string>("%s"), // 85 ValidFormat<std::string>("%10s"), // 86 ValidFormat<int>("%.10x"), // 87 ValidFormat<int, int>("%*.3x"), // 88 ValidFormat<int>("%1.d"), // 89 ValidFormat<int>("%.d"), // 90 ValidFormat<int, double>("%d %g"), // 91 ValidFormat<int, std::string>("%*s"), // 92 ValidFormat<int, double>("%.*f"), // 93 ValidFormat<void (*)(), volatile int*>("%p %p"), // 94 ValidFormat<string_view, const char*, double, void*>( 95 "string_view=%s const char*=%s double=%f void*=%p)"), 96 ValidFormat<int>("%v"), // 97 98 ValidFormat<int>("%% %1$d"), // 99 ValidFormat<int>("%1$ld"), // 100 ValidFormat<int>("%1$lld"), // 101 ValidFormat<std::string>("%1$s"), // 102 ValidFormat<std::string>("%1$10s"), // 103 ValidFormat<int>("%1$.10x"), // 104 ValidFormat<int>("%1$*1$.*1$d"), // 105 ValidFormat<int, int>("%1$*2$.3x"), // 106 ValidFormat<int>("%1$1.d"), // 107 ValidFormat<int>("%1$.d"), // 108 ValidFormat<double, int>("%2$d %1$g"), // 109 ValidFormat<int, std::string>("%2$*1$s"), // 110 ValidFormat<int, double>("%2$.*1$f"), // 111 ValidFormat<void*, string_view, const char*, double>( 112 "string_view=%2$s const char*=%3$s double=%4$f void*=%1$p " 113 "repeat=%3$s)"), 114 ValidFormat<std::string>("%1$v"), 115 }; 116 117 for (Case c : trues) { 118 EXPECT_TRUE(c.result) << c.format; 119 } 120 121 constexpr Case falses[] = { 122 ValidFormat<int>(""), // 123 124 ValidFormat<e>("%s"), // 125 ValidFormat<e2>("%s"), // 126 ValidFormat<>("%s"), // 127 ValidFormat<>("%r"), // 128 ValidFormat<int>("%s"), // 129 ValidFormat<int>("%.1.d"), // 130 ValidFormat<int>("%*1d"), // 131 ValidFormat<int>("%1-d"), // 132 ValidFormat<std::string, int>("%*s"), // 133 ValidFormat<int>("%*d"), // 134 ValidFormat<std::string>("%p"), // 135 ValidFormat<int (*)(int)>("%d"), // 136 ValidFormat<int>("%1v"), // 137 ValidFormat<int>("%.1v"), // 138 139 ValidFormat<>("%3$d"), // 140 ValidFormat<>("%1$r"), // 141 ValidFormat<int>("%1$s"), // 142 ValidFormat<int>("%1$.1.d"), // 143 ValidFormat<int>("%1$*2$1d"), // 144 ValidFormat<int>("%1$1-d"), // 145 ValidFormat<std::string, int>("%2$*1$s"), // 146 ValidFormat<std::string>("%1$p"), // 147 ValidFormat<int>("%1$*2$v"), // 148 149 ValidFormat<int, int>("%d %2$d"), // 150 }; 151 152 for (Case c : falses) { 153 EXPECT_FALSE(c.result) << "format<" << c.format << ">"; 154 } 155 } 156 157 TEST(StrFormatChecker, LongFormat) { 158 #define CHARS_X_40 "1234567890123456789012345678901234567890" 159 #define CHARS_X_400 \ 160 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 \ 161 CHARS_X_40 CHARS_X_40 CHARS_X_40 162 #define CHARS_X_4000 \ 163 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 \ 164 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 165 constexpr char long_format[] = 166 CHARS_X_4000 "%d" CHARS_X_4000 "%s" CHARS_X_4000; 167 constexpr bool is_valid = ValidFormat<int, std::string>(long_format).result; 168 EXPECT_TRUE(is_valid); 169 } 170 171 #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 172 173 } // namespace 174 } // namespace str_format_internal 175 ABSL_NAMESPACE_END 176 } // namespace absl