diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a3c3288..332eaa8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,11 +1,20 @@ include(ExternalProject) -ExternalProject_Add(toml - SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/toml - GIT_REPOSITORY https://github.com/toml-lang/toml - GIT_TAG v0.5.0 + +set(TOML11_LANGSPEC_GIT_REPOSITORY "https://github.com/toml-lang/toml" CACHE STRING + "URL of the TOML language specification repository") + +set(TOML11_LANGSPEC_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/toml" CACHE FILEPATH + "directory for the TOML language specification tree") + +if(NOT EXISTS "${TOML11_LANGSPEC_SOURCE_DIR}/toml.abnf") + ExternalProject_Add(toml + SOURCE_DIR "${TOML11_LANGSPEC_SOURCE_DIR}" + GIT_REPOSITORY "${TOML11_LANGSPEC_GIT_REPOSITORY}" + GIT_TAG "v0.5.0" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") +endif() set(TEST_NAMES test_datetime @@ -62,6 +71,82 @@ CHECK_CXX_COMPILER_FLAG("-Wrange-loop-analysis" COMPILER_SUPPORTS_WRANGE_LOOP_AN CHECK_CXX_COMPILER_FLAG("-Wundef" COMPILER_SUPPORTS_WUNDEF) CHECK_CXX_COMPILER_FLAG("-Wshadow" COMPILER_SUPPORTS_WSHADOW) +include(CheckCXXSourceCompiles) + +# check which standard library implementation is used. If libstdc++ is used, +# it will fail to compile. It compiles if libc++ is used. +check_cxx_source_compiles(" +#include +#ifdef __GLIBCXX__ + static_assert(false); +#endif +int main() { + return 0; +}" TOML11_WITH_LIBCXX_LIBRARY) + +# LLVM 8 requires -lc++fs if compiled with libc++ to use . +# LLVM 9+ does not require any special library. +# GCC 8 requires -lstdc++fs. GCC 9+ does not require it. +# +# Yes, we can check the version of the compiler used in the current build +# directly in CMake. But, in most cases, clang build uses libstdc++ as the +# standard library implementation and it makes the condition complicated. +# In many environment, the default installed C++ compiler is GCC and libstdc++ +# is installed along with it. In most build on such an environment, even if we +# chose clang as the C++ compiler, still libstdc++ is used. Checking default +# gcc version makes the condition complicated. +# The purpose of this file is to compile tests. We know the environment on which +# the tests run. We can set this option and, I think, it is easier and better. +option(TOML11_REQUIRE_FILESYSTEM_LIBRARY "need to link -lstdc++fs or -lc++fs" OFF) + +find_package(Boost COMPONENTS unit_test_framework REQUIRED) + +set(PREVIOUSLY_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") +set(PREVIOUSLY_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + +list(APPEND CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIRS}) +list(APPEND CMAKE_REQUIRED_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#undef BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_HEADER) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#undef BOOST_TEST_DYN_LINK +#undef BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_STATIC) + +check_cxx_source_compiles(" +#define BOOST_TEST_MODULE \"dummy\" +#define BOOST_TEST_DYN_LINK +#undef BOOST_TEST_NO_LIB +#include +BOOST_AUTO_TEST_CASE(proforma) { BOOST_TEST(true); } +" TOML11_WITH_BOOST_TEST_DYNAMIC) + +set(CMAKE_REQUIRED_INCLUDES "${PREVIOUSLY_REQUIRED_INCLUDES}") +set(CMAKE_REQUIRED_LIBRARIES "${PREVIOUSLY_REQUIRED_LIBRARIES}") + +unset(PREVIOUSLY_REQUIRED_INCLUDES) +unset(PREVIOUSLY_REQUIRED_LIBRARIES) + +if(TOML11_WITH_BOOST_TEST_DYNAMIC) + add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST -DBOOST_TEST_DYN_LINK) +elseif(TOML11_WITH_BOOST_TEST_STATIC) + add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST) +elseif(TOML11_WITH_BOOST_TEST_HEADER) + add_definitions(-DBOOST_TEST_NO_LIB) +else() + message(FATAL_ERROR "Neither the Boost.Test static or shared library nor the header-only version seem to be usable.") +endif() + if(COMPILER_SUPPORTS_WALL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() @@ -152,41 +237,18 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4265") endif() -find_package(Boost COMPONENTS unit_test_framework REQUIRED) -add_definitions(-DBOOST_TEST_DYN_LINK) -add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST) - -# check which standard library implementation is used. If libstdc++ is used, -# it will fail to compile. It compiles if libc++ is used. -include(CheckCXXSourceCompiles) -check_cxx_source_compiles(" -#include -#ifdef __GLIBCXX__ - static_assert(false); -#endif -int main() { - return 0; -}" TOML11_WITH_LIBCXX_LIBRARY) - -# LLVM 8 requires -lc++fs if compiled with libc++ to use . -# LLVM 9+ does not require any special library. -# GCC 8 requires -lstdc++fs. GCC 9+ does not require it. -# -# Yes, we can check the version of the compiler used in the current build -# directly in CMake. But, in most cases, clang build uses libstdc++ as the -# standard library implementation and it makes the condition complicated. -# In many environment, the default installed C++ compiler is GCC and libstdc++ -# is installed along with it. In most build on such an environment, even if we -# chose clang as the C++ compiler, still libstdc++ is used. Checking default -# gcc version makes the condition complicated. -# The purpose of this file is to compile tests. We know the environment on which -# the tests run. We can set this option and, I think, it is easier and better. -option(TOML11_REQUIRE_FILESYSTEM_LIBRARY "need to link -lstdc++fs or -lc++fs" OFF) +set(TEST_ENVIRON "TOMLDIR=${TOML11_LANGSPEC_SOURCE_DIR}") +if(WIN32) + # Set the PATH to be able to find Boost DLL + STRING(REPLACE ";" "\\;" PATH_STRING "$ENV{PATH}") + list(APPEND TEST_ENVIRON "PATH=${PATH_STRING}\;${Boost_LIBRARY_DIRS}") +endif() foreach(TEST_NAME ${TEST_NAMES}) add_executable(${TEST_NAME} ${TEST_NAME}.cpp) target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11) target_include_directories(${TEST_NAME} SYSTEM PRIVATE ${Boost_INCLUDE_DIRS}) + target_compile_definitions(${TEST_NAME} PRIVATE "BOOST_TEST_MODULE=\"${TEST_NAME}\"") # to compile tests with ... if(TOML11_REQUIRE_FILESYSTEM_LIBRARY) @@ -212,14 +274,7 @@ foreach(TEST_NAME ${TEST_NAMES}) endif() add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - # Set the PATH to be able to find Boost DLL - if(WIN32) - STRING(REPLACE ";" "\\;" PATH_STRING "$ENV{PATH}") - set_tests_properties(${TEST_NAME} - PROPERTIES ENVIRONMENT "PATH=${PATH_STRING}\;${Boost_LIBRARY_DIRS}" - ) - endif() + set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${TEST_ENVIRON}") endforeach(TEST_NAME) diff --git a/tests/check.cpp b/tests/check.cpp index a271f3f..bf67775 100644 --- a/tests/check.cpp +++ b/tests/check.cpp @@ -1,4 +1,5 @@ -#include "toml.hpp" +#include + #include #include diff --git a/tests/check_serialization.cpp b/tests/check_serialization.cpp index 6f60103..e97d51b 100644 --- a/tests/check_serialization.cpp +++ b/tests/check_serialization.cpp @@ -1,6 +1,7 @@ -#include "toml.hpp" -#include +#include + #include +#include int main(int argc, char **argv) { diff --git a/tests/check_toml_test.cpp b/tests/check_toml_test.cpp index 9c57572..51404c9 100644 --- a/tests/check_toml_test.cpp +++ b/tests/check_toml_test.cpp @@ -1,6 +1,7 @@ -#include "toml.hpp" -#include +#include + #include +#include struct json_serializer { diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 8cc6573..2d2b6a6 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -1,13 +1,7 @@ -#define BOOST_TEST_MODULE "test_comments" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif - #include +#include "unit_test.hpp" + BOOST_AUTO_TEST_CASE(test_comment_before) { { diff --git a/tests/test_datetime.cpp b/tests/test_datetime.cpp index 395949e..bbbcc42 100644 --- a/tests/test_datetime.cpp +++ b/tests/test_datetime.cpp @@ -1,12 +1,7 @@ -#define BOOST_TEST_MODULE "test_datetime" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include +#include "unit_test.hpp" + BOOST_AUTO_TEST_CASE(test_local_date) { const toml::local_date date(2018, toml::month_t::Jan, 1); diff --git a/tests/test_error_detection.cpp b/tests/test_error_detection.cpp index 07c607f..5e39ef6 100644 --- a/tests/test_error_detection.cpp +++ b/tests/test_error_detection.cpp @@ -1,13 +1,9 @@ -#define BOOST_TEST_MODULE "test_error_detection" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include + +#include "unit_test.hpp" + #include +#include BOOST_AUTO_TEST_CASE(test_detect_empty_key) { diff --git a/tests/test_expect.cpp b/tests/test_expect.cpp index 2971f0c..308d4fb 100644 --- a/tests/test_expect.cpp +++ b/tests/test_expect.cpp @@ -1,16 +1,12 @@ -#define BOOST_TEST_MODULE "test_expect" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + +#include +#include +#include #include #include -#include -#include -#include BOOST_AUTO_TEST_CASE(test_expect) { diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp index 7e727ac..1b21264 100644 --- a/tests/test_extended_conversions.cpp +++ b/tests/test_extended_conversions.cpp @@ -1,11 +1,7 @@ -#define BOOST_TEST_MODULE "test_extended_conversions" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + #include #include diff --git a/tests/test_find.cpp b/tests/test_find.cpp index aa44b7b..944b8e8 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -1,22 +1,17 @@ -#define BOOST_TEST_MODULE "test_find" - -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif - #include -#include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include +#include +#include + #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif -#include using test_value_types = std::tuple< toml::basic_value, @@ -830,4 +825,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_va BOOST_TEST(tm.tm_sec == 0); } } - diff --git a/tests/test_find_or.cpp b/tests/test_find_or.cpp index b0f786d..8348f2f 100644 --- a/tests/test_find_or.cpp +++ b/tests/test_find_or.cpp @@ -1,17 +1,14 @@ -#define BOOST_TEST_MODULE "test_find_or" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include #include +#include + #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif diff --git a/tests/test_find_or_recursive.cpp b/tests/test_find_or_recursive.cpp index 364112a..1f2f480 100644 --- a/tests/test_find_or_recursive.cpp +++ b/tests/test_find_or_recursive.cpp @@ -1,17 +1,14 @@ -#define BOOST_TEST_MODULE "test_find_or_recursive" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include #include +#include + #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif @@ -394,8 +391,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move_only, value_type, test_value_typ BOOST_TEST(ref == toml::find_or(v, "key1", "key2", std::move(opt))); } } - - - - - diff --git a/tests/test_format_error.cpp b/tests/test_format_error.cpp index df558da..c00f845 100644 --- a/tests/test_format_error.cpp +++ b/tests/test_format_error.cpp @@ -1,11 +1,7 @@ -#define BOOST_TEST_MODULE "test_format_error" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + #include // to check it successfully compiles. it does not check the formatted string. diff --git a/tests/test_get.cpp b/tests/test_get.cpp index a0dd315..4a16e34 100644 --- a/tests/test_get.cpp +++ b/tests/test_get.cpp @@ -1,17 +1,14 @@ -#define BOOST_TEST_MODULE "test_get" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include #include +#include + #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif @@ -506,4 +503,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_va BOOST_TEST(tm.tm_sec == 0); } } - diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp index 081b966..9ecb36e 100644 --- a/tests/test_get_or.cpp +++ b/tests/test_get_or.cpp @@ -1,17 +1,14 @@ -#define BOOST_TEST_MODULE "test_get_or" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include #include +#include + #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif diff --git a/tests/test_lex_boolean.cpp b/tests/test_lex_boolean.cpp index c2e43a8..deecffe 100644 --- a/tests/test_lex_boolean.cpp +++ b/tests/test_lex_boolean.cpp @@ -1,6 +1,6 @@ -#define BOOST_TEST_MODULE "test_lex_boolean" -#include #include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" using namespace toml; diff --git a/tests/test_lex_datetime.cpp b/tests/test_lex_datetime.cpp index a790eeb..8e33d38 100644 --- a/tests/test_lex_datetime.cpp +++ b/tests/test_lex_datetime.cpp @@ -1,6 +1,6 @@ -#define BOOST_TEST_MODULE "test_lex_datetime" -#include #include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" using namespace toml; diff --git a/tests/test_lex_floating.cpp b/tests/test_lex_floating.cpp index 9c5c809..8c9cd20 100644 --- a/tests/test_lex_floating.cpp +++ b/tests/test_lex_floating.cpp @@ -1,9 +1,10 @@ -#define BOOST_TEST_MODULE "test_lex_floating" -#include #include -#include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" +#include + using namespace toml; using namespace detail; diff --git a/tests/test_lex_integer.cpp b/tests/test_lex_integer.cpp index bb6dbb7..50b9178 100644 --- a/tests/test_lex_integer.cpp +++ b/tests/test_lex_integer.cpp @@ -1,6 +1,6 @@ -#define BOOST_TEST_MODULE "test_lex_integer" -#include #include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" using namespace toml; diff --git a/tests/test_lex_key_comment.cpp b/tests/test_lex_key_comment.cpp index 0921bd6..da123a4 100644 --- a/tests/test_lex_key_comment.cpp +++ b/tests/test_lex_key_comment.cpp @@ -1,6 +1,6 @@ -#define BOOST_TEST_MODULE "lex_key_comment_test" -#include #include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" using namespace toml; diff --git a/tests/test_lex_string.cpp b/tests/test_lex_string.cpp index 643ab31..f8f2424 100644 --- a/tests/test_lex_string.cpp +++ b/tests/test_lex_string.cpp @@ -1,6 +1,6 @@ -#define BOOST_TEST_MODULE "test_lex_string" -#include #include + +#include "unit_test.hpp" #include "test_lex_aux.hpp" using namespace toml; diff --git a/tests/test_literals.cpp b/tests/test_literals.cpp index 5aaf928..de81f39 100644 --- a/tests/test_literals.cpp +++ b/tests/test_literals.cpp @@ -1,11 +1,7 @@ -#define BOOST_TEST_MODULE "test_literals" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + #include BOOST_AUTO_TEST_CASE(test_file_as_literal) diff --git a/tests/test_parse_array.cpp b/tests/test_parse_array.cpp index a75a6f1..053d4c5 100644 --- a/tests/test_parse_array.cpp +++ b/tests/test_parse_array.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_array_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_boolean.cpp b/tests/test_parse_boolean.cpp index 068aaa4..5ed128c 100644 --- a/tests/test_parse_boolean.cpp +++ b/tests/test_parse_boolean.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "test_parse_boolean" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_datetime.cpp b/tests/test_parse_datetime.cpp index e7247b0..46bd78c 100644 --- a/tests/test_parse_datetime.cpp +++ b/tests/test_parse_datetime.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_datetime_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index b525f98..2c45670 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -1,19 +1,15 @@ -#define BOOST_TEST_MODULE "test_parse_file" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include + +#include "unit_test.hpp" + #include +#include +#include +#include BOOST_AUTO_TEST_CASE(test_example) { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); @@ -76,7 +72,7 @@ BOOST_AUTO_TEST_CASE(test_example) BOOST_AUTO_TEST_CASE(test_example_stream) { - std::ifstream ifs("toml/tests/example.toml", std::ios::binary); + std::ifstream ifs(testinput("example.toml"), std::ios::binary); const auto data = toml::parse(ifs); BOOST_TEST(toml::find(data, "title") == "TOML Example"); @@ -144,7 +140,7 @@ BOOST_AUTO_TEST_CASE(test_example_stream) BOOST_AUTO_TEST_CASE(test_example_file_pointer) { - FILE * file = fopen("toml/tests/example.toml", "rb"); + FILE * file = fopen(testinput("example.toml").c_str(), "rb"); const auto data = toml::parse(file, "toml/tests/example.toml"); fclose(file); @@ -213,7 +209,7 @@ BOOST_AUTO_TEST_CASE(test_example_file_pointer) BOOST_AUTO_TEST_CASE(test_fruit) { - const auto data = toml::parse("toml/tests/fruit.toml"); + const auto data = toml::parse(testinput("fruit.toml")); const auto blah = toml::find(toml::find(data, "fruit"), "blah"); BOOST_TEST(toml::find(blah.at(0), "name") == "apple"); BOOST_TEST(toml::find(blah.at(1), "name") == "banana"); @@ -231,7 +227,7 @@ BOOST_AUTO_TEST_CASE(test_fruit) BOOST_AUTO_TEST_CASE(test_hard_example) { - const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto data = toml::parse(testinput("hard_example.toml")); const auto the = toml::find(data, "the"); BOOST_TEST(toml::find(the, "test_string") == "You'll hate me after this - #"); @@ -258,7 +254,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example) } BOOST_AUTO_TEST_CASE(test_hard_example_comment) { - const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto data = toml::parse(testinput("hard_example.toml")); const auto the = toml::find(data, "the"); BOOST_TEST(toml::find(the, "test_string") == "You'll hate me after this - #"); @@ -287,7 +283,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_comment) BOOST_AUTO_TEST_CASE(test_example_preserve_comment) { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); @@ -369,8 +365,8 @@ BOOST_AUTO_TEST_CASE(test_example_preserve_comment) BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse( + testinput("example.toml")); static_assert(std::is_same::type> @@ -993,40 +989,18 @@ BOOST_AUTO_TEST_CASE(test_file_ends_without_lf) BOOST_AUTO_TEST_CASE(test_parse_function_compiles) { - // toml::parse(""); - const auto string_literal = toml::parse("toml/tests/example.toml"); - - BOOST_TEST_MESSAGE("string_literal"); - - const char* fname_cstring = "toml/tests/example.toml"; - // toml::parse(const char*); - const auto cstring = toml::parse(fname_cstring); - - BOOST_TEST_MESSAGE("const char*"); - - // toml::parse(char*); - std::array fname_char_ptr; - std::strncpy(fname_char_ptr.data(), fname_cstring, 24); - const auto char_ptr = toml::parse(fname_char_ptr.data()); - - BOOST_TEST_MESSAGE("char*"); - - // toml::parse(const std::string&); - const std::string fname_string("toml/tests/example.toml"); - const auto string = toml::parse(fname_string); - std::string fname_string_mut("toml/tests/example.toml"); - // toml::parse(std::string&); - const auto string_mutref = toml::parse(fname_string_mut); - // toml::parse(std::string&&); - const auto string_rref = toml::parse(std::move(fname_string_mut)); - - BOOST_TEST_MESSAGE("strings"); - + using result_type = decltype(toml::parse("string literal")); + (void) [](const char* that) -> result_type { return toml::parse(that); }; + (void) [](char* that) -> result_type { return toml::parse(that); }; + (void) [](const std::string& that) -> result_type { return toml::parse(that); }; + (void) [](std::string& that) -> result_type { return toml::parse(that); }; + (void) [](std::string&& that) -> result_type { return toml::parse(that); }; #ifdef TOML11_HAS_STD_FILESYSTEM - const std::filesystem::path fname_path(fname_string.begin(), fname_string.end()); - const auto filesystem_path = toml::parse(fname_path); - BOOST_TEST_MESSAGE("path"); + (void) [](const std::filesystem::path& that) -> result_type { return toml::parse(that); }; + (void) [](std::filesystem::path& that) -> result_type { return toml::parse(that); }; + (void) [](std::filesystem::path&& that) -> result_type { return toml::parse(that); }; #endif + (void) [](std::FILE* that) -> result_type { return toml::parse(that, "mandatory.toml"); }; } BOOST_AUTO_TEST_CASE(test_parse_nonexistent_file) diff --git a/tests/test_parse_floating.cpp b/tests/test_parse_floating.cpp index 15f433d..5c05bab 100644 --- a/tests/test_parse_floating.cpp +++ b/tests/test_parse_floating.cpp @@ -1,14 +1,10 @@ -#define BOOST_TEST_MODULE "parse_floating_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" +#include + using namespace toml; using namespace detail; diff --git a/tests/test_parse_inline_table.cpp b/tests/test_parse_inline_table.cpp index 5fa99c1..9217a23 100644 --- a/tests/test_parse_inline_table.cpp +++ b/tests/test_parse_inline_table.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_inline_table_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_integer.cpp b/tests/test_parse_integer.cpp index 8e73686..423961f 100644 --- a/tests/test_parse_integer.cpp +++ b/tests/test_parse_integer.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_integer_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_key.cpp b/tests/test_parse_key.cpp index f05c26b..3af0eaa 100644 --- a/tests/test_parse_key.cpp +++ b/tests/test_parse_key.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_key_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_string.cpp b/tests/test_parse_string.cpp index 5367c00..bf381e3 100644 --- a/tests/test_parse_string.cpp +++ b/tests/test_parse_string.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_string_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_table.cpp b/tests/test_parse_table.cpp index cb5baee..0fd54c7 100644 --- a/tests/test_parse_table.cpp +++ b/tests/test_parse_table.cpp @@ -1,12 +1,7 @@ -#define BOOST_TEST_MODULE "parse_table_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif -#include #include +#include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_table_key.cpp b/tests/test_parse_table_key.cpp index 47df434..a921c96 100644 --- a/tests/test_parse_table_key.cpp +++ b/tests/test_parse_table_key.cpp @@ -1,11 +1,6 @@ -#define BOOST_TEST_MODULE "parse_table_key_test" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" #include "test_parse_aux.hpp" using namespace toml; diff --git a/tests/test_parse_unicode.cpp b/tests/test_parse_unicode.cpp index e3797a6..8bc4253 100644 --- a/tests/test_parse_unicode.cpp +++ b/tests/test_parse_unicode.cpp @@ -1,17 +1,13 @@ -#define BOOST_TEST_MODULE "test_parse_unicode" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include + +#include "unit_test.hpp" + #include +#include BOOST_AUTO_TEST_CASE(test_hard_example_unicode) { - const auto data = toml::parse("toml/tests/hard_example_unicode.toml"); + const auto data = toml::parse(testinput("hard_example_unicode.toml")); const auto the = toml::find(data, "the"); BOOST_TEST(toml::get(the.at("test_string")) == diff --git a/tests/test_result.cpp b/tests/test_result.cpp index d693bd6..ad5084c 100644 --- a/tests/test_result.cpp +++ b/tests/test_result.cpp @@ -1,8 +1,9 @@ -#define BOOST_TEST_MODULE "test_result" -#include -#include #include +#include "unit_test.hpp" + +#include + BOOST_AUTO_TEST_CASE(test_construct) { { @@ -437,5 +438,3 @@ BOOST_AUTO_TEST_CASE(test_and_or_other) BOOST_TEST("foo" == r1_gen().and_other(r2_gen()).unwrap_err()); } } - - diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 7e1d8e1..b6b8acb 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -1,15 +1,11 @@ -#define BOOST_TEST_MODULE "test_serialize_file" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + #include -#include -#include #include +#include +#include #include template& v) BOOST_AUTO_TEST_CASE(test_example) { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); { std::ofstream ofs("tmp1.toml"); ofs << std::setw(80) << data; @@ -69,7 +65,7 @@ BOOST_AUTO_TEST_CASE(test_example) BOOST_AUTO_TEST_CASE(test_example_map_dq) { const auto data = toml::parse( - "toml/tests/example.toml"); + testinput("example.toml")); { std::ofstream ofs("tmp1_map_dq.toml"); ofs << std::setw(80) << data; @@ -91,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_example_map_dq) BOOST_AUTO_TEST_CASE(test_example_with_comment) { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); { std::ofstream ofs("tmp1_com.toml"); ofs << std::setw(80) << data; @@ -117,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment) BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) { { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); { std::ofstream ofs("tmp1_com_nocomment.toml"); ofs << std::setw(80) << toml::nocomment << data; @@ -127,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) BOOST_TEST(!has_comment_inside(serialized)); } { - const auto data_nocomment = toml::parse("toml/tests/example.toml"); + const auto data_nocomment = toml::parse(testinput("example.toml")); auto serialized = toml::parse("tmp1_com_nocomment.toml"); { auto& owner = toml::find(serialized, "owner"); @@ -146,7 +142,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) { const auto data = toml::parse( - "toml/tests/example.toml"); + testinput("example.toml")); { std::ofstream ofs("tmp1_com_map_dq.toml"); ofs << std::setw(80) << data; @@ -173,7 +169,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) { { - const auto data = toml::parse("toml/tests/example.toml"); + const auto data = toml::parse(testinput("example.toml")); { std::ofstream ofs("tmp1_com_map_dq_nocomment.toml"); ofs << std::setw(80) << toml::nocomment << data; @@ -182,7 +178,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) BOOST_TEST(!has_comment_inside(serialized)); } { - const auto data_nocomment = toml::parse("toml/tests/example.toml"); + const auto data_nocomment = toml::parse(testinput("example.toml")); auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); { auto& owner = toml::find(serialized, "owner"); @@ -199,7 +195,7 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) BOOST_AUTO_TEST_CASE(test_fruit) { - const auto data = toml::parse("toml/tests/fruit.toml"); + const auto data = toml::parse(testinput("fruit.toml")); { std::ofstream ofs("tmp2.toml"); ofs << std::setw(80) << data; @@ -211,7 +207,7 @@ BOOST_AUTO_TEST_CASE(test_fruit) BOOST_AUTO_TEST_CASE(test_fruit_map_dq) { const auto data = toml::parse( - "toml/tests/fruit.toml"); + testinput("fruit.toml")); { std::ofstream ofs("tmp2.toml"); ofs << std::setw(80) << data; @@ -223,7 +219,7 @@ BOOST_AUTO_TEST_CASE(test_fruit_map_dq) BOOST_AUTO_TEST_CASE(test_fruit_with_comments) { - const auto data = toml::parse("toml/tests/fruit.toml"); + const auto data = toml::parse(testinput("fruit.toml")); { std::ofstream ofs("tmp2_com.toml"); ofs << std::setw(80) << data; @@ -235,7 +231,7 @@ BOOST_AUTO_TEST_CASE(test_fruit_with_comments) BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq) { const auto data = toml::parse( - "toml/tests/fruit.toml"); + testinput("fruit.toml")); { std::ofstream ofs("tmp2_com.toml"); ofs << std::setw(80) << data; @@ -246,7 +242,7 @@ BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq) BOOST_AUTO_TEST_CASE(test_hard_example) { - const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto data = toml::parse(testinput("hard_example.toml")); { std::ofstream ofs("tmp3.toml"); ofs << std::setw(80) << data; @@ -258,7 +254,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example) BOOST_AUTO_TEST_CASE(test_hard_example_map_dq) { const auto data = toml::parse( - "toml/tests/hard_example.toml"); + testinput("hard_example.toml")); { std::ofstream ofs("tmp3.toml"); ofs << std::setw(80) << data; @@ -271,7 +267,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_map_dq) BOOST_AUTO_TEST_CASE(test_hard_example_with_comment) { const auto data = toml::parse( - "toml/tests/hard_example.toml"); + testinput("hard_example.toml")); { std::ofstream ofs("tmp3_com.toml"); ofs << std::setw(80) << data; diff --git a/tests/test_string.cpp b/tests/test_string.cpp index 444fc63..e3f093a 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -1,7 +1,7 @@ -#define BOOST_TEST_MODULE "test_string" -#include #include +#include "unit_test.hpp" + BOOST_AUTO_TEST_CASE(test_basic_string) { { @@ -151,4 +151,3 @@ BOOST_AUTO_TEST_CASE(test_string_add_assign) } - diff --git a/tests/test_traits.cpp b/tests/test_traits.cpp index 63b8a14..4d5e3e2 100644 --- a/tests/test_traits.cpp +++ b/tests/test_traits.cpp @@ -1,21 +1,16 @@ -#define BOOST_TEST_MODULE "test_traits" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include -#include -#include +#include "unit_test.hpp" + #include +#include +#include +#include #include #include +#include #include #include -#include struct dummy_type{}; diff --git a/tests/test_utility.cpp b/tests/test_utility.cpp index 6919399..c67e3b8 100644 --- a/tests/test_utility.cpp +++ b/tests/test_utility.cpp @@ -1,13 +1,9 @@ -#define BOOST_TEST_MODULE "test_acceptor" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include -#include + +#include "unit_test.hpp" + #include +#include BOOST_AUTO_TEST_CASE(test_try_reserve) { diff --git a/tests/test_value.cpp b/tests/test_value.cpp index 099d502..296d343 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -1,11 +1,7 @@ -#define BOOST_TEST_MODULE "test_value" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif #include + +#include "unit_test.hpp" + #include #include diff --git a/tests/unit_test.hpp b/tests/unit_test.hpp new file mode 100644 index 0000000..5999f57 --- /dev/null +++ b/tests/unit_test.hpp @@ -0,0 +1,23 @@ +#ifndef BOOST_TEST_MODULE +# error "Please #define BOOST_TEST_MODULE before you #include " +#endif + +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +# include +#else +# include +#endif + +#include +#include + +static inline auto testinput(const std::string& basename) -> std::string +{ + const auto this_or_that = [](const char *const s, const char *const t) { return s ? s : t; }; + std::string directory = this_or_that(std::getenv("TOMLDIR"), "toml"); + if (!directory.empty() && directory.back() != '/') + { + directory.push_back('/'); + } + return directory.append("tests/").append(basename); +} diff --git a/toml/comments.hpp b/toml/comments.hpp index ec25041..c0f66f3 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -425,14 +425,14 @@ struct discard_comments // empty, so accessing through operator[], front/back, data causes address // error. - reference operator[](const size_type) noexcept {return *data();} - const_reference operator[](const size_type) const noexcept {return *data();} + reference operator[](const size_type) noexcept {never_call("toml::discard_comment::operator[]");} + const_reference operator[](const size_type) const noexcept {never_call("toml::discard_comment::operator[]");} reference at(const size_type) {throw std::out_of_range("toml::discard_comment is always empty.");} const_reference at(const size_type) const {throw std::out_of_range("toml::discard_comment is always empty.");} - reference front() noexcept {return *data();} - const_reference front() const noexcept {return *data();} - reference back() noexcept {return *data();} - const_reference back() const noexcept {return *data();} + reference front() noexcept {never_call("toml::discard_comment::front");} + const_reference front() const noexcept {never_call("toml::discard_comment::front");} + reference back() noexcept {never_call("toml::discard_comment::back");} + const_reference back() const noexcept {never_call("toml::discard_comment::back");} pointer data() noexcept {return nullptr;} const_pointer data() const noexcept {return nullptr;} @@ -450,6 +450,18 @@ struct discard_comments const_reverse_iterator rend() const noexcept {return const_iterator{};} const_reverse_iterator crbegin() const noexcept {return const_iterator{};} const_reverse_iterator crend() const noexcept {return const_iterator{};} + + private: + + [[noreturn]] static void never_call(const char *const this_function) + { +#ifdef __has_builtin +# if __has_builtin(__builtin_unreachable) + __builtin_unreachable(); +# endif +#endif + throw std::logic_error{this_function}; + } }; inline bool operator==(const discard_comments&, const discard_comments&) noexcept {return true;} diff --git a/toml/datetime.hpp b/toml/datetime.hpp index 36db1e1..83d04ba 100644 --- a/toml/datetime.hpp +++ b/toml/datetime.hpp @@ -85,9 +85,9 @@ enum class month_t : std::uint8_t struct local_date { - std::int16_t year; // A.D. (like, 2018) - std::uint8_t month; // [0, 11] - std::uint8_t day; // [1, 31] + std::int16_t year{}; // A.D. (like, 2018) + std::uint8_t month{}; // [0, 11] + std::uint8_t day{}; // [1, 31] local_date(int y, month_t m, int d) : year (static_cast(y)), @@ -181,12 +181,12 @@ operator<<(std::basic_ostream& os, const local_date& date) struct local_time { - std::uint8_t hour; // [0, 23] - std::uint8_t minute; // [0, 59] - std::uint8_t second; // [0, 60] - std::uint16_t millisecond; // [0, 999] - std::uint16_t microsecond; // [0, 999] - std::uint16_t nanosecond; // [0, 999] + std::uint8_t hour{}; // [0, 23] + std::uint8_t minute{}; // [0, 59] + std::uint8_t second{}; // [0, 60] + std::uint16_t millisecond{}; // [0, 999] + std::uint16_t microsecond{}; // [0, 999] + std::uint16_t nanosecond{}; // [0, 999] local_time(int h, int m, int s, int ms = 0, int us = 0, int ns = 0) @@ -297,8 +297,8 @@ operator<<(std::basic_ostream& os, const local_time& time) struct time_offset { - std::int8_t hour; // [-12, 12] - std::int8_t minute; // [-59, 59] + std::int8_t hour{}; // [-12, 12] + std::int8_t minute{}; // [-59, 59] time_offset(int h, int m) : hour (static_cast(h)), @@ -364,8 +364,8 @@ operator<<(std::basic_ostream& os, const time_offset& offset) struct local_datetime { - local_date date; - local_time time; + local_date date{}; + local_time time{}; local_datetime(local_date d, local_time t): date(d), time(t) {} @@ -478,9 +478,9 @@ operator<<(std::basic_ostream& os, const local_datetime& dt) struct offset_datetime { - local_date date; - local_time time; - time_offset offset; + local_date date{}; + local_time time{}; + time_offset offset{}; offset_datetime(local_date d, local_time t, time_offset o) : date(d), time(t), offset(o) diff --git a/toml/parser.hpp b/toml/parser.hpp index 4d59f0a..590cb2a 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -2414,12 +2414,14 @@ parse(std::vector& letters, const std::string& fname) } } - const auto data = detail::parse_toml_file(loc); - if(!data) + if (auto data = detail::parse_toml_file(loc)) { - throw syntax_error(data.unwrap_err(), source_location(loc)); + return std::move(data).unwrap(); + } + else + { + throw syntax_error(std::move(data).unwrap_err(), source_location(loc)); } - return data.unwrap(); } } // detail diff --git a/toml/region.hpp b/toml/region.hpp index 2e01e51..8c4f2f1 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -227,8 +227,7 @@ struct region final : public region_base region& operator+=(const region& other) { // different regions cannot be concatenated - assert(this->begin() == other.begin() && this->end() == other.end() && - this->last_ == other.first_); + assert(this->source_ == other.source_ && this->last_ == other.first_); this->last_ = other.last_; return *this;