/*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2011-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <boost/lexical_cast.hpp>
#include <folly/Conv.h>
-#include <folly/Foreach.h>
+#include <folly/container/Foreach.h>
#include <folly/portability/GTest.h>
#include <algorithm>
EXPECT_TRUE(shouldWork == std::numeric_limits<float>::min() ||
shouldWork == 0.f);
} catch (...) {
- EXPECT_TRUE(false);
+ ADD_FAILURE();
}
}
// Test NaN conversion
try {
to<double>("not a number");
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (const std::range_error &) {
}
+ EXPECT_TRUE(std::isnan(to<double>("nan")));
EXPECT_TRUE(std::isnan(to<double>("NaN")));
+ EXPECT_TRUE(std::isnan(to<double>("NAN")));
+ EXPECT_TRUE(std::isnan(to<double>("-nan")));
+ EXPECT_TRUE(std::isnan(to<double>("-NaN")));
+ EXPECT_TRUE(std::isnan(to<double>("-NAN")));
+
EXPECT_EQ(to<double>("inf"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("Inf"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("INF"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("inF"), numeric_limits<double>::infinity());
EXPECT_EQ(to<double>("infinity"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("Infinity"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("INFINITY"), numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("iNfInItY"), numeric_limits<double>::infinity());
EXPECT_THROW(to<double>("infinitX"), std::range_error);
EXPECT_EQ(to<double>("-inf"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-Inf"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-INF"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-inF"), -numeric_limits<double>::infinity());
EXPECT_EQ(to<double>("-infinity"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-Infinity"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-INFINITY"), -numeric_limits<double>::infinity());
+ EXPECT_EQ(to<double>("-iNfInItY"), -numeric_limits<double>::infinity());
EXPECT_THROW(to<double>("-infinitX"), std::range_error);
}
try {
to<int>(pc);
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (const std::range_error &) {
}
}
try {
to<int64_t>(&pc);
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (const std::range_error &) {
}
}
try {
to<double>(pc);
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (const std::range_error &) {
}
}
/* This seems not work in ubuntu11.10, gcc 4.6.1
try {
auto f = to<float>(957837589847);
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (std::range_error& e) {
//LOG(INFO) << e.what();
}
try {
auto i2 = to<int>(42.1);
LOG(ERROR) << "to<int> returned " << i2 << " instead of throwing";
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (std::range_error&) {
//LOG(INFO) << e.what();
}
LOG(ERROR) << "to<char> returned "
<< static_cast<unsigned int>(i2)
<< " instead of throwing";
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (std::range_error&) {
//LOG(INFO) << e.what();
}
LOG(ERROR) << "to<A> returned "
<< static_cast<unsigned int>(i2)
<< " instead of throwing";
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (std::range_error&) {
//LOG(INFO) << e.what();
}
try {
auto i = to<int32_t>(x);
LOG(ERROR) << "to<int32_t> returned " << i << " instead of throwing";
- EXPECT_TRUE(false);
+ ADD_FAILURE();
} catch (std::range_error&) {
}
}
EXPECT_TRUE(to<bool>(42ul));
}
-template<typename Src>
+template <typename Src>
void testStr2Bool() {
EXPECT_FALSE(to<bool>(Src("0")));
EXPECT_FALSE(to<bool>(Src(" 000 ")));
std::string where = to<std::string>(__FILE__, "(", line, "): ");
try {
auto res = expr();
- EXPECT_TRUE(false) << where << exprStr << " -> " << res;
+ ADD_FAILURE() << where << exprStr << " -> " << res;
} catch (const ConversionError& e) {
EXPECT_EQ(code, e.errorCode()) << where << exprStr;
std::string str(e.what());
}
}
}
-}
+} // namespace
#define EXPECT_CONV_ERROR_QUOTE(expr, code, value, quoted) \
testConvError( \
oss << to<std::string>(value);
return oss.str();
}
-}
+} // namespace
#define EXPECT_CONV_ERROR_ARITH(type, val, code) \
EXPECT_CONV_ERROR_QUOTE( \
EXPECT_EQ(rv2.value(), 4711);
}
+TEST(Conv, TryStringToEnum) {
+ enum class A { x = 42, y = 420, z = 65 };
+ auto rv1 = folly::tryTo<A>("1000000000000000000000000000000");
+ EXPECT_FALSE(rv1.hasValue());
+ auto rv2 = folly::tryTo<A>("42");
+ EXPECT_TRUE(rv2.hasValue());
+ EXPECT_EQ(A::x, rv2.value());
+ auto rv3 = folly::tryTo<A>("50");
+ EXPECT_TRUE(rv3.hasValue());
+ EXPECT_EQ(static_cast<A>(50), rv3.value());
+}
+
TEST(Conv, TryStringToFloat) {
auto rv1 = folly::tryTo<float>("");
EXPECT_FALSE(rv1.hasValue());
return 2000 + folly::estimateSpaceNeeded(in.w) +
folly::estimateSpaceNeeded(in.h);
}
+
+enum class SmallEnum {};
+
+Expected<StringPiece, ConversionCode> parseTo(StringPiece in, SmallEnum& out) {
+ out = {};
+ if (in == "SmallEnum") {
+ return in.removePrefix(in), in;
+ } else {
+ return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);
+ }
+}
+
+template <class String>
+void toAppend(SmallEnum, String* result) {
+ folly::toAppend("SmallEnum", result);
}
+} // namespace my
TEST(Conv, custom_kkproviders) {
my::Dimensions expected{7, 8};
// make sure above implementation of estimateSpaceNeeded() is used.
EXPECT_GT(str.capacity(), 2000);
EXPECT_LT(str.capacity(), 2500);
+ // toAppend with other arguments
+ toAppend("|", expected, &str);
+ EXPECT_EQ("7x8|7x8", str);
+}
+
+TEST(conv, custom_enumclass) {
+ EXPECT_EQ(my::SmallEnum{}, folly::to<my::SmallEnum>("SmallEnum"));
+ EXPECT_EQ(my::SmallEnum{}, folly::tryTo<my::SmallEnum>("SmallEnum").value());
+ auto str = to<string>(my::SmallEnum{});
+ toAppend("|", my::SmallEnum{}, &str);
+ EXPECT_EQ("SmallEnum|SmallEnum", str);
}
TEST(Conv, TryToThenWithVoid) {