# HG changeset patch # User David Demelier # Date 1523045167 -7200 # Node ID 6eb4caea77a540637d4cffbf4378b21e1a7d2c03 # Parent 8a79b5c0ddc72a30c9653a4cfb4a567e91c80b46 Tests: split libirccd util tests into libcommon, closes #789 @1h While here, remove unneeded and deprecated functions from string_util and adapt existing code to new functions. diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 CMakeLists.txt --- a/CMakeLists.txt Fri Apr 06 21:10:34 2018 +0200 +++ b/CMakeLists.txt Fri Apr 06 22:06:07 2018 +0200 @@ -70,6 +70,8 @@ include(cmake/function/IrccdIndentMessage.cmake) include(cmake/check/PutTime.cmake) +include(cmake/check/UidIsSigned.cmake) +include(cmake/check/GidIsSigned.cmake) include(cmake/IrccdVersion.cmake) include(cmake/IrccdOptions.cmake) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 cmake/check/GidIsSigned.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake/check/GidIsSigned.cmake Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,33 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2018 David Demelier +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +include(CheckCXXSourceCompiles) + +# Check if gid_t is signed. +check_cxx_source_compiles( + "#include + + #include + + int main() + { + static_assert(std::is_signed::value, \"gid is signed\"); + } + " + HAVE_SIGNED_GID_T +) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 cmake/check/UidIsSigned.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmake/check/UidIsSigned.cmake Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,33 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2018 David Demelier +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +include(CheckCXXSourceCompiles) + +# Check if uid_t is signed. +check_cxx_source_compiles( + "#include + + #include + + int main() + { + static_assert(std::is_signed::value, \"uid is signed\"); + } + " + HAVE_SIGNED_UID_T +) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 cmake/internal/sysconfig.hpp.in --- a/cmake/internal/sysconfig.hpp.in Fri Apr 06 21:10:34 2018 +0200 +++ b/cmake/internal/sysconfig.hpp.in Fri Apr 06 22:06:07 2018 +0200 @@ -87,7 +87,8 @@ #cmakedefine HAVE_SETGID #cmakedefine HAVE_SETPROGNAME #cmakedefine HAVE_SETUID -#cmakedefine HAVE_STD_PUT_TIME +#cmakedefine HAVE_SIGNED_GID_T +#cmakedefine HAVE_SIGNED_UID_T #cmakedefine HAVE_STAT #cmakedefine HAVE_STAT_ST_ATIME #cmakedefine HAVE_STAT_ST_BLKSIZE @@ -102,6 +103,7 @@ #cmakedefine HAVE_STAT_ST_RDEV #cmakedefine HAVE_STAT_ST_SIZE #cmakedefine HAVE_STAT_ST_UID +#cmakedefine HAVE_STD_PUT_TIME #cmakedefine HAVE_SYSLOG /* diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 libcommon/irccd/string_util.cpp --- a/libcommon/irccd/string_util.cpp Fri Apr 06 21:10:34 2018 +0200 +++ b/libcommon/irccd/string_util.cpp Fri Apr 06 22:06:07 2018 +0200 @@ -344,30 +344,6 @@ return value == "1" || value == "YES" || value == "TRUE" || value == "ON"; } -bool is_int(const std::string &str, int base) noexcept -{ - if (str.empty()) - return false; - - char *ptr; - - std::strtol(str.c_str(), &ptr, base); - - return *ptr == 0; -} - -bool is_real(const std::string &str) noexcept -{ - if (str.empty()) - return false; - - char *ptr; - - std::strtod(str.c_str(), &ptr); - - return *ptr == 0; -} - } // !string_util } // !util diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 libcommon/irccd/string_util.hpp --- a/libcommon/irccd/string_util.hpp Fri Apr 06 21:10:34 2018 +0200 +++ b/libcommon/irccd/string_util.hpp Fri Apr 06 22:06:07 2018 +0200 @@ -275,34 +275,6 @@ IRCCD_EXPORT bool is_boolean(std::string value) noexcept; /** - * Check if the string is an integer. - * - * \param value the input - * \param base the optional base - * \return true if integer - */ -IRCCD_EXPORT bool is_int(const std::string& value, int base = 10) noexcept; - -/** - * Check if the string is real. - * - * \param value the value - * \return true if real - */ -IRCCD_EXPORT bool is_real(const std::string& value) noexcept; - -/** - * Check if the string is a number. - * - * \param value the value - * \return true if it is a number - */ -inline bool is_number(const std::string& value) noexcept -{ - return is_int(value) || is_real(value); -} - -/** * \cond HIDDEN_SYMBOLS */ diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 libcommon/irccd/system.cpp --- a/libcommon/irccd/system.cpp Fri Apr 06 21:10:34 2018 +0200 +++ b/libcommon/irccd/system.cpp Fri Apr 06 22:06:07 2018 +0200 @@ -478,11 +478,13 @@ { assert(value.c_str()); - uid_t id; +#if defined(HAVE_SIGNED_UID_T) + auto id = string_util::to_int(value); +#else + auto id = string_util::to_uint(value); +#endif - if (string_util::is_int(value)) - id = std::stoi(value); - else { + if (!id) { auto pw = getpwnam(value.c_str()); if (!pw) @@ -491,7 +493,7 @@ id = pw->pw_uid; } - if (setuid(id) < 0) + if (setuid(*id) < 0) throw std::runtime_error(std::strerror(errno)); } @@ -503,11 +505,13 @@ { assert(value.c_str()); - gid_t id; +#if defined(HAVE_SIGNED_GID_T) + auto id = string_util::to_int(value); +#else + auto id = string_util::to_uint(value); +#endif - if (string_util::is_int(value)) - id = std::stoi(value); - else { + if (!id) { auto gr = getgrnam(value.c_str()); if (!gr) @@ -516,7 +520,7 @@ id = gr->gr_gid; } - if (setgid(id) < 0) + if (setgid(*id) < 0) throw std::runtime_error(std::strerror(errno)); } diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libcommon/CMakeLists.txt --- a/tests/src/libcommon/CMakeLists.txt Fri Apr 06 21:10:34 2018 +0200 +++ b/tests/src/libcommon/CMakeLists.txt Fri Apr 06 22:06:07 2018 +0200 @@ -16,4 +16,6 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # +add_subdirectory(fs-util) add_subdirectory(network-stream) +add_subdirectory(string-util) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libcommon/fs-util/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libcommon/fs-util/CMakeLists.txt Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,23 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2018 David Demelier +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +irccd_define_test( + NAME fs-util + SOURCES main.cpp + LIBRARIES libcommon +) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libcommon/fs-util/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libcommon/fs-util/main.cpp Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,79 @@ +/* + * main.cpp -- test fs_util functions + * + * Copyright (c) 2013-2018 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define BOOST_TEST_MODULE "fs_util" +#include + +#include +#include + +namespace irccd { + +/* + * fs_util::find function (name) + * ------------------------------------------------------------------ + */ + +BOOST_AUTO_TEST_SUITE(fs_find_name) + +BOOST_AUTO_TEST_CASE(not_recursive) +{ + auto file1 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-1.txt", false); + auto file2 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-2.txt", false); + + BOOST_TEST(file1.find("file-1.txt") != std::string::npos); + BOOST_TEST(file2.empty()); +} + +BOOST_AUTO_TEST_CASE(recursive) +{ + auto file1 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-1.txt", true); + auto file2 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-2.txt", true); + + BOOST_TEST(file1.find("file-1.txt") != std::string::npos); + BOOST_TEST(file2.find("file-2.txt") != std::string::npos); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * fs_util::find function (regex) + * ------------------------------------------------------------------ + */ + +BOOST_AUTO_TEST_SUITE(fs_find_regex) + +BOOST_AUTO_TEST_CASE(not_recursive) +{ + const std::regex regex("file-[12]\\.txt"); + const auto file = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", regex, false); + + BOOST_TEST(file.find("file-1.txt") != std::string::npos); +} + +BOOST_AUTO_TEST_CASE(recursive) +{ + const std::regex regex("file-[12]\\.txt"); + const auto file = fs_util::find(CMAKE_SOURCE_DIR "/tests/root/level-1", regex, true); + + BOOST_TEST(file.find("file-2.txt") != std::string::npos); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // !irccd diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libcommon/string-util/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libcommon/string-util/CMakeLists.txt Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,23 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2018 David Demelier +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +irccd_define_test( + NAME string-util + SOURCES main.cpp + LIBRARIES libcommon +) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libcommon/string-util/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/src/libcommon/string-util/main.cpp Fri Apr 06 22:06:07 2018 +0200 @@ -0,0 +1,380 @@ +/* + * main.cpp -- test string_util functions + * + * Copyright (c) 2013-2018 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define BOOST_TEST_MODULE "string_util" +#include + +#include +#include + +namespace irccd { + +/* + * string_util::format function + * -------------------------------------------------------- + */ +BOOST_AUTO_TEST_SUITE(format) + +BOOST_AUTO_TEST_CASE(nothing) +{ + std::string expected = "hello world!"; + std::string result = string_util::format("hello world!"); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(escape) +{ + string_util::subst params; + + params.keywords.emplace("target", "hello"); + + BOOST_TEST(string_util::format("$@#") == "$@#"); + BOOST_TEST(string_util::format(" $ @ # ") == " $ @ # "); + BOOST_TEST(string_util::format("#") == "#"); + BOOST_TEST(string_util::format(" # ") == " # "); + BOOST_TEST(string_util::format("#@") == "#@"); + BOOST_TEST(string_util::format("##") == "##"); + BOOST_TEST(string_util::format("#!") == "#!"); + BOOST_TEST(string_util::format("##{target}") == "#{target}"); + BOOST_TEST(string_util::format("@#{target}", params) == "@hello"); + BOOST_TEST(string_util::format("#{target}#", params) == "hello#"); + BOOST_REQUIRE_THROW(string_util::format("#{failure"), std::exception); +} + +BOOST_AUTO_TEST_CASE(disable_date) +{ + string_util::subst params; + + params.flags &= ~(string_util::subst_flags::date); + + BOOST_TEST(string_util::format("%H:%M", params) == "%H:%M"); +} + +BOOST_AUTO_TEST_CASE(disable_keywords) +{ + string_util::subst params; + + params.keywords.emplace("target", "hello"); + params.flags &= ~(string_util::subst_flags::keywords); + + BOOST_TEST(string_util::format("#{target}", params) == "#{target}"); +} + +BOOST_AUTO_TEST_CASE(disable_env) +{ + string_util::subst params; + + params.flags &= ~(string_util::subst_flags::env); + + BOOST_TEST(string_util::format("${HOME}", params) == "${HOME}"); +} + +BOOST_AUTO_TEST_CASE(keyword_simple) +{ + string_util::subst params; + + params.keywords.insert({"target", "irccd"}); + + std::string expected = "hello irccd!"; + std::string result = string_util::format("hello #{target}!", params); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(keyword_multiple) +{ + string_util::subst params; + + params.keywords.insert({"target", "irccd"}); + params.keywords.insert({"source", "nightmare"}); + + std::string expected = "hello irccd from nightmare!"; + std::string result = string_util::format("hello #{target} from #{source}!", params); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(keyword_adj_twice) +{ + string_util::subst params; + + params.keywords.insert({"target", "irccd"}); + + std::string expected = "hello irccdirccd!"; + std::string result = string_util::format("hello #{target}#{target}!", params); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(keyword_missing) +{ + std::string expected = "hello !"; + std::string result = string_util::format("hello #{target}!"); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(env_simple) +{ + std::string home = sys::env("HOME"); + + if (!home.empty()) { + std::string expected = "my home is " + home; + std::string result = string_util::format("my home is ${HOME}"); + + BOOST_TEST(expected == result); + } +} + +BOOST_AUTO_TEST_CASE(env_missing) +{ + std::string expected = "value is "; + std::string result = string_util::format("value is ${HOPE_THIS_VAR_NOT_EXIST}"); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * string_util::split function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(split) + +using list = std::vector; + +BOOST_AUTO_TEST_CASE(simple) +{ + list expected { "a", "b" }; + list result = string_util::split("a;b", ";"); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(cut) +{ + list expected { "msg", "#staff", "foo bar baz" }; + list result = string_util::split("msg;#staff;foo bar baz", ";", 3); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * string_util::strip function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(strip) + +BOOST_AUTO_TEST_CASE(left) +{ + std::string value = " 123"; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "123"); +} + +BOOST_AUTO_TEST_CASE(right) +{ + std::string value = "123 "; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "123"); +} + +BOOST_AUTO_TEST_CASE(both) +{ + std::string value = " 123 "; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "123"); +} + +BOOST_AUTO_TEST_CASE(none) +{ + std::string value = "without"; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "without"); +} + +BOOST_AUTO_TEST_CASE(betweenEmpty) +{ + std::string value = "one list"; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "one list"); +} + +BOOST_AUTO_TEST_CASE(betweenLeft) +{ + std::string value = " space at left"; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "space at left"); +} + +BOOST_AUTO_TEST_CASE(betweenRight) +{ + std::string value = "space at right "; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "space at right"); +} + +BOOST_AUTO_TEST_CASE(betweenBoth) +{ + std::string value = " space at both "; + std::string result = string_util::strip(value); + + BOOST_TEST(result == "space at both"); +} + +BOOST_AUTO_TEST_CASE(empty) +{ + std::string value = " "; + std::string result = string_util::strip(value); + + BOOST_TEST(result == ""); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * string_util::join function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(join) + +BOOST_AUTO_TEST_CASE(empty) +{ + std::string expected = ""; + std::string result = string_util::join({}); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(one) +{ + std::string expected = "1"; + std::string result = string_util::join({1}); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(two) +{ + std::string expected = "1:2"; + std::string result = string_util::join({1, 2}); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(delimiterString) +{ + std::string expected = "1;;2;;3"; + std::string result = string_util::join({1, 2, 3}, ";;"); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_CASE(delimiterChar) +{ + std::string expected = "1@2@3@4"; + std::string result = string_util::join({1, 2, 3, 4}, '@'); + + BOOST_TEST(expected == result); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * string_util::is_identifier function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(is_identifier_valid) + +BOOST_AUTO_TEST_CASE(correct) +{ + BOOST_TEST(string_util::is_identifier("localhost")); + BOOST_TEST(string_util::is_identifier("localhost2")); + BOOST_TEST(string_util::is_identifier("localhost2-4_")); +} + +BOOST_AUTO_TEST_CASE(incorrect) +{ + BOOST_TEST(!string_util::is_identifier("")); + BOOST_TEST(!string_util::is_identifier("localhost with spaces")); + BOOST_TEST(!string_util::is_identifier("localhost*")); + BOOST_TEST(!string_util::is_identifier("&&")); + BOOST_TEST(!string_util::is_identifier("@'")); + BOOST_TEST(!string_util::is_identifier("##")); + BOOST_TEST(!string_util::is_identifier("===++")); +} + +BOOST_AUTO_TEST_SUITE_END() + +/* + * string_util::is_boolean function + * -------------------------------------------------------- + */ + +BOOST_AUTO_TEST_SUITE(is_boolean) + +BOOST_AUTO_TEST_CASE(correct) +{ + // true + BOOST_TEST(string_util::is_boolean("true")); + BOOST_TEST(string_util::is_boolean("True")); + BOOST_TEST(string_util::is_boolean("TRUE")); + BOOST_TEST(string_util::is_boolean("TruE")); + + // yes + BOOST_TEST(string_util::is_boolean("yes")); + BOOST_TEST(string_util::is_boolean("Yes")); + BOOST_TEST(string_util::is_boolean("YES")); + BOOST_TEST(string_util::is_boolean("YeS")); + + // on + BOOST_TEST(string_util::is_boolean("on")); + BOOST_TEST(string_util::is_boolean("On")); + BOOST_TEST(string_util::is_boolean("oN")); + BOOST_TEST(string_util::is_boolean("ON")); + + // 1 + BOOST_TEST(string_util::is_boolean("1")); +} + +BOOST_AUTO_TEST_CASE(incorrect) +{ + BOOST_TEST(!string_util::is_boolean("false")); + BOOST_TEST(!string_util::is_boolean("lol")); + BOOST_TEST(!string_util::is_boolean("")); + BOOST_TEST(!string_util::is_boolean("0")); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // !irccd diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libirccd/CMakeLists.txt --- a/tests/src/libirccd/CMakeLists.txt Fri Apr 06 21:10:34 2018 +0200 +++ b/tests/src/libirccd/CMakeLists.txt Fri Apr 06 22:06:07 2018 +0200 @@ -48,4 +48,3 @@ add_subdirectory(irc) add_subdirectory(logger) add_subdirectory(rules) -add_subdirectory(util) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libirccd/util/CMakeLists.txt --- a/tests/src/libirccd/util/CMakeLists.txt Fri Apr 06 21:10:34 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for irccd -# -# Copyright (c) 2013-2018 David Demelier -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -irccd_define_test( - NAME util - SOURCES main.cpp - LIBRARIES libirccd -) diff -r 8a79b5c0ddc7 -r 6eb4caea77a5 tests/src/libirccd/util/main.cpp --- a/tests/src/libirccd/util/main.cpp Fri Apr 06 21:10:34 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,472 +0,0 @@ -/* - * main.cpp -- test util functions - * - * Copyright (c) 2013-2018 David Demelier - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define BOOST_TEST_MODULE "util" -#include - -#include - -#include -#include -#include - -namespace std { - -std::ostream& operator<<(std::ostream& out, const std::vector& list) -{ - for (const auto& s : list) - out << s << " "; - - return out; -} - -} // !std - -namespace irccd { - -BOOST_AUTO_TEST_SUITE(format) - -/* - * string_util::format function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_CASE(nothing) -{ - std::string expected = "hello world!"; - std::string result = string_util::format("hello world!"); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(escape) -{ - string_util::subst params; - - params.keywords.emplace("target", "hello"); - - BOOST_REQUIRE_EQUAL("$@#", string_util::format("$@#")); - BOOST_REQUIRE_EQUAL(" $ @ # ", string_util::format(" $ @ # ")); - BOOST_REQUIRE_EQUAL("#", string_util::format("#")); - BOOST_REQUIRE_EQUAL(" # ", string_util::format(" # ")); - BOOST_REQUIRE_EQUAL("#@", string_util::format("#@")); - BOOST_REQUIRE_EQUAL("##", string_util::format("##")); - BOOST_REQUIRE_EQUAL("#!", string_util::format("#!")); - BOOST_REQUIRE_EQUAL("#{target}", string_util::format("##{target}")); - BOOST_REQUIRE_EQUAL("@hello", string_util::format("@#{target}", params)); - BOOST_REQUIRE_EQUAL("hello#", string_util::format("#{target}#", params)); - BOOST_REQUIRE_THROW(string_util::format("#{failure"), std::exception); -} - -BOOST_AUTO_TEST_CASE(disable_date) -{ - string_util::subst params; - - params.flags &= ~(string_util::subst_flags::date); - - BOOST_REQUIRE_EQUAL("%H:%M", string_util::format("%H:%M", params)); -} - -BOOST_AUTO_TEST_CASE(disable_keywords) -{ - string_util::subst params; - - params.keywords.emplace("target", "hello"); - params.flags &= ~(string_util::subst_flags::keywords); - - BOOST_REQUIRE_EQUAL("#{target}", string_util::format("#{target}", params)); -} - -BOOST_AUTO_TEST_CASE(disable_env) -{ - string_util::subst params; - - params.flags &= ~(string_util::subst_flags::env); - - BOOST_REQUIRE_EQUAL("${HOME}", string_util::format("${HOME}", params)); -} - -BOOST_AUTO_TEST_CASE(keyword_simple) -{ - string_util::subst params; - - params.keywords.insert({"target", "irccd"}); - - std::string expected = "hello irccd!"; - std::string result = string_util::format("hello #{target}!", params); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(keyword_multiple) -{ - string_util::subst params; - - params.keywords.insert({"target", "irccd"}); - params.keywords.insert({"source", "nightmare"}); - - std::string expected = "hello irccd from nightmare!"; - std::string result = string_util::format("hello #{target} from #{source}!", params); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(keyword_adj_twice) -{ - string_util::subst params; - - params.keywords.insert({"target", "irccd"}); - - std::string expected = "hello irccdirccd!"; - std::string result = string_util::format("hello #{target}#{target}!", params); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(keyword_missing) -{ - std::string expected = "hello !"; - std::string result = string_util::format("hello #{target}!"); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(env_simple) -{ - std::string home = sys::env("HOME"); - - if (!home.empty()) { - std::string expected = "my home is " + home; - std::string result = string_util::format("my home is ${HOME}"); - - BOOST_REQUIRE_EQUAL(expected, result); - } -} - -BOOST_AUTO_TEST_CASE(env_missing) -{ - std::string expected = "value is "; - std::string result = string_util::format("value is ${HOPE_THIS_VAR_NOT_EXIST}"); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::split function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(split) - -using list = std::vector; - -BOOST_AUTO_TEST_CASE(simple) -{ - list expected { "a", "b" }; - list result = string_util::split("a;b", ";"); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(cut) -{ - list expected { "msg", "#staff", "foo bar baz" }; - list result = string_util::split("msg;#staff;foo bar baz", ";", 3); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::strip function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(strip) - -BOOST_AUTO_TEST_CASE(left) -{ - std::string value = " 123"; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("123", result); -} - -BOOST_AUTO_TEST_CASE(right) -{ - std::string value = "123 "; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("123", result); -} - -BOOST_AUTO_TEST_CASE(both) -{ - std::string value = " 123 "; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("123", result); -} - -BOOST_AUTO_TEST_CASE(none) -{ - std::string value = "without"; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("without", result); -} - -BOOST_AUTO_TEST_CASE(betweenEmpty) -{ - std::string value = "one list"; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("one list", result); -} - -BOOST_AUTO_TEST_CASE(betweenLeft) -{ - std::string value = " space at left"; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("space at left", result); -} - -BOOST_AUTO_TEST_CASE(betweenRight) -{ - std::string value = "space at right "; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("space at right", result); -} - -BOOST_AUTO_TEST_CASE(betweenBoth) -{ - std::string value = " space at both "; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("space at both", result); -} - -BOOST_AUTO_TEST_CASE(empty) -{ - std::string value = " "; - std::string result = string_util::strip(value); - - BOOST_REQUIRE_EQUAL("", result); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::join function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(join) - -BOOST_AUTO_TEST_CASE(empty) -{ - std::string expected = ""; - std::string result = string_util::join({}); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(one) -{ - std::string expected = "1"; - std::string result = string_util::join({1}); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(two) -{ - std::string expected = "1:2"; - std::string result = string_util::join({1, 2}); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(delimiterString) -{ - std::string expected = "1;;2;;3"; - std::string result = string_util::join({1, 2, 3}, ";;"); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_CASE(delimiterChar) -{ - std::string expected = "1@2@3@4"; - std::string result = string_util::join({1, 2, 3, 4}, '@'); - - BOOST_REQUIRE_EQUAL(expected, result); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::is_identifier function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(is_identifier_valid) - -BOOST_AUTO_TEST_CASE(correct) -{ - BOOST_REQUIRE(string_util::is_identifier("localhost")); - BOOST_REQUIRE(string_util::is_identifier("localhost2")); - BOOST_REQUIRE(string_util::is_identifier("localhost2-4_")); -} - -BOOST_AUTO_TEST_CASE(incorrect) -{ - BOOST_REQUIRE(!string_util::is_identifier("")); - BOOST_REQUIRE(!string_util::is_identifier("localhost with spaces")); - BOOST_REQUIRE(!string_util::is_identifier("localhost*")); - BOOST_REQUIRE(!string_util::is_identifier("&&")); - BOOST_REQUIRE(!string_util::is_identifier("@'")); - BOOST_REQUIRE(!string_util::is_identifier("##")); - BOOST_REQUIRE(!string_util::is_identifier("===++")); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::is_boolean function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(is_boolean) - -BOOST_AUTO_TEST_CASE(correct) -{ - // true - BOOST_REQUIRE(string_util::is_boolean("true")); - BOOST_REQUIRE(string_util::is_boolean("True")); - BOOST_REQUIRE(string_util::is_boolean("TRUE")); - BOOST_REQUIRE(string_util::is_boolean("TruE")); - - // yes - BOOST_REQUIRE(string_util::is_boolean("yes")); - BOOST_REQUIRE(string_util::is_boolean("Yes")); - BOOST_REQUIRE(string_util::is_boolean("YES")); - BOOST_REQUIRE(string_util::is_boolean("YeS")); - - // on - BOOST_REQUIRE(string_util::is_boolean("on")); - BOOST_REQUIRE(string_util::is_boolean("On")); - BOOST_REQUIRE(string_util::is_boolean("oN")); - BOOST_REQUIRE(string_util::is_boolean("ON")); - - // 1 - BOOST_REQUIRE(string_util::is_boolean("1")); -} - -BOOST_AUTO_TEST_CASE(incorrect) -{ - BOOST_REQUIRE(!string_util::is_boolean("false")); - BOOST_REQUIRE(!string_util::is_boolean("lol")); - BOOST_REQUIRE(!string_util::is_boolean("")); - BOOST_REQUIRE(!string_util::is_boolean("0")); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * string_util::is_number function - * -------------------------------------------------------- - */ - -BOOST_AUTO_TEST_SUITE(is_number) - -BOOST_AUTO_TEST_CASE(correct) -{ - BOOST_REQUIRE(string_util::is_number("123")); - BOOST_REQUIRE(string_util::is_number("-123")); - BOOST_REQUIRE(string_util::is_number("123.67")); -} - -BOOST_AUTO_TEST_CASE(incorrect) -{ - BOOST_REQUIRE(!string_util::is_number("lol")); - BOOST_REQUIRE(!string_util::is_number("this is not a number")); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * fs_util::find function (name) - * ------------------------------------------------------------------ - */ - -BOOST_AUTO_TEST_SUITE(fs_find_name) - -BOOST_AUTO_TEST_CASE(not_recursive) -{ - auto file1 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-1.txt", false); - auto file2 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-2.txt", false); - - BOOST_TEST(file1.find("file-1.txt") != std::string::npos); - BOOST_TEST(file2.empty()); -} - -BOOST_AUTO_TEST_CASE(recursive) -{ - auto file1 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-1.txt", true); - auto file2 = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", "file-2.txt", true); - - BOOST_TEST(file1.find("file-1.txt") != std::string::npos); - BOOST_TEST(file2.find("file-2.txt") != std::string::npos); -} - -BOOST_AUTO_TEST_SUITE_END() - -/* - * fs_util::find function (regex) - * ------------------------------------------------------------------ - */ - -BOOST_AUTO_TEST_SUITE(fs_find_regex) - -BOOST_AUTO_TEST_CASE(not_recursive) -{ - const std::regex regex("file-[12]\\.txt"); - - auto file = fs_util::find(CMAKE_SOURCE_DIR "/tests/root", regex, false); - - BOOST_TEST(file.find("file-1.txt") != std::string::npos); -} - -BOOST_AUTO_TEST_CASE(recursive) -{ - const std::regex regex("file-[12]\\.txt"); - - auto file = fs_util::find(CMAKE_SOURCE_DIR "/tests/root/level-1", regex, true); - - BOOST_TEST(file.find("file-2.txt") != std::string::npos); -} - -BOOST_AUTO_TEST_SUITE_END() - -} // !irccd