De-abseil: Add our own llarp::TrimWhiteSpace

Adds a TrimWhiteSpace instead of using abseil's.

Adds Catch2 tests for it, and also converts the existing str tests to
catch (which look much, much nicer than the gtest ones).
pull/1124/head
Jason Rhinelander 4 years ago
parent 00a624ab40
commit 98c34d995b

@ -12,8 +12,6 @@
#include <util/str.hpp>
#include <util/lokinet_init.h>
#include <absl/strings/strip.h>
#include <cstdlib>
#include <fstream>
#include <ios>
@ -237,13 +235,13 @@ namespace llarp
if(idx != std::string::npos)
{
std::string data = v.substr(0, idx);
absl::StripAsciiWhitespace(&data);
TrimWhiteSpace(data);
parsed_opts.emplace(std::move(data));
v = v.substr(idx + 1);
}
else
{
absl::StripAsciiWhitespace(&v);
TrimWhiteSpace(v);
parsed_opts.insert(std::move(v));
}
} while(idx != std::string::npos);

@ -18,8 +18,6 @@
#include <util/str.hpp>
#include <absl/strings/ascii.h>
namespace llarp
{
namespace handlers
@ -193,7 +191,7 @@ namespace llarp
{
routerStr = v;
}
absl::StripAsciiWhitespace(&routerStr);
TrimWhiteSpace(routerStr);
if(!(exitRouter.FromString(routerStr)
|| HexDecode(routerStr.c_str(), exitRouter.begin(),
exitRouter.size())))

@ -60,4 +60,24 @@ namespace llarp
return false;
}
constexpr static char whitespace[] = " \t\n\r\f\v";
void
TrimWhiteSpace(std::string& str)
{
size_t begin = str.find_first_not_of(whitespace);
if(begin == std::string::npos)
{
str.clear();
return;
}
size_t end = str.find_last_not_of(whitespace) + 1;
if(begin == 0)
str.resize(end);
else
{
std::copy(str.begin() + begin, str.begin() + end, str.begin());
str.resize(end - begin);
}
}
} // namespace llarp

@ -20,6 +20,11 @@ namespace llarp
bool
IsTrueValue(string_view str);
/// Trim leading and trailing (ascii) whitespace from the given string; the
/// string is modified in-place.
void
TrimWhiteSpace(std::string &str);
} // namespace llarp
#endif

