00001 #include <string>
00002
00003 #include "gmock/gmock.h"
00004 #include "gtest/gtest.h"
00005 #include "absl/strings/str_format.h"
00006
00007 namespace absl {
00008 namespace str_format_internal {
00009 namespace {
00010
00011 std::string ConvToString(Conv conv) {
00012 std::string out;
00013 #define CONV_SET_CASE(c) \
00014 if (Contains(conv, Conv::c)) out += #c;
00015 ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, )
00016 #undef CONV_SET_CASE
00017 if (Contains(conv, Conv::star)) out += "*";
00018 return out;
00019 }
00020
00021 TEST(StrFormatChecker, ArgumentToConv) {
00022 Conv conv = ArgumentToConv<std::string>();
00023 EXPECT_EQ(ConvToString(conv), "s");
00024
00025 conv = ArgumentToConv<const char*>();
00026 EXPECT_EQ(ConvToString(conv), "sp");
00027
00028 conv = ArgumentToConv<double>();
00029 EXPECT_EQ(ConvToString(conv), "fFeEgGaA");
00030
00031 conv = ArgumentToConv<int>();
00032 EXPECT_EQ(ConvToString(conv), "cdiouxXfFeEgGaA*");
00033
00034 conv = ArgumentToConv<std::string*>();
00035 EXPECT_EQ(ConvToString(conv), "p");
00036 }
00037
00038 #if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
00039
00040 struct Case {
00041 bool result;
00042 const char* format;
00043 };
00044
00045 template <typename... Args>
00046 constexpr Case ValidFormat(const char* format) {
00047 return {ValidFormatImpl<ArgumentToConv<Args>()...>(format), format};
00048 }
00049
00050 TEST(StrFormatChecker, ValidFormat) {
00051
00052
00053
00054
00055 enum e {};
00056 enum class e2 {};
00057 constexpr Case trues[] = {
00058 ValidFormat<>("abc"),
00059
00060 ValidFormat<e>("%d"),
00061 ValidFormat<e2>("%d"),
00062 ValidFormat<int>("%% %d"),
00063 ValidFormat<int>("%ld"),
00064 ValidFormat<int>("%lld"),
00065 ValidFormat<std::string>("%s"),
00066 ValidFormat<std::string>("%10s"),
00067 ValidFormat<int>("%.10x"),
00068 ValidFormat<int, int>("%*.3x"),
00069 ValidFormat<int>("%1.d"),
00070 ValidFormat<int>("%.d"),
00071 ValidFormat<int, double>("%d %g"),
00072 ValidFormat<int, std::string>("%*s"),
00073 ValidFormat<int, double>("%.*f"),
00074 ValidFormat<void (*)(), volatile int*>("%p %p"),
00075 ValidFormat<string_view, const char*, double, void*>(
00076 "string_view=%s const char*=%s double=%f void*=%p)"),
00077
00078 ValidFormat<int>("%% %1$d"),
00079 ValidFormat<int>("%1$ld"),
00080 ValidFormat<int>("%1$lld"),
00081 ValidFormat<std::string>("%1$s"),
00082 ValidFormat<std::string>("%1$10s"),
00083 ValidFormat<int>("%1$.10x"),
00084 ValidFormat<int>("%1$*1$.*1$d"),
00085 ValidFormat<int, int>("%1$*2$.3x"),
00086 ValidFormat<int>("%1$1.d"),
00087 ValidFormat<int>("%1$.d"),
00088 ValidFormat<double, int>("%2$d %1$g"),
00089 ValidFormat<int, std::string>("%2$*1$s"),
00090 ValidFormat<int, double>("%2$.*1$f"),
00091 ValidFormat<void*, string_view, const char*, double>(
00092 "string_view=%2$s const char*=%3$s double=%4$f void*=%1$p "
00093 "repeat=%3$s)")};
00094
00095 for (Case c : trues) {
00096 EXPECT_TRUE(c.result) << c.format;
00097 }
00098
00099 constexpr Case falses[] = {
00100 ValidFormat<int>(""),
00101
00102 ValidFormat<e>("%s"),
00103 ValidFormat<e2>("%s"),
00104 ValidFormat<>("%s"),
00105 ValidFormat<>("%r"),
00106 ValidFormat<int>("%s"),
00107 ValidFormat<int>("%.1.d"),
00108 ValidFormat<int>("%*1d"),
00109 ValidFormat<int>("%1-d"),
00110 ValidFormat<std::string, int>("%*s"),
00111 ValidFormat<int>("%*d"),
00112 ValidFormat<std::string>("%p"),
00113 ValidFormat<int (*)(int)>("%d"),
00114
00115 ValidFormat<>("%3$d"),
00116 ValidFormat<>("%1$r"),
00117 ValidFormat<int>("%1$s"),
00118 ValidFormat<int>("%1$.1.d"),
00119 ValidFormat<int>("%1$*2$1d"),
00120 ValidFormat<int>("%1$1-d"),
00121 ValidFormat<std::string, int>("%2$*1$s"),
00122 ValidFormat<std::string>("%1$p"),
00123
00124 ValidFormat<int, int>("%d %2$d"),
00125 };
00126
00127 for (Case c : falses) {
00128 EXPECT_FALSE(c.result) << c.format;
00129 }
00130 }
00131
00132 TEST(StrFormatChecker, LongFormat) {
00133 #define CHARS_X_40 "1234567890123456789012345678901234567890"
00134 #define CHARS_X_400 \
00135 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 CHARS_X_40 \
00136 CHARS_X_40 CHARS_X_40 CHARS_X_40
00137 #define CHARS_X_4000 \
00138 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400 \
00139 CHARS_X_400 CHARS_X_400 CHARS_X_400 CHARS_X_400
00140 constexpr char long_format[] =
00141 CHARS_X_4000 "%d" CHARS_X_4000 "%s" CHARS_X_4000;
00142 constexpr bool is_valid = ValidFormat<int, std::string>(long_format).result;
00143 EXPECT_TRUE(is_valid);
00144 }
00145
00146 #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
00147
00148 }
00149 }
00150 }