17 #ifndef __STDC_FORMAT_MACROS 18 #define __STDC_FORMAT_MACROS 1 27 #include <boost/regex.hpp> 33 using namespace folly;
36 TEST(StringPrintf, BasicTest) {
45 TEST(StringPrintf, NumericFormats) {
56 stringPrintf(
"%" PRId64, static_cast<int64_t>(0xffffffffffffffffLL)));
59 stringPrintf(
"%" PRId64, static_cast<uint64_t>(0xffffffffffffffffULL)));
67 TEST(StringPrintf, Appending) {
78 va_start(apOrig, fmt);
114 #ifdef HAVE_VSNPRINTF_ERRORS 125 "long string requiring reallocation 1 2 3 0x12345678",
126 "%s %s %d %d %d %#x",
128 "requiring reallocation",
136 TEST(StringPrintf, VariousSizes) {
139 for (
int i = 0;
i < 4096; ++
i) {
140 string expected(
i + 1,
'a');
141 expected =
"X" + expected +
"X";
143 EXPECT_EQ(expected.size(), result.size());
148 EXPECT_EQ(
"abc12345678910111213141516171819202122232425xyz",
150 "%d%d%d%d%d%d%d%d%d%d%dxyz",
151 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
152 17, 18, 19, 20, 21, 22, 23, 24, 25));
156 TEST(StringPrintf, oldStringPrintfTests) {
162 for (
int size = (1 << 8);
size <= (1 << 15);
size <<= 1) {
169 TEST(StringPrintf, oldStringAppendf) {
176 EXPECT_EQ(
"hello world", cEscape<std::string>(
"hello world"));
178 "hello \\\\world\\\" goodbye",
179 cEscape<std::string>(
"hello \\world\" goodbye"));
180 EXPECT_EQ(
"hello\\nworld", cEscape<std::string>(
"hello\nworld"));
181 EXPECT_EQ(
"hello\\377\\376", cEscape<std::string>(
"hello\xff\xfe"));
185 EXPECT_EQ(
"hello world", cUnescape<std::string>(
"hello world"));
187 "hello \\world\" goodbye",
188 cUnescape<std::string>(
"hello \\\\world\\\" goodbye"));
189 EXPECT_EQ(
"hello\nworld", cUnescape<std::string>(
"hello\\nworld"));
190 EXPECT_EQ(
"hello\nworld", cUnescape<std::string>(
"hello\\012world"));
191 EXPECT_EQ(
"hello\nworld", cUnescape<std::string>(
"hello\\x0aworld"));
192 EXPECT_EQ(
"hello\xff\xfe", cUnescape<std::string>(
"hello\\377\\376"));
193 EXPECT_EQ(
"hello\xff\xfe", cUnescape<std::string>(
"hello\\xff\\xfe"));
194 EXPECT_EQ(
"hello\\", cUnescape<std::string>(
"hello\\",
false));
197 cUnescape<std::string>(
"hello\\"),
198 std::invalid_argument,
199 "incomplete escape sequence");
201 cUnescape<std::string>(
"hello\\x"),
202 std::invalid_argument,
203 "incomplete hex escape sequence");
205 cUnescape<std::string>(
"hello\\q"),
206 std::invalid_argument,
207 "invalid escape sequence");
211 EXPECT_EQ(
"hello%2c%20%2fworld", uriEscape<std::string>(
"hello, /world"));
219 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~",
220 uriEscape<std::string>(
221 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~"));
225 EXPECT_EQ(
"hello, /world", uriUnescape<std::string>(
"hello, /world"));
226 EXPECT_EQ(
"hello, /world", uriUnescape<std::string>(
"hello%2c%20%2fworld"));
227 EXPECT_EQ(
"hello,+/world", uriUnescape<std::string>(
"hello%2c+%2fworld"));
231 EXPECT_EQ(
"hello/", uriUnescape<std::string>(
"hello%2f"));
232 EXPECT_EQ(
"hello/", uriUnescape<std::string>(
"hello%2F"));
233 EXPECT_THROW({ uriUnescape<std::string>(
"hello%"); }, std::invalid_argument);
234 EXPECT_THROW({ uriUnescape<std::string>(
"hello%2"); }, std::invalid_argument);
236 { uriUnescape<std::string>(
"hello%2g"); }, std::invalid_argument);
248 TEST(Escape, uriEscapeAllCombinations) {
254 for (
int i = 0;
i < 256; ++
i) {
256 for (
int j = 0; j < 256; ++j) {
261 expectPrintable(tmp);
271 (v >=
'0' && v <=
'9') || (v >=
'A' && v <=
'F') ||
272 (v >=
'a' && v <=
'f'));
276 TEST(Escape, uriUnescapePercentDecoding) {
277 char c[4] = {
'%',
'\0',
'\0',
'\0'};
280 unsigned int expected = 0;
281 for (
int i = 0;
i < 256; ++
i) {
283 for (
int j = 0; j < 256; ++j) {
285 if (isHex(
i) && isHex(j)) {
289 EXPECT_EQ(1, sscanf(c + 1,
"%x", &expected));
290 unsigned char v = out[0];
301 double pow2(
int exponent) {
302 return double(
int64_t(1) << exponent);
360 {
string(
"1.735 EiB"), 2e18, PRETTY_BYTES_IEC},
362 {
string(
"0 B "), 0, PRETTY_BYTES_IEC},
363 {
string(
"1 B "), pow2(0), PRETTY_BYTES_IEC},
364 {
string(
"1 KiB"), pow2(10), PRETTY_BYTES_IEC},
365 {
string(
"1 MiB"), pow2(20), PRETTY_BYTES_IEC},
366 {
string(
"1 GiB"), pow2(30), PRETTY_BYTES_IEC},
367 {
string(
"1 TiB"), pow2(40), PRETTY_BYTES_IEC},
368 {
string(
"1 PiB"), pow2(50), PRETTY_BYTES_IEC},
369 {
string(
"1 EiB"), pow2(60), PRETTY_BYTES_IEC},
424 {
string(
"10 Y"), 1e25, PRETTY_SI},
425 {
string(
"1 y"), 1e-24, PRETTY_SI},
426 {
string(
"10 y"), 1e-23, PRETTY_SI},
454 double recoveredX = 0;
457 }
catch (
const std::exception& ex) {
460 double relativeError =
461 fabs(x) < 1e-5 ? (x - recoveredX) : (x - recoveredX) /
x;
468 for (
double x = 1e-18;
x < 1e40;
x *= 1.9) {
470 for (
int it = 0; it < 2; ++it, addSpace =
true) {
471 double recoveredX = 0;
475 }
catch (
const std::exception& ex) {
478 double relativeError = (
x - recoveredX) /
x;
497 "00000000 61 62 63 00 02 a0 " 501 a =
"abcdefghijklmnopqrstuvwxyz";
503 "00000000 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 " 504 "|abcdefghijklmnop|\n" 505 "00000010 71 72 73 74 75 76 77 78 79 7a " 515 fbstring expected = strerror(ENOENT);
531 template <
template <
class,
class>
class VectorType>
533 VectorType<string, std::allocator<string>> parts;
582 folly::split(
',',
string(
",,a,,c,,,"), parts,
true);
589 folly::split(
',',
",,a,,c,,,", parts,
true);
593 folly::split(
',',
",,a,,c,,,", parts,
true);
614 string orig =
"ab2342asdfv~~!";
620 folly::split(
"452x;o38asfsajsdlfdf.j",
"asfds", parts,
true);
648 orig =
"All, , your base, are , , belong to us";
666 orig =
", Facebook, rul,es!, ";
680 template <
template <
class,
class>
class VectorType>
682 VectorType<StringPiece, std::allocator<StringPiece>> pieces;
683 VectorType<StringPiece, std::allocator<StringPiece>> pieces2;
706 folly::split(
',',
",,a,,c,,,", pieces,
true);
713 folly::split(
',',
",,a,,c,,,", pieces,
true);
717 folly::split(
',',
",,a,,c,,,", pieces,
true);
748 string orig =
"ab2342asdfv~~!";
754 folly::split(
"452x;o38asfsajsdlfdf.j",
"asfds", pieces,
true);
773 orig =
"All, , your base, are , , belong to us";
791 orig =
", Facebook, rul,es!, ";
805 const char* str =
"a,b";
813 std::set<StringPiece> unique;
814 folly::splitTo<StringPiece>(
816 "asd:bsd:asd:asd:bsd:csd::asd",
817 std::inserter(unique, unique.begin()),
820 if (unique.size() == 3) {
825 VectorType<fbstring, std::allocator<fbstring>> blah;
833 splitTest<std::vector>();
836 splitTest<folly::fbvector>();
839 piecesTest<std::vector>();
842 piecesTest<folly::fbvector>();
848 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c.d", a, b, c, d));
849 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b, c));
850 EXPECT_TRUE(folly::split<false>(
'.',
"a.b", a, b));
858 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b, c));
863 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b));
874 EXPECT_TRUE(folly::split<false>(
'.',
"a.b", a, b));
888 TEST(Split, std_string_fixed) {
891 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c.d", a, b, c, d));
892 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b, c));
893 EXPECT_TRUE(folly::split<false>(
'.',
"a.b", a, b));
901 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b, c));
906 EXPECT_TRUE(folly::split<false>(
'.',
"a.b.c", a, b));
917 EXPECT_TRUE(folly::split<false>(
'.',
"a.b", a, b));
942 EXPECT_TRUE(folly::split<false>(
':',
"b:14:15.3:c", a, b, c, d));
950 EXPECT_TRUE(folly::split<false>(
':',
"a:13:14.7:b", a, b, d));
969 EXPECT_TRUE(folly::split<false>(
':',
"a:13:14.7:b", a, b, std::ignore));
973 EXPECT_FALSE(folly::split<false>(
':',
"a:13", std::ignore, b, std::ignore));
974 EXPECT_TRUE(folly::split<false>(
':',
":13:", std::ignore, b, std::ignore));
988 using std::runtime_error::runtime_error;
992 return ColorError(
"Invalid my::Color representation : " + sp.
str());
1000 }
else if (in ==
"B") {
1009 TEST(Split, fixed_convert_custom) {
1022 std::vector<int>
empty = {};
1023 join(
":", empty, output);
1026 std::vector<std::string> input1 = {
"1",
"23",
"456",
""};
1027 join(
':', input1, output);
1029 output =
join(
':', input1);
1032 auto input2 = {1, 23, 456};
1033 join(
"-*-", input2, output);
1035 output =
join(
"-*-", input2);
1038 auto input3 = {
'f',
'a',
'c',
'e',
'b',
'o',
'o',
'k'};
1039 join(
"", input3, output);
1042 join(
"_", {
"",
"f",
"a",
"c",
"e",
"b",
"o",
"o",
"k",
""},
output);
1045 output =
join(
"", input3.begin(), input3.end());
1048 std::multiset<char> input4(input3);
1049 output =
join(
"", input4);
1051 output =
join(
"", input4.begin(), input4.end());
1056 string input1 =
"0123";
1070 auto bytes = folly::make_array<uint8_t>(1, 2, 3, 4);
1075 string input1 =
"30313233";
1080 fbstring input2 =
"610063ff65b667";
1092 string input3 =
"x";
1096 string input4 =
"xy";
1155 char* copyWithSameAlignment(
char* dst,
const char* src,
size_t length) {
1156 const char* originalDst = dst;
1157 size_t dstOffset = size_t(dst) & 0x7;
1158 size_t srcOffset = size_t(src) & 0x7;
1159 while (dstOffset != srcOffset) {
1164 CHECK(dst <= originalDst + 7);
1165 CHECK((
size_t(dst) & 0x7) == (
size_t(src) & 0x7));
1166 memcpy(dst, src, length);
1173 auto controlBuf = std::vector<char>(src.
size() + 7);
1175 copyWithSameAlignment(controlBuf.data(), src.
begin(), src.
size());
1177 auto testBuf = std::vector<char>(src.
size() + 7);
1178 char*
test = copyWithSameAlignment(testBuf.data(), src.
begin(), src.
size());
1180 for (
size_t i = 0;
i < src.
size();
i++) {
1181 control[
i] = tolower(control[
i]);
1184 for (
size_t i = 0;
i < src.
size();
i++) {
1191 TEST(String, toLowerAsciiAligned) {
1192 static const size_t kSize = 256;
1194 for (
size_t i = 0;
i < kSize;
i++) {
1195 input[
i] = (char)(
i & 0xff);
1200 TEST(String, toLowerAsciiUnaligned) {
1201 static const size_t kSize = 256;
1203 for (
size_t i = 0;
i < kSize;
i++) {
1204 input[
i] = (char)(
i & 0xff);
1211 for (
size_t length = 1; length < 23; length++) {
1212 for (
size_t offset = 0; offset + length <= kSize; offset++) {
1259 TEST(String, stripLeftMargin_really_empty) {
1265 TEST(String, stripLeftMargin_empty) {
1266 auto input = R
"TEXT( 1272 TEST(String, stripLeftMargin_only_whitespace) {
1274 string input = R
"TEXT( 1277 input = boost::regex_replace(input, boost::regex("~"),
"");
1279 auto expected =
"\n";
1283 TEST(String, stripLeftMargin_only_uneven_whitespace) {
1285 string input = R
"TEXT( 1289 input = boost::regex_replace(input, boost::regex("~"),
"");
1291 auto expected =
"\n\n";
1296 TEST(String, stripLeftMargin_one_line) {
1297 auto input = R
"TEXT( 1300 auto expected =
"hi there bob!\n";
1304 TEST(String, stripLeftMargin_two_lines) {
1305 auto input = R
"TEXT( 1309 auto expected =
"hi there bob!\nnice weather today!\n";
1313 TEST(String, stripLeftMargin_three_lines_uneven) {
1314 auto input = R
"TEXT( 1319 auto expected =
" hi there bob!\nnice weather today!\n so long!\n";
1323 TEST(String, stripLeftMargin_preceding_blank_lines) {
1324 auto input = R
"TEXT( 1329 auto expected =
"\n\nhi there bob!\n";
1333 TEST(String, stripLeftMargin_succeeding_blank_lines) {
1334 auto input = R
"TEXT( 1339 auto expected =
"hi there bob!\n\n\n";
1343 TEST(String, stripLeftMargin_interstitial_undented_whiteline) {
1345 string input = R
"TEXT( 1350 input = boost::regex_replace(input, boost::regex(" +~"),
"");
1351 EXPECT_EQ(
"\n hi there bob!\n\n so long!\n ", input);
1352 auto expected =
"hi there bob!\n\nso long!\n";
1356 TEST(String, stripLeftMargin_interstitial_dedented_whiteline) {
1358 string input = R
"TEXT( 1363 input = boost::regex_replace(input, boost::regex("~"),
"");
1364 EXPECT_EQ(
"\n hi there bob!\n \n so long!\n ", input);
1365 auto expected =
"hi there bob!\n\nso long!\n";
1369 TEST(String, stripLeftMargin_interstitial_equidented_whiteline) {
1371 string input = R
"TEXT( 1376 input = boost::regex_replace(input, boost::regex("~"),
"");
1377 EXPECT_EQ(
"\n hi there bob!\n \n so long!\n ", input);
1378 auto expected =
"hi there bob!\n\nso long!\n";
1382 TEST(String, stripLeftMargin_interstitial_indented_whiteline) {
1384 string input = R
"TEXT( 1389 input = boost::regex_replace(input, boost::regex("~"),
"");
1390 EXPECT_EQ(
"\n hi there bob!\n \n so long!\n ", input);
1391 auto expected =
"hi there bob!\n \nso long!\n";
1395 TEST(String, stripLeftMargin_no_pre_whitespace) {
1397 string input = R
"TEXT( hi there bob! 1401 input = boost::regex_replace(input, boost::regex("~"),
"");
1402 EXPECT_EQ(
" hi there bob!\n \n so long!\n ", input);
1403 auto expected =
"hi there bob!\n \nso long!\n";
1407 TEST(String, stripLeftMargin_no_post_whitespace) {
1409 string input = R
"TEXT( 1413 input = boost::regex_replace(input, boost::regex("~"),
"");
1414 EXPECT_EQ(
"\n hi there bob!\n \n so long! ", input);
1415 auto expected =
"hi there bob!\n \nso long! ";
#define EXPECT_LE(val1, val2)
StringPiece ltrimWhitespace(StringPiece sp)
bool unhexlify(const InputString &input, OutputString &output)
#define EXPECT_THROW(statement, expected_exception)
#define EXPECT_THROW_RE(statement, exceptionType, pattern)
void uriUnescape(StringPiece str, String &out, UriEscapeMode mode)
void vprintfError(const char *fmt,...)
#define EXPECT_EQ(val1, val2)
fbstring exceptionStr(const std::exception &e)
std::string stringVPrintf(const char *format, va_list ap)
constexpr size_type size() const
std::string stringPrintf(const char *format,...)
std::string & stringVAppendf(std::string *output, const char *format, va_list ap)
void humanify(const String1 &input, String2 &output)
FOLLY_NODISCARD std::enable_if< std::is_arithmetic< Tgt >::value, Expected< StringPiece, ConversionCode > >::type parseTo(StringPiece src, Tgt &out)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
bool prefix(Cursor &c, uint32_t expected)
#define EXPECT_GE(val1, val2)
void split(const Delim &delimiter, const String &input, std::vector< OutputType > &out, bool ignoreEmpty)
std::string prettyPrint(double val, PrettyType type, bool addSpace)
std::string stripLeftMargin(std::string s)
void vprintfCheck(const char *expected, const char *fmt,...)
constexpr auto size(C const &c) -> decltype(c.size())
constexpr auto empty(C const &c) -> decltype(c.empty())
constexpr Unexpected< typename std::decay< Error >::type > makeUnexpected(Error &&)
void uriEscape(StringPiece str, String &out, UriEscapeMode mode)
constexpr Iter data() const
void cUnescape(StringPiece str, String &out, bool strict)
StringPiece rtrimWhitespace(StringPiece sp)
void hexDump(const void *ptr, size_t size, OutIt out)
std::string & stringAppendf(std::string *output, const char *format,...)
fbstring errnoStr(int err)
double prettyToDouble(folly::StringPiece *const prettyString, const PrettyType type)
#define EXPECT_NEAR(val1, val2, abs_error)
constexpr Iter begin() const
#define EXPECT_TRUE(condition)
#define EXPECT_DOUBLE_EQ(val1, val2)
void toLowerAscii(char *str, size_t length)
PrettyTestCase prettyTestCases[]
void backslashify(folly::StringPiece input, OutputString &output, bool hex_style)
StringPiece trimWhitespace(StringPiece sp)
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
#define EXPECT_FALSE(condition)
Range< const char * > StringPiece
bool hexlify(const InputString &input, OutputString &output, bool append_output)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
void cEscape(StringPiece str, String &out)
ConversionError makeConversionError(ConversionCode code, StringPiece input)