X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Ftest%2FStringTest.cpp;h=4140d7d2904429fe80691e7b8374e4e169e2de6b;hb=95d9935053bd95825ecd84fd647d697df1113daf;hp=df5c689121e7120dacd93e330442de0f4608b27f;hpb=f3f96c69481d5dd078e3563b13bf05903dba6517;p=folly.git diff --git a/folly/test/StringTest.cpp b/folly/test/StringTest.cpp index df5c6891..4140d7d2 100644 --- a/folly/test/StringTest.cpp +++ b/folly/test/StringTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012 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,13 +14,18 @@ * limitations under the License. */ -#include "folly/String.h" +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif -#include -#include -#include +#include -#include "folly/Benchmark.h" +#include + +#include + +#include +#include using namespace folly; using namespace std; @@ -36,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)); @@ -60,11 +68,70 @@ TEST(StringPrintf, Appending) { EXPECT_EQ(s, "abc 123"); } +void vprintfCheck(const char* expected, const char* fmt, ...) { + va_list apOrig; + va_start(apOrig, fmt); + SCOPE_EXIT { + va_end(apOrig); + }; + va_list ap; + va_copy(ap, apOrig); + SCOPE_EXIT { + va_end(ap); + }; + + // Check both APIs for calling stringVPrintf() + EXPECT_EQ(expected, stringVPrintf(fmt, ap)); + va_end(ap); + va_copy(ap, apOrig); + + std::string out; + stringVPrintf(&out, fmt, ap); + va_end(ap); + va_copy(ap, apOrig); + EXPECT_EQ(expected, out); + + // Check stringVAppendf() as well + std::string prefix = "foobar"; + out = prefix; + EXPECT_EQ(prefix + expected, stringVAppendf(&out, fmt, ap)); + va_end(ap); + va_copy(ap, apOrig); +} + +void vprintfError(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + SCOPE_EXIT { + 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) { + vprintfCheck("foo", "%s", "foo"); + vprintfCheck("long string requiring reallocation 1 2 3 0x12345678", + "%s %s %d %d %d %#x", + "long string", "requiring reallocation", 1, 2, 3, 0x12345678); + vprintfError("bogus%", "foo"); +} + 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", @@ -95,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", @@ -131,55 +188,94 @@ TEST(Escape, cUnescape) { std::invalid_argument); } -namespace { -fbstring bmString; -fbstring bmEscapedString; -fbstring escapedString; -fbstring unescapedString; -const size_t kBmStringLength = 64 << 10; -const uint32_t kPrintablePercentage = 90; - -void initBenchmark() { - bmString.reserve(kBmStringLength); - - std::mt19937 rnd; - std::uniform_int_distribution printable(32, 126); - std::uniform_int_distribution nonPrintable(0, 160); - std::uniform_int_distribution percentage(0, 99); - - for (size_t i = 0; i < kBmStringLength; ++i) { - unsigned char c; - if (percentage(rnd) < kPrintablePercentage) { - 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; - } - } - bmString.push_back(c); - } +TEST(Escape, uriEscape) { + EXPECT_EQ("hello%2c%20%2fworld", uriEscape("hello, /world")); + EXPECT_EQ("hello%2c%20/world", uriEscape("hello, /world", + UriEscapeMode::PATH)); + EXPECT_EQ("hello%2c+%2fworld", uriEscape("hello, /world", + UriEscapeMode::QUERY)); + EXPECT_EQ( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~", + uriEscape( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~") + ); +} - bmEscapedString = cEscape(bmString); +TEST(Escape, uriUnescape) { + EXPECT_EQ("hello, /world", uriUnescape("hello, /world")); + EXPECT_EQ("hello, /world", uriUnescape("hello%2c%20%2fworld")); + EXPECT_EQ("hello,+/world", uriUnescape("hello%2c+%2fworld")); + EXPECT_EQ("hello, /world", uriUnescape("hello%2c+%2fworld", + UriEscapeMode::QUERY)); + EXPECT_EQ("hello/", uriUnescape("hello%2f")); + EXPECT_EQ("hello/", uriUnescape("hello%2F")); + EXPECT_THROW({uriUnescape("hello%");}, + std::invalid_argument); + EXPECT_THROW({uriUnescape("hello%2");}, + std::invalid_argument); + EXPECT_THROW({uriUnescape("hello%2g");}, + std::invalid_argument); } -BENCHMARK(BM_cEscape, iters) { - while (iters--) { - escapedString = cEscape(bmString); - doNotOptimizeAway(escapedString.size()); +namespace { +void expectPrintable(StringPiece s) { + for (char c : s) { + EXPECT_LE(32, c); + EXPECT_GE(127, c); } } - -BENCHMARK(BM_cUnescape, iters) { - while (iters--) { - unescapedString = cUnescape(bmEscapedString); - doNotOptimizeAway(unescapedString.size()); +} // namespace + +TEST(Escape, uriEscapeAllCombinations) { + char c[3]; + c[2] = '\0'; + StringPiece in(c, 2); + fbstring tmp; + fbstring out; + for (int i = 0; i < 256; ++i) { + c[0] = i; + for (int j = 0; j < 256; ++j) { + c[1] = j; + tmp.clear(); + out.clear(); + uriEscape(in, tmp); + expectPrintable(tmp); + uriUnescape(tmp, out); + EXPECT_EQ(in, out); + } } } -} // namespace +namespace { +bool isHex(int v) { + return ((v >= '0' && v <= '9') || + (v >= 'A' && v <= 'F') || + (v >= 'a' && v <= 'f')); +} +} // namespace + +TEST(Escape, uriUnescapePercentDecoding) { + char c[4] = {'%', '\0', '\0', '\0'}; + StringPiece in(c, 3); + fbstring out; + unsigned int expected = 0; + for (int i = 0; i < 256; ++i) { + c[1] = i; + for (int j = 0; j < 256; ++j) { + c[2] = j; + if (isHex(i) && isHex(j)) { + out.clear(); + uriUnescape(in, out); + EXPECT_EQ(1, out.size()); + EXPECT_EQ(1, sscanf(c + 1, "%x", &expected)); + unsigned char v = out[0]; + EXPECT_EQ(expected, v); + } else { + EXPECT_THROW({uriUnescape(in, out);}, std::invalid_argument); + } + } + } +} namespace { @@ -187,116 +283,177 @@ double pow2(int exponent) { return double(int64_t(1) << exponent); } -} // namespace +} // namespace +struct PrettyTestCase{ + std::string prettyString; + double realValue; + PrettyType prettyType; +}; -TEST(PrettyPrint, Basic) { - // check time printing - EXPECT_EQ(string("8.53e+07 s "), prettyPrint(85.3e6, PRETTY_TIME)); - EXPECT_EQ(string("85.3 s "), prettyPrint(85.3, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ms"), prettyPrint(85.3e-3, PRETTY_TIME)); - EXPECT_EQ(string("85.3 us"), prettyPrint(85.3e-6, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ns"), prettyPrint(85.3e-9, PRETTY_TIME)); - EXPECT_EQ(string("85.3 ps"), prettyPrint(85.3e-12, PRETTY_TIME)); - EXPECT_EQ(string("8.53e-14 s "), prettyPrint(85.3e-15, PRETTY_TIME)); - - EXPECT_EQ(string("0 s "), prettyPrint(0, PRETTY_TIME)); - EXPECT_EQ(string("1 s "), prettyPrint(1.0, PRETTY_TIME)); - EXPECT_EQ(string("1 ms"), prettyPrint(1.0e-3, PRETTY_TIME)); - EXPECT_EQ(string("1 us"), prettyPrint(1.0e-6, PRETTY_TIME)); - EXPECT_EQ(string("1 ns"), prettyPrint(1.0e-9, PRETTY_TIME)); - EXPECT_EQ(string("1 ps"), prettyPrint(1.0e-12, PRETTY_TIME)); +PrettyTestCase prettyTestCases[] = +{ + {string("8.53e+07 s "), 85.3e6, PRETTY_TIME}, + {string("8.53e+07 s "), 85.3e6, PRETTY_TIME}, + {string("85.3 ms"), 85.3e-3, PRETTY_TIME}, + {string("85.3 us"), 85.3e-6, PRETTY_TIME}, + {string("85.3 ns"), 85.3e-9, PRETTY_TIME}, + {string("85.3 ps"), 85.3e-12, PRETTY_TIME}, + {string("8.53e-14 s "), 85.3e-15, PRETTY_TIME}, + + {string("0 s "), 0, PRETTY_TIME}, + {string("1 s "), 1.0, PRETTY_TIME}, + {string("1 ms"), 1.0e-3, PRETTY_TIME}, + {string("1 us"), 1.0e-6, PRETTY_TIME}, + {string("1 ns"), 1.0e-9, PRETTY_TIME}, + {string("1 ps"), 1.0e-12, PRETTY_TIME}, // check bytes printing - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES)); - EXPECT_EQ(string("833 kB"), prettyPrint(853.e3, PRETTY_BYTES)); - EXPECT_EQ(string("813.5 MB"), prettyPrint(853.e6, PRETTY_BYTES)); - EXPECT_EQ(string("7.944 GB"), prettyPrint(8.53e9, PRETTY_BYTES)); - EXPECT_EQ(string("794.4 GB"), prettyPrint(853.e9, PRETTY_BYTES)); - EXPECT_EQ(string("775.8 TB"), prettyPrint(853.e12, PRETTY_BYTES)); - - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES)); - EXPECT_EQ(string("1 B "), prettyPrint(pow2(0), PRETTY_BYTES)); - EXPECT_EQ(string("1 kB"), prettyPrint(pow2(10), PRETTY_BYTES)); - EXPECT_EQ(string("1 MB"), prettyPrint(pow2(20), PRETTY_BYTES)); - EXPECT_EQ(string("1 GB"), prettyPrint(pow2(30), PRETTY_BYTES)); - EXPECT_EQ(string("1 TB"), prettyPrint(pow2(40), PRETTY_BYTES)); - - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES_IEC)); - EXPECT_EQ(string("833 KiB"), prettyPrint(853.e3, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("813.5 MiB"), prettyPrint(853.e6, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("7.944 GiB"), prettyPrint(8.53e9, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("794.4 GiB"), prettyPrint(853.e9, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("775.8 TiB"), prettyPrint(853.e12, PRETTY_BYTES_IEC)); - - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 B "), prettyPrint(pow2(0), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 KiB"), prettyPrint(pow2(10), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 MiB"), prettyPrint(pow2(20), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 GiB"), prettyPrint(pow2(30), PRETTY_BYTES_IEC)); - EXPECT_EQ(string("1 TiB"), prettyPrint(pow2(40), PRETTY_BYTES_IEC)); + {string("853 B "), 853., PRETTY_BYTES}, + {string("833 kB"), 853.e3, PRETTY_BYTES}, + {string("813.5 MB"), 853.e6, PRETTY_BYTES}, + {string("7.944 GB"), 8.53e9, PRETTY_BYTES}, + {string("794.4 GB"), 853.e9, PRETTY_BYTES}, + {string("775.8 TB"), 853.e12, PRETTY_BYTES}, + + {string("0 B "), 0, PRETTY_BYTES}, + {string("1 B "), pow2(0), PRETTY_BYTES}, + {string("1 kB"), pow2(10), PRETTY_BYTES}, + {string("1 MB"), pow2(20), PRETTY_BYTES}, + {string("1 GB"), pow2(30), PRETTY_BYTES}, + {string("1 TB"), pow2(40), PRETTY_BYTES}, + + {string("853 B "), 853., PRETTY_BYTES_IEC}, + {string("833 KiB"), 853.e3, PRETTY_BYTES_IEC}, + {string("813.5 MiB"), 853.e6, PRETTY_BYTES_IEC}, + {string("7.944 GiB"), 8.53e9, PRETTY_BYTES_IEC}, + {string("794.4 GiB"), 853.e9, PRETTY_BYTES_IEC}, + {string("775.8 TiB"), 853.e12, PRETTY_BYTES_IEC}, + + {string("0 B "), 0, PRETTY_BYTES_IEC}, + {string("1 B "), pow2(0), PRETTY_BYTES_IEC}, + {string("1 KiB"), pow2(10), PRETTY_BYTES_IEC}, + {string("1 MiB"), pow2(20), PRETTY_BYTES_IEC}, + {string("1 GiB"), pow2(30), PRETTY_BYTES_IEC}, + {string("1 TiB"), pow2(40), PRETTY_BYTES_IEC}, // check bytes metric printing - EXPECT_EQ(string("853 B "), prettyPrint(853., PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 kB"), prettyPrint(853.e3, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 MB"), prettyPrint(853.e6, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("8.53 GB"), prettyPrint(8.53e9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 GB"), prettyPrint(853.e9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("853 TB"), prettyPrint(853.e12, PRETTY_BYTES_METRIC)); + {string("853 B "), 853., PRETTY_BYTES_METRIC}, + {string("853 kB"), 853.e3, PRETTY_BYTES_METRIC}, + {string("853 MB"), 853.e6, PRETTY_BYTES_METRIC}, + {string("8.53 GB"), 8.53e9, PRETTY_BYTES_METRIC}, + {string("853 GB"), 853.e9, PRETTY_BYTES_METRIC}, + {string("853 TB"), 853.e12, PRETTY_BYTES_METRIC}, - EXPECT_EQ(string("0 B "), prettyPrint(0, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 B "), prettyPrint(1.0, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 kB"), prettyPrint(1.0e+3, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 MB"), prettyPrint(1.0e+6, PRETTY_BYTES_METRIC)); + {string("0 B "), 0, PRETTY_BYTES_METRIC}, + {string("1 B "), 1.0, PRETTY_BYTES_METRIC}, + {string("1 kB"), 1.0e+3, PRETTY_BYTES_METRIC}, + {string("1 MB"), 1.0e+6, PRETTY_BYTES_METRIC}, - EXPECT_EQ(string("1 GB"), prettyPrint(1.0e+9, PRETTY_BYTES_METRIC)); - EXPECT_EQ(string("1 TB"), prettyPrint(1.0e+12, PRETTY_BYTES_METRIC)); + {string("1 GB"), 1.0e+9, PRETTY_BYTES_METRIC}, + {string("1 TB"), 1.0e+12, PRETTY_BYTES_METRIC}, // check metric-units (powers of 1000) printing - EXPECT_EQ(string("853 "), prettyPrint(853., PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 k"), prettyPrint(853.e3, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 M"), prettyPrint(853.e6, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("8.53 bil"), prettyPrint(8.53e9, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 bil"), prettyPrint(853.e9, PRETTY_UNITS_METRIC)); - EXPECT_EQ(string("853 tril"), prettyPrint(853.e12, PRETTY_UNITS_METRIC)); + {string("853 "), 853., PRETTY_UNITS_METRIC}, + {string("853 k"), 853.e3, PRETTY_UNITS_METRIC}, + {string("853 M"), 853.e6, PRETTY_UNITS_METRIC}, + {string("8.53 bil"), 8.53e9, PRETTY_UNITS_METRIC}, + {string("853 bil"), 853.e9, PRETTY_UNITS_METRIC}, + {string("853 tril"), 853.e12, PRETTY_UNITS_METRIC}, // check binary-units (powers of 1024) printing - EXPECT_EQ(string("0 "), prettyPrint(0, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 "), prettyPrint(pow2(0), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 k"), prettyPrint(pow2(10), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 M"), prettyPrint(pow2(20), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 G"), prettyPrint(pow2(30), PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1 T"), prettyPrint(pow2(40), PRETTY_UNITS_BINARY)); - - EXPECT_EQ(string("1023 "), - prettyPrint(pow2(10) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 k"), - prettyPrint(pow2(20) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 M"), - prettyPrint(pow2(30) - 1, PRETTY_UNITS_BINARY)); - EXPECT_EQ(string("1024 G"), - prettyPrint(pow2(40) - 1, PRETTY_UNITS_BINARY)); - - EXPECT_EQ(string("0 "), prettyPrint(0, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 "), prettyPrint(pow2(0), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Ki"), prettyPrint(pow2(10), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Mi"), prettyPrint(pow2(20), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Gi"), prettyPrint(pow2(30), PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1 Ti"), prettyPrint(pow2(40), PRETTY_UNITS_BINARY_IEC)); - - EXPECT_EQ(string("1023 "), - prettyPrint(pow2(10) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Ki"), - prettyPrint(pow2(20) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Mi"), - prettyPrint(pow2(30) - 1, PRETTY_UNITS_BINARY_IEC)); - EXPECT_EQ(string("1024 Gi"), - prettyPrint(pow2(40) - 1, PRETTY_UNITS_BINARY_IEC)); + {string("0 "), 0, PRETTY_UNITS_BINARY}, + {string("1 "), pow2(0), PRETTY_UNITS_BINARY}, + {string("1 k"), pow2(10), PRETTY_UNITS_BINARY}, + {string("1 M"), pow2(20), PRETTY_UNITS_BINARY}, + {string("1 G"), pow2(30), PRETTY_UNITS_BINARY}, + {string("1 T"), pow2(40), PRETTY_UNITS_BINARY}, + + {string("1023 "), pow2(10) - 1, PRETTY_UNITS_BINARY}, + {string("1024 k"), pow2(20) - 1, PRETTY_UNITS_BINARY}, + {string("1024 M"), pow2(30) - 1, PRETTY_UNITS_BINARY}, + {string("1024 G"), pow2(40) - 1, PRETTY_UNITS_BINARY}, + + {string("0 "), 0, PRETTY_UNITS_BINARY_IEC}, + {string("1 "), pow2(0), PRETTY_UNITS_BINARY_IEC}, + {string("1 Ki"), pow2(10), PRETTY_UNITS_BINARY_IEC}, + {string("1 Mi"), pow2(20), PRETTY_UNITS_BINARY_IEC}, + {string("1 Gi"), pow2(30), PRETTY_UNITS_BINARY_IEC}, + {string("1 Ti"), pow2(40), PRETTY_UNITS_BINARY_IEC}, + + {string("1023 "), pow2(10) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Ki"), pow2(20) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Mi"), pow2(30) - 1, PRETTY_UNITS_BINARY_IEC}, + {string("1024 Gi"), pow2(40) - 1, PRETTY_UNITS_BINARY_IEC}, + + //check border SI cases + + {string("1 Y"), 1e24, PRETTY_SI}, + {string("10 Y"), 1e25, PRETTY_SI}, + {string("1 y"), 1e-24, PRETTY_SI}, + {string("10 y"), 1e-23, PRETTY_SI}, // check that negative values work - EXPECT_EQ(string("-85.3 s "), prettyPrint(-85.3, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 ms"), prettyPrint(-85.3e-3, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 us"), prettyPrint(-85.3e-6, PRETTY_TIME)); - EXPECT_EQ(string("-85.3 ns"), prettyPrint(-85.3e-9, PRETTY_TIME)); + {string("-85.3 s "), -85.3, PRETTY_TIME}, + {string("-85.3 ms"), -85.3e-3, PRETTY_TIME}, + {string("-85.3 us"), -85.3e-6, PRETTY_TIME}, + {string("-85.3 ns"), -85.3e-9, PRETTY_TIME}, + // end of test + {string("endoftest"), 0, PRETTY_NUM_TYPES} +}; + +TEST(PrettyPrint, Basic) { + for (int i = 0; prettyTestCases[i].prettyType != PRETTY_NUM_TYPES; ++i){ + const PrettyTestCase& prettyTest = prettyTestCases[i]; + EXPECT_EQ(prettyTest.prettyString, + prettyPrint(prettyTest.realValue, prettyTest.prettyType)); + } +} + +TEST(PrettyToDouble, Basic) { + // check manually created tests + for (int i = 0; prettyTestCases[i].prettyType != PRETTY_NUM_TYPES; ++i){ + PrettyTestCase testCase = prettyTestCases[i]; + PrettyType formatType = testCase.prettyType; + double x = testCase.realValue; + std::string testString = testCase.prettyString; + double recoveredX = 0; + try{ + recoveredX = prettyToDouble(testString, formatType); + } catch (const std::range_error& ex) { + ADD_FAILURE() << testCase.prettyString << " -> " << ex.what(); + } + double relativeError = fabs(x) < 1e-5 ? (x-recoveredX) : + (x - recoveredX) / x; + EXPECT_NEAR(0, relativeError, 1e-3); + } + + // checks for compatibility with prettyPrint over the whole parameter space + for (int i = 0 ; i < PRETTY_NUM_TYPES; ++i){ + PrettyType formatType = static_cast(i); + 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 = 0; + try{ + recoveredX = prettyToDouble(prettyPrint(x, formatType, addSpace), + formatType); + } catch (std::range_error&) { + ADD_FAILURE(); + } + double relativeError = (x - recoveredX) / x; + EXPECT_NEAR(0, relativeError, 1e-3); + } + } + } + + // check for incorrect values + EXPECT_THROW(prettyToDouble("10Mx", PRETTY_SI), std::range_error); + EXPECT_THROW(prettyToDouble("10 Mx", PRETTY_SI), std::range_error); + EXPECT_THROW(prettyToDouble("10 M x", PRETTY_SI), std::range_error); + + StringPiece testString = "10Mx"; + EXPECT_DOUBLE_EQ(prettyToDouble(&testString, PRETTY_UNITS_METRIC), 10e6); + EXPECT_EQ(testString, "x"); } TEST(PrettyPrint, HexDump) { @@ -334,19 +491,9 @@ TEST(System, errnoStr) { EXPECT_EQ(EACCES, errno); } -namespace folly_test { -struct ThisIsAVeryLongStructureName { -}; -} // namespace folly_test - -TEST(System, demangle) { - EXPECT_EQ("folly_test::ThisIsAVeryLongStructureName", - demangle(typeid(folly_test::ThisIsAVeryLongStructureName))); -} - namespace { -template class VectorType> +template