@ -39,7 +39,6 @@ list(APPEND TEST_SRC
util/test_llarp_util_decaying_hashset.cpp
util/test_llarp_util_encode.cpp
util/test_llarp_util_printer.cpp
util/test_llarp_utils_str.cpp
util/test_llarp_util_log_level.cpp
util/thread/test_llarp_util_queue_manager.cpp
util/thread/test_llarp_util_queue.cpp
@ -75,6 +74,7 @@ add_subdirectory(Catch2)
add_executable(${CHECK_EXE}
nodedb/test_nodedb.cpp
path/test_path.cpp
util/test_llarp_util_str.cpp
check_main.cpp)
target_link_libraries(${CHECK_EXE} PUBLIC ${STATIC_LIB} Catch2::Catch2)

@ -0,0 +1,89 @@
#include <util/str.hpp>
#include <catch2/catch.hpp>
using namespace std::literals;
TEST_CASE("TrimWhiteSpace -- positive tests", "[str][trim]")
{
// Test that things that should be trimmed actually get trimmed
auto fee = " J a c k"s;
auto fi = "\ra\nd"s;
auto fo = "\fthe "s;
auto fum = " \t\r\n\v\f Beanstalk\n\n\n\t\r\f\v \n\n\r\f\f\f\f\v"s;
for (auto* s: {&fee, &fi, &fo, &fum})
llarp::TrimWhiteSpace(*s);
REQUIRE( fee == "J a c k" );
REQUIRE( fi == "a\nd" );
REQUIRE( fo == "the" );
REQUIRE( fum == "Beanstalk" );
}
TEST_CASE("TrimWhitespace -- negative tests", "[str][trim]")
{
// Test that things that shouldn't be trimmed don't get trimmed
auto c = GENERATE(range(std::numeric_limits<char>::min(), std::numeric_limits<char>::max()));
std::string plant = c + "bean"s + c;
llarp::TrimWhiteSpace(plant);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v')
REQUIRE( plant == "bean" );
else
{
REQUIRE( plant.size() == 6 );
REQUIRE( plant.substr(1, 4) == "bean" );
}
}
TEST_CASE("caseless comparison tests - less than", "[str][lt]") {
using namespace llarp;
CaselessLessThan lt;
auto expect_less_than = GENERATE(table<const char*, const char*>({
{"", "1"},
{"1", "11"},
{"abc", "abcd"},
{"ABC", "abcd"},
{"abc", "ABCD"},
{"abc", "Abcd"},
{"abc", "abcD"},
{"abc", "abCd"},
{"abc", "zz"},
{"abc", "zzzz"},
{"abc", "abd"},
{"abc", "aBd"},
{"abc", "abD"},
{"ABC", "abd"},
{"abC", "abd"},
}));
REQUIRE( lt(std::get<0>(expect_less_than), std::get<1>(expect_less_than)) );
REQUIRE( !lt(std::get<1>(expect_less_than), std::get<0>(expect_less_than)) );
}
TEST_CASE("caseless comparison tests - equality", "[str][eq]") {
using namespace llarp;
CaselessLessThan lt;
auto expect_less_than = GENERATE(table<const char*, const char*>({
{"1", "1"},
{"a", "A"},
{"abc", "ABC"},
{"abc", "aBc"},
{"ABC", "abc"},
}));
REQUIRE( !lt(std::get<0>(expect_less_than), std::get<1>(expect_less_than)) );
REQUIRE( !lt(std::get<1>(expect_less_than), std::get<0>(expect_less_than)) );
}
TEST_CASE("truthy string values", "[str][truthy]") {
auto val = GENERATE("true", "TruE", "yes", "yeS", "yES", "yes", "YES", "1", "on", "oN", "ON");
REQUIRE( llarp::IsTrueValue(val) );
}
TEST_CASE("falsey string values", "[str][falsey]") {
auto val = GENERATE("false", "FalSe", "no", "NO", "No", "nO", "0", "off", "OFF");
REQUIRE( llarp::IsFalseValue(val) );
}
TEST_CASE("neither true nor false string values", "[str][nottruefalse]") {
auto val = GENERATE("false y", "maybe", "not on", "2", "yesno", "YESNO", "-1", "default", "OMG");
REQUIRE( !llarp::IsTrueValue(val) );
REQUIRE( !llarp::IsFalseValue(val) );
}

@ -1,68 +0,0 @@
#include <util/str.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace llarp;
using namespace ::testing;
struct CmpTestData
{
bool lt;
std::string lhs;
std::string rhs;
};
class CaselessCmpTest : public ::testing::TestWithParam< CmpTestData >
{
};
TEST_P(CaselessCmpTest, test)
{
CaselessCmp cmp;
auto d = GetParam();
ASSERT_EQ(d.lt, cmp(d.lhs, d.rhs));
}
std::vector< CmpTestData > CMPTESTDATA{
{true, "", "1"}, {false, "1", ""}, {true, "abc", "abcd"},
{true, "abc", "abd"}, {false, "11", "1"}, {false, "a", "A"},
{false, "abc", "aBc"}, {false, "ABC", "abc"}};
INSTANTIATE_TEST_SUITE_P(TestStr, CaselessCmpTest, ValuesIn(CMPTESTDATA));
using TestData = std::pair< bool, std::string >;
class TestIsFalseValue : public ::testing::TestWithParam< TestData >
{
};
TEST_P(TestIsFalseValue, test)
{
ASSERT_EQ(GetParam().first, IsFalseValue(GetParam().second));
}
std::vector< TestData > FALSE_DATA{
{true, "false"}, {true, "FaLsE"}, {true, "no"}, {true, "nO"},
{true, "No"}, {true, "NO"}, {true, "NO"}, {true, "0"},
{true, "off"}, {true, "oFF"}, {false, "false y"}, {false, "true"},
{false, "tRue"}, {false, "on"}};
INSTANTIATE_TEST_SUITE_P(TestStr, TestIsFalseValue, ValuesIn(FALSE_DATA));
class TestIsTrueValue : public ::testing::TestWithParam< TestData >
{
};
TEST_P(TestIsTrueValue, test)
{
ASSERT_EQ(GetParam().first, IsTrueValue(GetParam().second));
}
std::vector< TestData > TRUE_DATA{
{true, "true"}, {true, "TruE"}, {true, "yes"}, {true, "yeS"},
{true, "yES"}, {true, "YES"}, {true, "1"}, {false, "0"},
{true, "on"}, {true, "oN"}, {false, "false y"}, {false, "truth"},
{false, "false"}, {false, "off"}};
INSTANTIATE_TEST_SUITE_P(TestStr, TestIsTrueValue, ValuesIn(TRUE_DATA));
Loading…
Cancel
Save