X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Ftest%2FStringTest.cpp;h=4140d7d2904429fe80691e7b8374e4e169e2de6b;hb=a447cb9ebc32100b18c0e3fc75bf5882db4857e3;hp=e24f30285302dd9dc7735d4afac3bce8c8c75209;hpb=0606460a10e0e41f9be09552d771ea1ee327f8ee;p=folly.git diff --git a/folly/test/StringTest.cpp b/folly/test/StringTest.cpp index e24f3028..4140d7d2 100644 --- a/folly/test/StringTest.cpp +++ b/folly/test/StringTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,18 @@ * limitations under the License. */ +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include -#include -#include -#include -#include +#include -#include +#include + +#include +#include using namespace folly; using namespace std; @@ -37,12 +41,15 @@ TEST(StringPrintf, BasicTest) { TEST(StringPrintf, NumericFormats) { EXPECT_EQ("12", stringPrintf("%d", 12)); - EXPECT_EQ("5000000000", stringPrintf("%ld", 5000000000UL)); - EXPECT_EQ("5000000000", stringPrintf("%ld", 5000000000L)); - EXPECT_EQ("-5000000000", stringPrintf("%ld", -5000000000L)); + EXPECT_EQ("2000000000", stringPrintf("%ld", 2000000000UL)); + EXPECT_EQ("2000000000", stringPrintf("%ld", 2000000000L)); + EXPECT_EQ("-2000000000", stringPrintf("%ld", -2000000000L)); + EXPECT_EQ("5000000000", stringPrintf("%lld", 5000000000ULL)); + EXPECT_EQ("5000000000", stringPrintf("%lld", 5000000000LL)); + EXPECT_EQ("-5000000000", stringPrintf("%lld", -5000000000LL)); EXPECT_EQ("-1", stringPrintf("%d", 0xffffffff)); - EXPECT_EQ("-1", stringPrintf("%ld", 0xffffffffffffffff)); - EXPECT_EQ("-1", stringPrintf("%ld", 0xffffffffffffffffUL)); + EXPECT_EQ("-1", stringPrintf("%" PRId64, 0xffffffffffffffff)); + EXPECT_EQ("-1", stringPrintf("%" PRId64, 0xffffffffffffffffUL)); EXPECT_EQ("7.7", stringPrintf("%1.1f", 7.7)); EXPECT_EQ("7.7", stringPrintf("%1.1lf", 7.7)); @@ -99,8 +106,13 @@ void vprintfError(const char* fmt, ...) { va_end(ap); }; + // OSX's sprintf family does not return a negative number on a bad format + // string, but Linux does. It's unclear to me which behavior is more + // correct. +#ifdef HAVE_VSNPRINTF_ERRORS EXPECT_THROW({stringVPrintf(fmt, ap);}, std::runtime_error); +#endif } TEST(StringPrintf, VPrintf) { @@ -112,10 +124,14 @@ TEST(StringPrintf, VPrintf) { } TEST(StringPrintf, VariousSizes) { - // Test a wide variety of output sizes - for (int i = 0; i < 100; ++i) { + // Test a wide variety of output sizes, making sure to cross the + // vsnprintf buffer boundary implementation detail. + for (int i = 0; i < 4096; ++i) { string expected(i + 1, 'a'); - EXPECT_EQ("X" + expected + "X", stringPrintf("X%sX", expected.c_str())); + expected = "X" + expected + "X"; + string result = stringPrintf("%s", expected.c_str()); + EXPECT_EQ(expected.size(), result.size()); + EXPECT_EQ(expected, result); } EXPECT_EQ("abc12345678910111213141516171819202122232425xyz", @@ -146,16 +162,6 @@ TEST(StringPrintf, oldStringAppendf) { EXPECT_EQ(string("helloa/b/c/d"), s); } -BENCHMARK(new_stringPrintfSmall, iters) { - for (int64_t i = 0; i < iters; ++i) { - int32_t x = int32_t(i); - int32_t y = int32_t(i + 1); - string s = - stringPrintf("msg msg msg msg msg msg msg msg: %d, %d, %s", - x, y, "hello"); - } -} - TEST(Escape, cEscape) { EXPECT_EQ("hello world", cEscape("hello world")); EXPECT_EQ("hello \\\\world\\\" goodbye", @@ -188,6 +194,11 @@ TEST(Escape, uriEscape) { UriEscapeMode::PATH)); EXPECT_EQ("hello%2c+%2fworld", uriEscape("hello, /world", UriEscapeMode::QUERY)); + EXPECT_EQ( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~", + uriEscape( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~") + ); } TEST(Escape, uriUnescape) { @@ -213,7 +224,7 @@ void expectPrintable(StringPiece s) { EXPECT_GE(127, c); } } -} // namespace +} // namespace TEST(Escape, uriEscapeAllCombinations) { char c[3]; @@ -241,7 +252,7 @@ bool isHex(int v) { (v >= 'A' && v <= 'F') || (v >= 'a' && v <= 'f')); } -} // namespace +} // namespace TEST(Escape, uriUnescapePercentDecoding) { char c[4] = {'%', '\0', '\0', '\0'}; @@ -266,103 +277,13 @@ TEST(Escape, uriUnescapePercentDecoding) { } } -namespace { -fbstring cbmString; -fbstring cbmEscapedString; -fbstring cEscapedString; -fbstring cUnescapedString; -const size_t kCBmStringLength = 64 << 10; -const uint32_t kCPrintablePercentage = 90; - -fbstring uribmString; -fbstring uribmEscapedString; -fbstring uriEscapedString; -fbstring uriUnescapedString; -const size_t kURIBmStringLength = 256; -const uint32_t kURIPassThroughPercentage = 50; - -void initBenchmark() { - std::mt19937 rnd; - - // C escape - std::uniform_int_distribution printable(32, 126); - std::uniform_int_distribution nonPrintable(0, 160); - std::uniform_int_distribution percentage(0, 99); - - cbmString.reserve(kCBmStringLength); - for (size_t i = 0; i < kCBmStringLength; ++i) { - unsigned char c; - if (percentage(rnd) < kCPrintablePercentage) { - c = printable(rnd); - } else { - c = nonPrintable(rnd); - // Generate characters in both non-printable ranges: - // 0..31 and 127..255 - if (c >= 32) { - c += (126 - 32) + 1; - } - } - cbmString.push_back(c); - } - - cbmEscapedString = cEscape(cbmString); - - // URI escape - std::uniform_int_distribution passthrough('a', 'z'); - std::string encodeChars = " ?!\"',+[]"; - std::uniform_int_distribution encode(0, encodeChars.size() - 1); - - uribmString.reserve(kURIBmStringLength); - for (size_t i = 0; i < kURIBmStringLength; ++i) { - unsigned char c; - if (percentage(rnd) < kURIPassThroughPercentage) { - c = passthrough(rnd); - } else { - c = encodeChars[encode(rnd)]; - } - uribmString.push_back(c); - } - - uribmEscapedString = uriEscape(uribmString); -} - -BENCHMARK(BM_cEscape, iters) { - while (iters--) { - cEscapedString = cEscape(cbmString); - doNotOptimizeAway(cEscapedString.size()); - } -} - -BENCHMARK(BM_cUnescape, iters) { - while (iters--) { - cUnescapedString = cUnescape(cbmEscapedString); - doNotOptimizeAway(cUnescapedString.size()); - } -} - -BENCHMARK(BM_uriEscape, iters) { - while (iters--) { - uriEscapedString = uriEscape(uribmString); - doNotOptimizeAway(uriEscapedString.size()); - } -} - -BENCHMARK(BM_uriUnescape, iters) { - while (iters--) { - uriUnescapedString = uriUnescape(uribmEscapedString); - doNotOptimizeAway(uriUnescapedString.size()); - } -} - -} // namespace - namespace { double pow2(int exponent) { return double(int64_t(1) << exponent); } -} // namespace +} // namespace struct PrettyTestCase{ std::string prettyString; double realValue; @@ -495,11 +416,11 @@ TEST(PrettyToDouble, Basic) { PrettyType formatType = testCase.prettyType; double x = testCase.realValue; std::string testString = testCase.prettyString; - double recoveredX; + double recoveredX = 0; try{ recoveredX = prettyToDouble(testString, formatType); - } catch (std::range_error &ex){ - EXPECT_TRUE(false); + } catch (const std::range_error& ex) { + ADD_FAILURE() << testCase.prettyString << " -> " << ex.what(); } double relativeError = fabs(x) < 1e-5 ? (x-recoveredX) : (x - recoveredX) / x; @@ -512,12 +433,12 @@ TEST(PrettyToDouble, Basic) { for (double x = 1e-18; x < 1e40; x *= 1.9){ bool addSpace = static_cast (i) == PRETTY_SI; for (int it = 0; it < 2; ++it, addSpace = true){ - double recoveredX; + double recoveredX = 0; try{ recoveredX = prettyToDouble(prettyPrint(x, formatType, addSpace), formatType); - } catch (std::range_error &ex){ - EXPECT_TRUE(false); + } catch (std::range_error&) { + ADD_FAILURE(); } double relativeError = (x - recoveredX) / x; EXPECT_NEAR(0, relativeError, 1e-3); @@ -570,36 +491,9 @@ TEST(System, errnoStr) { EXPECT_EQ(EACCES, errno); } -namespace folly_test { -struct ThisIsAVeryLongStructureName { -}; -} // namespace folly_test - -#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK -TEST(System, demangle) { - char expected[] = "folly_test::ThisIsAVeryLongStructureName"; - EXPECT_STREQ( - expected, - demangle(typeid(folly_test::ThisIsAVeryLongStructureName)).c_str()); - - { - char buf[sizeof(expected)]; - EXPECT_EQ(sizeof(expected) - 1, - demangle(typeid(folly_test::ThisIsAVeryLongStructureName), - buf, sizeof(buf))); - EXPECT_STREQ(expected, buf); - - EXPECT_EQ(sizeof(expected) - 1, - demangle(typeid(folly_test::ThisIsAVeryLongStructureName), - buf, 11)); - EXPECT_STREQ("folly_test", buf); - } -} -#endif - namespace { -template class VectorType> +template