X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Ftest%2FStringTest.cpp;h=31c6e4ad91d8b7f6433c5424ff29bb25bcbb5303;hb=fa172175980b13569ba42008202a857af6e959dd;hp=4b6523e859b34827e684ed6603315ea8a458fa14;hpb=c72f7f6887de816d9f2bda14c0c460e3d2386c47;p=folly.git diff --git a/folly/test/StringTest.cpp b/folly/test/StringTest.cpp index 4b6523e8..31c6e4ad 100644 --- a/folly/test/StringTest.cpp +++ b/folly/test/StringTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 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,10 +14,18 @@ * limitations under the License. */ +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include +#include + #include -#include + +#include +#include using namespace folly; using namespace std; @@ -33,15 +41,15 @@ TEST(StringPrintf, BasicTest) { TEST(StringPrintf, NumericFormats) { EXPECT_EQ("12", stringPrintf("%d", 12)); - EXPECT_EQ("2000000000", stringPrintf("%ld", 2000000000ULL)); + 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)); @@ -411,8 +419,8 @@ TEST(PrettyToDouble, Basic) { double recoveredX = 0; try{ recoveredX = prettyToDouble(testString, formatType); - } catch (std::range_error &ex){ - EXPECT_TRUE(false); + } catch (const std::range_error& ex) { + EXPECT_TRUE(false) << testCase.prettyString << " -> " << ex.what(); } double relativeError = fabs(x) < 1e-5 ? (x-recoveredX) : (x - recoveredX) / x; @@ -429,7 +437,7 @@ TEST(PrettyToDouble, Basic) { try{ recoveredX = prettyToDouble(prettyPrint(x, formatType, addSpace), formatType); - } catch (std::range_error &ex){ + } catch (std::range_error&) { EXPECT_TRUE(false); } double relativeError = (x - recoveredX) / x; @@ -906,8 +914,51 @@ TEST(Split, fixed_convert) { EXPECT_EQ(13, b); EXPECT_EQ("14.7:b", d); - EXPECT_THROW(folly::split(':', "a:13:14.7:b", a, b, c), - std::range_error); + + // Enable verifying that a line only contains one field + EXPECT_TRUE(folly::split(' ', "hello", a)); + EXPECT_FALSE(folly::split(' ', "hello world", a)); +} + +namespace my { + +enum class Color { + Red, + Blue, +}; + +enum class ColorErrorCode { INVALID_COLOR }; + +struct ColorError : std::runtime_error { + using std::runtime_error::runtime_error; +}; + +ColorError makeConversionError(ColorErrorCode, StringPiece sp) { + return ColorError("Invalid my::Color representation : " + sp.str()); +} + +Expected parseTo( + StringPiece in, + Color& out) noexcept { + if (in == "R") { + out = Color::Red; + } else if (in == "B") { + out = Color::Blue; + } else { + return makeUnexpected(ColorErrorCode::INVALID_COLOR); + } + return StringPiece(in.end(), in.end()); +} +} + +TEST(Split, fixed_convert_custom) { + my::Color c1, c2; + + EXPECT_TRUE(folly::split(',', "R,B", c1, c2)); + EXPECT_EQ(c1, my::Color::Red); + EXPECT_EQ(c2, my::Color::Blue); + + EXPECT_THROW(folly::split(',', "B,G", c1, c2), my::ColorError); } TEST(String, join) { @@ -944,7 +995,7 @@ TEST(String, hexlify) { string input1 = "0123"; string output1; EXPECT_TRUE(hexlify(input1, output1)); - EXPECT_EQ(output1, "30313233"); + EXPECT_EQ("30313233", output1); fbstring input2 = "abcdefg"; input2[1] = 0; @@ -952,7 +1003,11 @@ TEST(String, hexlify) { input2[5] = 0xb6; fbstring output2; EXPECT_TRUE(hexlify(input2, output2)); - EXPECT_EQ(output2, "610063ff65b667"); + EXPECT_EQ("610063ff65b667", output2); + + EXPECT_EQ("666f6f626172", hexlify("foobar")); + auto bytes = folly::make_array(1, 2, 3, 4); + EXPECT_EQ("01020304", hexlify(ByteRange{bytes.data(), bytes.size()})); } TEST(String, unhexlify) { @@ -980,6 +1035,10 @@ TEST(String, unhexlify) { string input4 = "xy"; string output4; EXPECT_FALSE(unhexlify(input4, output4)); + + EXPECT_EQ("foobar", unhexlify("666f6f626172")); + EXPECT_EQ(StringPiece("foo\0bar", 7), unhexlify("666f6f00626172")); + EXPECT_THROW(unhexlify("666f6fzz626172"), std::domain_error); } TEST(String, backslashify) { @@ -1044,11 +1103,12 @@ char* copyWithSameAlignment(char* dst, const char* src, size_t length) { void testToLowerAscii(Range src) { // Allocate extra space so we can make copies that start at the // same alignment (byte, word, quadword, etc) as the source buffer. - char controlBuf[src.size() + 7]; - char* control = copyWithSameAlignment(controlBuf, src.begin(), src.size()); + auto controlBuf = std::vector(src.size() + 7); + char* control = + copyWithSameAlignment(controlBuf.data(), src.begin(), src.size()); - char testBuf[src.size() + 7]; - char* test = copyWithSameAlignment(testBuf, src.begin(), src.size()); + auto testBuf = std::vector(src.size() + 7); + char* test = copyWithSameAlignment(testBuf.data(), src.begin(), src.size()); for (size_t i = 0; i < src.size(); i++) { control[i] = tolower(control[i]); @@ -1295,7 +1355,7 @@ TEST(String, stripLeftMargin_no_post_whitespace) { EXPECT_EQ(expected, stripLeftMargin(input)); } -const folly::StringPiece kTestUTF8 = "This is \U0001F602 stuff!"; +const folly::StringPiece kTestUTF8 = u8"This is \U0001F602 stuff!"; TEST(UTF8StringPiece, valid_utf8) { folly::StringPiece sp = kTestUTF8; @@ -1317,3 +1377,11 @@ TEST(UTF8StringPiece, empty_mid_codepoint) { TEST(UTF8StringPiece, invalid_mid_codepoint) { EXPECT_THROW(UTF8StringPiece(kTestUTF8.subpiece(9, 1)), std::out_of_range); } + +TEST(UTF8StringPiece, valid_implicit_conversion) { + std::string input = u8"\U0001F602\U0001F602\U0001F602"; + auto checkImplicitCtor = [](UTF8StringPiece implicitCtor) { + return implicitCtor.walk_size(); + }; + EXPECT_EQ(3, checkImplicitCtor(input)); +}