diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index 47b6489..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,299 +0,0 @@ -include(ExternalProject) - -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 - test_string - test_utility - test_result - test_traits - test_value - test_lex_boolean - test_lex_integer - test_lex_floating - test_lex_datetime - test_lex_string - test_lex_key_comment - test_parse_boolean - test_parse_integer - test_parse_floating - test_parse_string - test_parse_datetime - test_parse_array - test_parse_table - test_parse_inline_table - test_parse_key - test_parse_table_key - test_literals - test_comments - test_get - test_get_or - test_find - test_find_or - test_find_or_recursive - test_expect - test_parse_file - test_serialize_file - test_parse_unicode - test_error_detection - test_format_error - test_extended_conversions -) - -include(CheckCXXCompilerFlag) - -CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL) -CHECK_CXX_COMPILER_FLAG("-Wextra" COMPILER_SUPPORTS_WEXTRA) -CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC) -CHECK_CXX_COMPILER_FLAG("-Werror" COMPILER_SUPPORTS_WERROR) - -CHECK_CXX_COMPILER_FLAG("-Wsign-conversion" COMPILER_SUPPORTS_WSIGN_CONVERSION) -CHECK_CXX_COMPILER_FLAG("-Wconversion" COMPILER_SUPPORTS_WCONVERSION) -CHECK_CXX_COMPILER_FLAG("-Wduplicated-cond" COMPILER_SUPPORTS_WDUPLICATED_COND) -CHECK_CXX_COMPILER_FLAG("-Wduplicated-branches" COMPILER_SUPPORTS_WDUPLICATED_BRANCHES) -CHECK_CXX_COMPILER_FLAG("-Wlogical-op" COMPILER_SUPPORTS_WLOGICAL_OP) -CHECK_CXX_COMPILER_FLAG("-Wuseless-cast" COMPILER_SUPPORTS_WUSELESS_CAST) -CHECK_CXX_COMPILER_FLAG("-Wdouble-promotion" COMPILER_SUPPORTS_WDOUBLE_PROMOTION) -CHECK_CXX_COMPILER_FLAG("-Wrange-loop-analysis" COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) -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}") -set(PREVIOUSLY_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - -list(APPEND CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIRS}) -list(APPEND CMAKE_REQUIRED_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -if(APPLE) - list(APPEND CMAKE_REQUIRED_FLAGS "-std=c++11") -endif() - -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}") -set(CMAKE_REQUIRED_FLAGS "${PREVIOUSLY_REQUIRED_FLAGS}") - -unset(PREVIOUSLY_REQUIRED_INCLUDES) -unset(PREVIOUSLY_REQUIRED_LIBRARIES) -unset(PREVIOUSLY_REQUIRED_FLAGS) - -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() -if(COMPILER_SUPPORTS_WEXTRA) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") -endif() -if(COMPILER_SUPPORTS_WPEDANTIC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") -endif() -if(COMPILER_SUPPORTS_WERROR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") -endif() -if(COMPILER_SUPPORTS_WSHADOW) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow") -endif() -if(COMPILER_SUPPORTS_WSIGN_CONVERSION) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-conversion") -endif() -if(COMPILER_SUPPORTS_WCONVERSION) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconversion") -endif() -if(COMPILER_SUPPORTS_WDUPLICATED_COND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-cond") -endif() -if(COMPILER_SUPPORTS_WDUPLICATED_BRANCHES) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-branches") -endif() -if(COMPILER_SUPPORTS_WLOGICAL_OP) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlogical-op") -endif() -if(COMPILER_SUPPORTS_WUSELESS_CAST) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuseless-cast") -endif() -if(COMPILER_SUPPORTS_WDOUBLE_PROMOTION) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion") -endif() -if(COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wrange-loop-analysis") -endif() -if(COMPILER_SUPPORTS_WUNDEF) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wundef") -endif() - -if(TOML11_USE_UNRELEASED_TOML_FEATURES) - message(STATUS "adding TOML11_USE_UNRELEASED_TOML_FEATURES flag") - add_definitions("-DTOML11_USE_UNRELEASED_TOML_FEATURES") -endif() - -# Disable some MSVC warnings -if(MSVC) - # conversion from 'double' to 'unsigned int', possible loss of data - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244") - # conversion from 'int' to 'unsigned int', signed/unsigned mismatch - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4365") - # layout of class may have changed from a previous version of the compiler - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4371") - # enumerator in switch of enum is not explicitly handled by a case label - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4061") - # unreferenced inline function has been removed - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4514") - # constructor is not implicitly called - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4582") - # destructor is not implicitly called - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4583") - # pragma warning: there is no warning number - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4619") - # default constructor was implicitly defined as deleted - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4623") - # copy constructor was implicitly defined as deleted - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4625") - # assignment operator was implicitly defined as deleted - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4626") - # move assignment operator was implicitly defined as deleted - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4627") - # is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4668") - # function not inlined - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4710") - # function selected for automatic inlining - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4711") - # bytes padding added after data member - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4820") - # pragma warning(pop): likely mismatch, popping warning state pushed in different file - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd5031") - # pragma warning(pop): spectre warnings in tests - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd5045") - # pragma warning(pop): spectre warnings in tests - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4265") -endif() - -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) - if(TOML11_WITH_LIBCXX_LIBRARY) - target_link_libraries(${TEST_NAME} "c++fs") - else() - target_link_libraries(${TEST_NAME} "stdc++fs") - endif() - endif() - - target_include_directories(${TEST_NAME} PRIVATE ${Boost_INCLUDE_DIRS}) - - if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - if(toml11_TEST_WITH_ASAN) - set_target_properties(${TEST_NAME} PROPERTIES - COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer" - LINK_FLAGS "-fsanitize=address -fno-omit-frame-pointer") - elseif(toml11_TEST_WITH_UBSAN) - set_target_properties(${TEST_NAME} PROPERTIES - COMPILE_FLAGS "-fsanitize=undefined" - LINK_FLAGS "-fsanitize=undefined") - endif() - endif() - - add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "${TEST_ENVIRON}") -endforeach(TEST_NAME) - - -# this test is to check it compiles. it will not run -add_executable(test_multiple_translation_unit - test_multiple_translation_unit_1.cpp - test_multiple_translation_unit_2.cpp) -target_link_libraries(test_multiple_translation_unit toml11::toml11) - -if(WIN32) - add_executable(test_windows test_windows.cpp) - target_link_libraries(test_windows toml11::toml11) -endif() - diff --git a/tests/check.cpp b/tests/check.cpp deleted file mode 100644 index bf67775..0000000 --- a/tests/check.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include - -#include -#include - -int main(int argc, char **argv) -{ - if(argc != 3) - { - std::cerr << "usage: ./check [filename] [valid|invalid]" << std::endl; - return 1; - } - - const std::string file_kind(argv[2]); - - try - { - const auto data = toml::parse(argv[1]); - std::cout << std::setprecision(16) << std::setw(80) << data; - if(file_kind == "valid") - { - return 0; - } - else - { - return 1; - } - } - catch(const toml::syntax_error& err) - { - std::cout << "what(): " << err.what() << std::endl; - if(file_kind == "invalid") - { - return 0; - } - else - { - return 1; - } - } - return 127; -} diff --git a/tests/check_serialization.cpp b/tests/check_serialization.cpp deleted file mode 100644 index e97d51b..0000000 --- a/tests/check_serialization.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include - -#include -#include - -int main(int argc, char **argv) -{ - if(argc != 2) - { - std::cerr << "usage: ./check [filename]" << std::endl; - return 1; - } - - const std::string filename(argv[1]); - - { - const auto data = toml::parse(filename); - { - std::ofstream ofs("tmp.toml"); - ofs << std::setprecision(16) << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp.toml"); - - if(data != serialized) - { - // this is really a ditry hack, but is the easiest way... - // TODO: cleanup by adding comparison function to check if a value is NaN or not - if(filename.substr(filename.size() - 22, 22) == "float-inf-and-nan.toml" && - std::isnan (toml::find(serialized, "nan")) && - !std::signbit (toml::find(serialized, "nan")) && - std::isnan (toml::find(serialized, "nan_plus")) && - !std::signbit (toml::find(serialized, "nan_plus")) && - std::isnan (toml::find(serialized, "nan_neg")) && - std::signbit (toml::find(serialized, "nan_neg")) && - !std::isnan (toml::find(serialized, "infinity")) && - !std::isfinite(toml::find(serialized, "infinity")) && - !std::signbit (toml::find(serialized, "infinity")) && - !std::isnan (toml::find(serialized, "infinity_plus")) && - !std::isfinite(toml::find(serialized, "infinity_plus")) && - !std::signbit (toml::find(serialized, "infinity_plus")) && - !std::isnan (toml::find(serialized, "infinity_neg")) && - !std::isfinite(toml::find(serialized, "infinity_neg")) && - std::signbit (toml::find(serialized, "infinity_neg"))) - { - // then it is correctly serialized. - // Note that, the result of (nan == nan) is false. so `data == serialized` is false. - } - else - { - std::cerr << "============================================================\n"; - std::cerr << "result (w/o comment) different: " << filename << std::endl; - std::cerr << "------------------------------------------------------------\n"; - std::cerr << "# serialized\n"; - std::cerr << serialized; - std::cerr << "------------------------------------------------------------\n"; - std::cerr << "# data\n"; - std::cerr << data; - return 1; - } - } - } - { - const auto data = toml::parse(filename); - { - std::ofstream ofs("tmp.toml"); - ofs << std::setprecision(16) << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp.toml"); - if(data != serialized) - { - // this is really a ditry hack, but is the easiest way... - // TODO: cleanup by adding comparison function to check if a value is NaN or not - if(filename.substr(filename.size() - 22, 22) == "float-inf-and-nan.toml" && - std::isnan (toml::find(serialized, "nan")) && - !std::signbit (toml::find(serialized, "nan")) && - std::isnan (toml::find(serialized, "nan_plus")) && - !std::signbit (toml::find(serialized, "nan_plus")) && - std::isnan (toml::find(serialized, "nan_neg")) && - std::signbit (toml::find(serialized, "nan_neg")) && - !std::isnan (toml::find(serialized, "infinity")) && - !std::isfinite(toml::find(serialized, "infinity")) && - !std::signbit (toml::find(serialized, "infinity")) && - !std::isnan (toml::find(serialized, "infinity_plus")) && - !std::isfinite(toml::find(serialized, "infinity_plus")) && - !std::signbit (toml::find(serialized, "infinity_plus")) && - !std::isnan (toml::find(serialized, "infinity_neg")) && - !std::isfinite(toml::find(serialized, "infinity_neg")) && - std::signbit (toml::find(serialized, "infinity_neg")) && - toml::find(data, "nan").comments() == toml::find(serialized, "nan").comments() && - toml::find(data, "nan_plus").comments() == toml::find(serialized, "nan_plus").comments() && - toml::find(data, "nan_neg").comments() == toml::find(serialized, "nan_neg").comments() && - toml::find(data, "infinity").comments() == toml::find(serialized, "infinity").comments() && - toml::find(data, "infinity_plus").comments() == toml::find(serialized, "infinity_plus").comments() && - toml::find(data, "infinity_neg").comments() == toml::find(serialized, "infinity_neg").comments() ) - { - // then it is correctly serialized. - // Note that, the result of (nan == nan) is false. so `data == serialized` is false. - } - else - { - std::cerr << "============================================================\n"; - std::cerr << "result (w/ comment) different: " << filename << std::endl; - std::cerr << "------------------------------------------------------------\n"; - std::cerr << "# serialized\n"; - std::cerr << serialized; - std::cerr << "------------------------------------------------------------\n"; - std::cerr << "# data\n"; - std::cerr << data; - return 1; - } - } - } - return 0; -} diff --git a/tests/check_toml_test.cpp b/tests/check_toml_test.cpp deleted file mode 100644 index 51404c9..0000000 --- a/tests/check_toml_test.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include - -#include -#include - -struct json_serializer -{ - void operator()(toml::boolean v) - { - std::cout << "{\"type\":\"bool\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(toml::integer v) - { - std::cout << "{\"type\":\"integer\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(toml::floating v) - { - if(std::isnan(v) && std::signbit(v)) - { - // toml-test does not allow negative NaN represented in "-nan" because - // there are languages that does not distinguish nan and -nan. - // But toml11 keeps sign from input. To resolve this difference, - // we convert -nan to nan here. - v = std::numeric_limits::quiet_NaN(); - } - std::cout << "{\"type\":\"float\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(const toml::string& v) - { - // since toml11 automatically convert string to multiline string that is - // valid only in TOML, we need to format the string to make it valid in - // JSON. - toml::serializer ser(std::numeric_limits::max()); - std::cout << "{\"type\":\"string\",\"value\":" - << ser(v.str) << "}"; - return ; - } - void operator()(const toml::local_time& v) - { - std::cout << "{\"type\":\"time-local\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(const toml::local_date& v) - { - std::cout << "{\"type\":\"date-local\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(const toml::local_datetime& v) - { - std::cout << "{\"type\":\"datetime-local\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(const toml::offset_datetime& v) - { - std::cout << "{\"type\":\"datetime\",\"value\":\"" << toml::value(v) << "\"}"; - return ; - } - void operator()(const toml::array& v) - { - if(!v.empty() && v.front().is_table()) - { - std::cout << '['; - bool is_first = true; - for(const auto& elem : v) - { - if(!is_first) {std::cout << ", ";} - is_first = false; - toml::visit(*this, elem); - } - std::cout << ']'; - } - else - { -// std::cout << "{\"type\":\"array\",\"value\":["; - std::cout << "["; - bool is_first = true; - for(const auto& elem : v) - { - if(!is_first) {std::cout << ", ";} - is_first = false; - toml::visit(*this, elem); - } - std::cout << "]"; - } - return ; - } - void operator()(const toml::table& v) - { - std::cout << '{'; - bool is_first = true; - for(const auto& elem : v) - { - if(!is_first) {std::cout << ", ";} - is_first = false; - const auto k = toml::format_key(elem.first); - if(k.at(0) == '"') - { - std::cout << k << ":"; - } - else // bare key - { - std::cout << '\"' << k << "\":"; - } - toml::visit(*this, elem.second); - } - std::cout << '}'; - return ; - } -}; - -int main() -{ - try - { - std::vector buf; - std::cin.peek(); - while(!std::cin.eof()) - { - buf.push_back(std::cin.get()); - std::cin.peek(); - } - std::string bufstr(buf.begin(), buf.end()); - - std::istringstream ss(bufstr); - - const auto data = toml::parse(ss); - std::cout << std::setprecision(std::numeric_limits::max_digits10); - toml::visit(json_serializer(), data); - return 0; - } - catch(const toml::syntax_error& err) - { - std::cout << "what(): " << err.what() << std::endl; - return 1; - } -} diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 5b9116d..c59a1b2 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -1,545 +1,21 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + #include -#include "unit_test.hpp" - -BOOST_AUTO_TEST_CASE(test_comment_before) +TEST_CASE("testing comments on simple value") { - { - const std::string file = R"( - # comment for a. - a = 42 - # comment for b. - b = "baz" - )"; - std::istringstream iss(file); - const auto v = toml::parse(iss); + const toml::value root = toml::parse_str(R"( + # comment 1 + # comment 2 + a = "foo" # comment 3 - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - - BOOST_TEST(a.comments().size() == 1u); - BOOST_TEST(a.comments().front() == " comment for a."); - BOOST_TEST(b.comments().size() == 1u); - BOOST_TEST(b.comments().front() == " comment for b."); - } - { - const std::string file = R"( - # comment for a. - # another comment for a. - a = 42 - # comment for b. - # also comment for b. - b = "baz" - )"; - - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - - BOOST_TEST(a.comments().size() == 2u); - BOOST_TEST(a.comments().front() == " comment for a."); - BOOST_TEST(a.comments().back() == " another comment for a."); - BOOST_TEST(b.comments().size() == 2u); - BOOST_TEST(b.comments().front() == " comment for b."); - BOOST_TEST(b.comments().back() == " also comment for b."); - } -} - -BOOST_AUTO_TEST_CASE(test_comment_inline) -{ - { - const std::string file = R"( - a = 42 # comment for a. - b = "baz" # comment for b. - )"; - - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - - BOOST_TEST(a.comments().size() == 1u); - BOOST_TEST(a.comments().front() == " comment for a."); - BOOST_TEST(b.comments().size() == 1u); - BOOST_TEST(b.comments().front() == " comment for b."); - } - { - const std::string file = R"( - a = [ - 42, - ] # comment for a. - b = [ - "bar", # this is not a comment for b, but "bar" - ] # this is a comment for b. - )"; - - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - const auto b0 = b.as_array().at(0); - - BOOST_TEST(a.comments().size() == 1u); - BOOST_TEST(a.comments().front() == " comment for a."); - BOOST_TEST(b.comments().size() == 1u); - BOOST_TEST(b.comments().front() == " this is a comment for b."); - BOOST_TEST(b0.comments().size() == 1u); - BOOST_TEST(b0.comments().front() == " this is not a comment for b, but \"bar\""); - } -} - -BOOST_AUTO_TEST_CASE(test_comment_both) -{ - { - const std::string file = R"( - # comment for a. - a = 42 # inline comment for a. - # comment for b. - b = "baz" # inline comment for b. - # comment for c. - c = [ # this comment will be ignored - # comment for the first element. - 10 # this also. - ] # another comment for c. - )"; - - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - const auto c = toml::find(v, "c"); - const auto c0 = c.as_array().at(0); - - BOOST_TEST(a.comments().size() == 2u); - BOOST_TEST(a.comments().front() == " comment for a."); - BOOST_TEST(a.comments().back() == " inline comment for a."); - BOOST_TEST(b.comments().size() == 2u); - BOOST_TEST(b.comments().front() == " comment for b."); - BOOST_TEST(b.comments().back() == " inline comment for b."); - - BOOST_TEST(c.comments().size() == 2u); - BOOST_TEST(c.comments().front() == " comment for c."); - BOOST_TEST(c.comments().back() == " another comment for c."); - - BOOST_TEST(c0.comments().size() == 2u); - BOOST_TEST(c0.comments().front() == " comment for the first element."); - BOOST_TEST(c0.comments().back() == " this also."); - } -} - -BOOST_AUTO_TEST_CASE(test_comments_on_implicit_values) -{ - { - const std::string file = R"( - # comment for the first element of array-of-tables. - [[array-of-tables]] - foo = "bar" - )"; - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto aot = toml::find(v, "array-of-tables"); - const auto elm = aot.at(0); - BOOST_TEST(aot.comments().empty()); - BOOST_TEST(elm.comments().size() == 1); - BOOST_TEST(elm.comments().front() == " comment for the first element of array-of-tables."); - } - { - const std::string file = R"( - # comment for the array itself - array-of-tables = [ - # comment for the first element of array-of-tables. - {foo = "bar"} - ] - )"; - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto aot = toml::find(v, "array-of-tables"); - const auto elm = aot.at(0); - BOOST_TEST(aot.comments().size() == 1); - BOOST_TEST(aot.comments().front() == " comment for the array itself"); - BOOST_TEST(elm.comments().size() == 1); - BOOST_TEST(elm.comments().front() == " comment for the first element of array-of-tables."); - } -} - -BOOST_AUTO_TEST_CASE(test_discard_comment) -{ - const std::string file = R"( - # comment for a. - a = 42 # inline comment for a. - # comment for b. - b = "baz" # inline comment for b. - # comment for c. - c = [ # this comment will be ignored - # comment for the first element. - 10 # this also. - ] # another comment for c. - )"; - - std::istringstream iss(file); - const auto v = toml::parse(iss); - - const auto a = toml::find(v, "a"); - const auto b = toml::find(v, "b"); - const auto c = toml::find(v, "c"); - const auto c0 = c.as_array().at(0); - - BOOST_TEST(a.comments().empty()); - BOOST_TEST(b.comments().empty()); - BOOST_TEST(c.comments().empty()); - BOOST_TEST(c0.comments().empty()); -} - -BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) -{ - using value_type = toml::basic_value; - { - const value_type v(true, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_boolean()); - BOOST_TEST(v.as_boolean() == true); - } - { - const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_integer()); - BOOST_TEST(v.as_integer() == 42); - } - { - const value_type v(3.14, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_floating()); - BOOST_TEST(v.as_floating() == 3.14); - } - { - const value_type v(toml::string("str"), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } - { - const value_type v(std::string("str"), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } - { - const value_type v(std::string("str"), toml::string_t::literal, - {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } - { - const value_type v("str", {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } - { - const value_type v("str", toml::string_t::literal, - {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L - { - using namespace std::literals::string_view_literals; - const value_type v("str"sv, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } - { - using namespace std::literals::string_view_literals; - const value_type v("str"sv, toml::string_t::literal, - {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_string()); - BOOST_TEST(v.as_string() == "str"); - } -#endif - const toml::local_date ld{2019, toml::month_t::Apr, 1}; - const toml::local_time lt{12, 30, 45}; - const toml::local_datetime ldt{ld, lt}; - const toml::offset_datetime odt{ld, lt, toml::time_offset{9, 0}}; - { - const value_type v(ld, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_local_date()); - BOOST_TEST(v.as_local_date() == ld); - } - { - const value_type v(lt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_local_time()); - BOOST_TEST(v.as_local_time() == lt); - } - { - const toml::local_time three_hours{3,0,0}; - const value_type v(std::chrono::hours(3), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_local_time()); - BOOST_TEST(v.as_local_time() == three_hours); - } - { - const value_type v(ldt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_local_datetime()); - BOOST_TEST(v.as_local_datetime() == ldt); - } - { - const value_type v(odt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_offset_datetime()); - BOOST_TEST(v.as_offset_datetime() == odt); - } - { - const auto systp = static_cast(odt); - const value_type v(systp, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_offset_datetime()); - - // While the conversion, the information about time offset may change. - const auto systp2 = static_cast( - v.as_offset_datetime()); - const bool result = systp == systp2; // because there is no operator<< - BOOST_TEST(result); - } - { - const typename value_type::array_type a{1,2,3,4,5}; - const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_array()); - BOOST_TEST(v.as_array().at(0).is_integer()); - BOOST_TEST(v.as_array().at(1).is_integer()); - BOOST_TEST(v.as_array().at(2).is_integer()); - BOOST_TEST(v.as_array().at(3).is_integer()); - BOOST_TEST(v.as_array().at(4).is_integer()); - BOOST_TEST(v.as_array().at(0).as_integer() == 1); - BOOST_TEST(v.as_array().at(1).as_integer() == 2); - BOOST_TEST(v.as_array().at(2).as_integer() == 3); - BOOST_TEST(v.as_array().at(3).as_integer() == 4); - BOOST_TEST(v.as_array().at(4).as_integer() == 5); - } - { - const std::initializer_list a = {1,2,3,4,5}; - const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_array()); - BOOST_TEST(v.as_array().at(0).is_integer()); - BOOST_TEST(v.as_array().at(1).is_integer()); - BOOST_TEST(v.as_array().at(2).is_integer()); - BOOST_TEST(v.as_array().at(3).is_integer()); - BOOST_TEST(v.as_array().at(4).is_integer()); - BOOST_TEST(v.as_array().at(0).as_integer() == 1); - BOOST_TEST(v.as_array().at(1).as_integer() == 2); - BOOST_TEST(v.as_array().at(2).as_integer() == 3); - BOOST_TEST(v.as_array().at(3).as_integer() == 4); - BOOST_TEST(v.as_array().at(4).as_integer() == 5); - } - { - const std::vector a = {1,2,3,4,5}; - const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_array()); - BOOST_TEST(v.as_array().at(0).is_integer()); - BOOST_TEST(v.as_array().at(1).is_integer()); - BOOST_TEST(v.as_array().at(2).is_integer()); - BOOST_TEST(v.as_array().at(3).is_integer()); - BOOST_TEST(v.as_array().at(4).is_integer()); - BOOST_TEST(v.as_array().at(0).as_integer() == 1); - BOOST_TEST(v.as_array().at(1).as_integer() == 2); - BOOST_TEST(v.as_array().at(2).as_integer() == 3); - BOOST_TEST(v.as_array().at(3).as_integer() == 4); - BOOST_TEST(v.as_array().at(4).as_integer() == 5); - } - { - const typename value_type::table_type t{ - {"key1", 42}, {"key2", "foobar"} - }; - const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_table()); - BOOST_TEST(v.as_table().at("key1").is_integer()); - BOOST_TEST(v.as_table().at("key1").as_integer() == 42); - BOOST_TEST(v.as_table().at("key2").is_string()); - BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); - } - { - const std::initializer_list> t{ - {"key1", 42}, {"key2", "foobar"} - }; - const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_table()); - BOOST_TEST(v.as_table().at("key1").is_integer()); - BOOST_TEST(v.as_table().at("key1").as_integer() == 42); - BOOST_TEST(v.as_table().at("key2").is_string()); - BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); - } - { - const std::map t{ - {"key1", 42}, {"key2", "foobar"} - }; - const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_table()); - BOOST_TEST(v.as_table().at("key1").is_integer()); - BOOST_TEST(v.as_table().at("key1").as_integer() == 42); - BOOST_TEST(v.as_table().at("key2").is_string()); - BOOST_TEST(v.as_table().at("key2").as_string() == "foobar"); - } -} - -BOOST_AUTO_TEST_CASE(test_overwrite_comments) -{ - using value_type = toml::basic_value; - { - const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_integer()); - BOOST_TEST(v.as_integer() == 42); - - const value_type u(v, {"comment3", "comment4"}); - BOOST_TEST(u.comments().size() == 2u); - BOOST_TEST(u.comments().at(0) == "comment3"); - BOOST_TEST(u.comments().at(1) == "comment4"); - BOOST_TEST(u.is_integer()); - BOOST_TEST(u.as_integer() == 42); - } - { - const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_integer()); - BOOST_TEST(v.as_integer() == 42); - - const value_type u(v); - BOOST_TEST(u.comments().size() == 2u); - BOOST_TEST(u.comments().at(0) == "comment1"); - BOOST_TEST(u.comments().at(1) == "comment2"); - BOOST_TEST(u.is_integer()); - BOOST_TEST(u.as_integer() == 42); - } - { - const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2u); - BOOST_TEST(v.comments().at(0) == "comment1"); - BOOST_TEST(v.comments().at(1) == "comment2"); - BOOST_TEST(v.is_integer()); - BOOST_TEST(v.as_integer() == 42); - - const value_type u(v, {}); - BOOST_TEST(u.comments().size() == 0u); - BOOST_TEST(u.is_integer()); - BOOST_TEST(u.as_integer() == 42); - } -} - -BOOST_AUTO_TEST_CASE(test_output_comments) -{ - using value_type = toml::basic_value; - { - const value_type v(42, {"comment1", "comment2"}); - std::ostringstream oss; - oss << v.comments(); - - std::ostringstream ref; - ref << "#comment1\n"; - ref << "#comment2\n"; - - BOOST_TEST(oss.str() == ref.str()); - } - { - const value_type v(42, {"comment1", "comment2"}); - std::ostringstream oss; - - // If v is not a table, toml11 assumes that user is writing something - // like the following. - - oss << "answer = " << v; - - BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); - } - - { - const value_type v(42, {"comment1", "comment2"}); - std::ostringstream oss; - - // If v is not a table, toml11 assumes that user is writing something - // like the following. - - oss << toml::nocomment << "answer = " << v; - - BOOST_TEST(oss.str() == "answer = 42"); - } - - { - const value_type v(42, {"comment1", "comment2"}); - std::ostringstream oss; - - // If v is not a table, toml11 assumes that user is writing something - // like the following. - - oss << toml::nocomment << toml::showcomment << "answer = " << v; - - BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); - } + # comment 4 + )"); + const auto& a = root.at("a"); + CHECK_EQ(a.comments().size(), 3); + CHECK_EQ(a.comments().at(0), "# comment 1"); + CHECK_EQ(a.comments().at(1), "# comment 2"); + CHECK_EQ(a.comments().at(2), "# comment 3"); } diff --git a/tests/test_datetime.cpp b/tests/test_datetime.cpp index bbbcc42..69c58cd 100644 --- a/tests/test_datetime.cpp +++ b/tests/test_datetime.cpp @@ -1,109 +1,110 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include -BOOST_AUTO_TEST_CASE(test_local_date) +TEST_CASE("testing local date") { const toml::local_date date(2018, toml::month_t::Jan, 1); const toml::local_date date1(date); - BOOST_TEST(date == date1); + CHECK(date == date1); const std::chrono::system_clock::time_point tp(date); const toml::local_date date2(tp); - BOOST_TEST(date == date2); + CHECK(date == date2); const toml::local_date date3(2017, toml::month_t::Dec, 31); - BOOST_TEST(date > date3); + CHECK(date > date3); std::ostringstream oss; oss << date; - BOOST_TEST(oss.str() == std::string("2018-01-01")); + CHECK(oss.str() == std::string("2018-01-01")); } -BOOST_AUTO_TEST_CASE(test_local_time) +TEST_CASE("testing local time") { const toml::local_time time(12, 30, 45); const toml::local_time time1(time); - BOOST_TEST(time == time1); + CHECK(time == time1); const std::chrono::nanoseconds dur(time); std::chrono::nanoseconds ns(0); ns += std::chrono::hours (12); ns += std::chrono::minutes(30); ns += std::chrono::seconds(45); - BOOST_TEST(dur.count() == ns.count()); + CHECK(dur.count() == ns.count()); const toml::local_time time3(12, 15, 45); - BOOST_TEST(time > time3); + CHECK(time > time3); { std::ostringstream oss; oss << time; - BOOST_TEST(oss.str() == std::string("12:30:45")); + CHECK(oss.str() == std::string("12:30:45")); } { const toml::local_time time4(12, 30, 45, 123, 456); std::ostringstream oss; oss << time4; - BOOST_TEST(oss.str() == std::string("12:30:45.123456")); + CHECK(oss.str() == std::string("12:30:45.123456")); } } -BOOST_AUTO_TEST_CASE(test_time_offset) +TEST_CASE("testing time offset") { const toml::time_offset time(9, 30); const toml::time_offset time1(time); - BOOST_TEST(time == time1); + CHECK(time == time1); const std::chrono::minutes dur(time); std::chrono::minutes m(0); m += std::chrono::hours (9); m += std::chrono::minutes(30); - BOOST_TEST(dur.count() == m.count()); + CHECK(dur.count() == m.count()); const toml::time_offset time2(9, 0); - BOOST_TEST(time2 < time); + CHECK(time2 < time); std::ostringstream oss; oss << time; - BOOST_TEST(oss.str() == std::string("+09:30")); + CHECK(oss.str() == std::string("+09:30")); } -BOOST_AUTO_TEST_CASE(test_local_datetime) +TEST_CASE("testing local datetime") { const toml::local_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1), toml::local_time(12, 30, 45)); const toml::local_datetime dt1(dt); - BOOST_TEST(dt == dt1); + CHECK(dt == dt1); const std::chrono::system_clock::time_point tp(dt); const toml::local_datetime dt2(tp); - BOOST_TEST(dt == dt2); + CHECK(dt == dt2); std::ostringstream oss; oss << dt; - BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45")); + CHECK(oss.str() == std::string("2018-01-01T12:30:45")); } -BOOST_AUTO_TEST_CASE(test_offset_datetime) +TEST_CASE("testing offset datetime") { const toml::offset_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1), toml::local_time(12, 30, 45), toml::time_offset(9, 30)); const toml::offset_datetime dt1(dt); - BOOST_TEST(dt == dt1); + CHECK(dt == dt1); const std::chrono::system_clock::time_point tp1(dt); const toml::offset_datetime dt2(tp1); const std::chrono::system_clock::time_point tp2(dt2); const bool tp_same = (tp1 == tp2); - BOOST_TEST(tp_same); + CHECK(tp_same); { std::ostringstream oss; oss << dt; - BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45+09:30")); + CHECK(oss.str() == std::string("2018-01-01T12:30:45+09:30")); } { const toml::offset_datetime dt3( @@ -112,6 +113,6 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime) toml::time_offset(0, 0)); std::ostringstream oss; oss << dt3; - BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45Z")); + CHECK(oss.str() == std::string("2018-01-01T12:30:45Z")); } } diff --git a/tests/test_error_detection.cpp b/tests/test_error_detection.cpp deleted file mode 100644 index 5e39ef6..0000000 --- a/tests/test_error_detection.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include - -BOOST_AUTO_TEST_CASE(test_detect_empty_key) -{ - std::istringstream stream(std::string("= \"value\"")); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_missing_value) -{ - std::istringstream stream(std::string("a =")); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_too_many_value) -{ - std::istringstream stream(std::string("a = 1 = \"value\"")); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_duplicate_table) -{ - std::istringstream stream(std::string( - "[table]\n" - "a = 42\n" - "[table]\n" - "b = 42\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_conflict_array_table) -{ - std::istringstream stream(std::string( - "[[table]]\n" - "a = 42\n" - "[table]\n" - "b = 42\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_conflict_table_array) -{ - std::istringstream stream(std::string( - "[table]\n" - "a = 42\n" - "[[table]]\n" - "b = 42\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_duplicate_value) -{ - std::istringstream stream(std::string( - "a = 1\n" - "a = 2\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_conflicting_value) -{ - std::istringstream stream(std::string( - "a.b = 1\n" - "a.b.c = 2\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array) -{ -#ifdef TOML11_DISALLOW_HETEROGENEOUS_ARRAYS - std::istringstream stream(std::string( - "a = [1, 1.0]\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -#else - BOOST_TEST_MESSAGE("After v1.0.0-rc.1, heterogeneous arrays are allowed"); -#endif -} - -BOOST_AUTO_TEST_CASE(test_detect_appending_array_of_table) -{ - std::istringstream stream(std::string( - "a = [{b = 1}]\n" - "[[a]]\n" - "b = 2\n" - )); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); -} diff --git a/tests/test_expect.cpp b/tests/test_expect.cpp deleted file mode 100644 index 308d4fb..0000000 --- a/tests/test_expect.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include -#include -#include -#include - -BOOST_AUTO_TEST_CASE(test_expect) -{ - { - toml::value v1(42); - toml::value v2(3.14); - const auto v1_or_0 = toml::expect(v1).unwrap_or(0); - const auto v2_or_0 = toml::expect(v2).unwrap_or(0); - BOOST_TEST(42 == v1_or_0); - BOOST_TEST( 0 == v2_or_0); - - const auto v1_or_none = toml::expect(v1).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); - const auto v2_or_none = toml::expect(v2).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); - BOOST_TEST("42" == v1_or_none); - BOOST_TEST("none" == v2_or_none); - } -} diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp deleted file mode 100644 index 1b21264..0000000 --- a/tests/test_extended_conversions.cpp +++ /dev/null @@ -1,627 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include - -namespace extlib -{ -struct foo -{ - int a; - std::string b; -}; -struct bar -{ - int a; - std::string b; - - void from_toml(const toml::value& v) - { - this->a = toml::find(v, "a"); - this->b = toml::find(v, "b"); - return ; - } - - toml::table into_toml() const - { - return toml::table{{"a", this->a}, {"b", this->b}}; - } -}; - -struct baz -{ - int a; - std::string b; -}; -struct qux -{ - int a; - std::string b; -}; - -struct foobar -{ - // via constructor - explicit foobar(const toml::value& v) - : a(toml::find(v, "a")), b(toml::find(v, "b")) - {} - int a; - std::string b; -}; -} // extlib - -namespace toml -{ -template<> -struct from -{ - static extlib::foo from_toml(const toml::value& v) - { - return extlib::foo{toml::find(v, "a"), toml::find(v, "b")}; - } -}; - -template<> -struct into -{ - static toml::value into_toml(const extlib::foo& f) - { - return toml::value{{"a", f.a}, {"b", f.b}}; - } -}; - -template<> -struct from -{ - static extlib::baz from_toml(const toml::value& v) - { - return extlib::baz{toml::find(v, "a"), toml::find(v, "b")}; - } -}; - -template<> -struct into -{ - static toml::table into_toml(const extlib::qux& f) - { - return toml::table{{"a", f.a}, {"b", f.b}}; - } -}; -} // toml - -// --------------------------------------------------------------------------- - -namespace extlib2 -{ -struct foo -{ - int a; - std::string b; -}; -struct bar -{ - int a; - std::string b; - - template class M, template class A> - void from_toml(const toml::basic_value& v) - { - this->a = toml::find(v, "a"); - this->b = toml::find(v, "b"); - return ; - } - - toml::table into_toml() const - { - return toml::table{{"a", this->a}, {"b", this->b}}; - } -}; -struct baz -{ - int a; - std::string b; -}; -struct qux -{ - int a; - std::string b; -}; - -struct foobar -{ - template class M, template class A> - explicit foobar(const toml::basic_value& v) - : a(toml::find(v, "a")), b(toml::find(v, "b")) - {} - int a; - std::string b; -}; - -} // extlib2 - -namespace toml -{ -template<> -struct from -{ - template class M, template class A> - static extlib2::foo from_toml(const toml::basic_value& v) - { - return extlib2::foo{toml::find(v, "a"), toml::find(v, "b")}; - } -}; - -template<> -struct into -{ - static toml::table into_toml(const extlib2::foo& f) - { - return toml::table{{"a", f.a}, {"b", f.b}}; - } -}; - -template<> -struct from -{ - template class M, template class A> - static extlib2::baz from_toml(const toml::basic_value& v) - { - return extlib2::baz{toml::find(v, "a"), toml::find(v, "b")}; - } -}; - -template<> -struct into -{ - static toml::basic_value - into_toml(const extlib2::qux& f) - { - return toml::basic_value{ - {"a", f.a}, {"b", f.b} - }; - } -}; -} // toml - -// --------------------------------------------------------------------------- - -BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods) -{ - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto foo = toml::get(v); - BOOST_TEST(foo.a == 42); - BOOST_TEST(foo.b == "baz"); - - const toml::value v2(foo); - - BOOST_TEST(v == v2); - } - - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto foo = toml::get(v); - BOOST_TEST(foo.a == 42); - BOOST_TEST(foo.b == "baz"); - - const toml::value v2(foo); - BOOST_TEST(v == v2); - } - - { - const toml::basic_value - v{{"a", 42}, {"b", "baz"}}; - - const auto foo = toml::get(v); - BOOST_TEST(foo.a == 42); - BOOST_TEST(foo.b == "baz"); - - const toml::basic_value - v2(foo); - - BOOST_TEST(v == v2); - } -} - -BOOST_AUTO_TEST_CASE(test_conversion_by_specialization) -{ - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto bar = toml::get(v); - BOOST_TEST(bar.a == 42); - BOOST_TEST(bar.b == "baz"); - - const toml::value v2(bar); - - BOOST_TEST(v == v2); - } - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto bar = toml::get(v); - BOOST_TEST(bar.a == 42); - BOOST_TEST(bar.b == "baz"); - - const toml::value v2(bar); - - BOOST_TEST(v == v2); - } - { - const toml::basic_value - v{{"a", 42}, {"b", "baz"}}; - - const auto bar = toml::get(v); - BOOST_TEST(bar.a == 42); - BOOST_TEST(bar.b == "baz"); - - const toml::basic_value - v2(bar); - - BOOST_TEST(v == v2); - } -} - -BOOST_AUTO_TEST_CASE(test_conversion_one_way) -{ - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto baz = toml::get(v); - BOOST_TEST(baz.a == 42); - BOOST_TEST(baz.b == "baz"); - } - { - const extlib::qux q{42, "qux"}; - const toml::value v(q); - - BOOST_TEST(toml::find(v, "a") == 42); - BOOST_TEST(toml::find(v, "b") == "qux"); - } - - { - const toml::basic_value v{ - {"a", 42}, {"b", "baz"} - }; - - const auto baz = toml::get(v); - BOOST_TEST(baz.a == 42); - BOOST_TEST(baz.b == "baz"); - } - { - const extlib::qux q{42, "qux"}; - const toml::basic_value v(q); - - BOOST_TEST(toml::find(v, "a") == 42); - BOOST_TEST(toml::find(v, "b") == "qux"); - } -} - -BOOST_AUTO_TEST_CASE(test_conversion_via_constructor) -{ - { - const toml::value v{{"a", 42}, {"b", "foobar"}}; - - const auto foobar = toml::get(v); - BOOST_TEST(foobar.a == 42); - BOOST_TEST(foobar.b == "foobar"); - } - - { - const toml::basic_value v{ - {"a", 42}, {"b", "foobar"} - }; - - const auto foobar = toml::get(v); - BOOST_TEST(foobar.a == 42); - BOOST_TEST(foobar.b == "foobar"); - } -} - -BOOST_AUTO_TEST_CASE(test_recursive_conversion) -{ - { - const toml::value v{ - toml::table{{"a", 42}, {"b", "baz"}}, - toml::table{{"a", 43}, {"b", "qux"}}, - toml::table{{"a", 44}, {"b", "quux"}}, - toml::table{{"a", 45}, {"b", "foobar"}}, - }; - - const auto foos = toml::get>(v); - BOOST_TEST(foos.size() == 4ul); - BOOST_TEST(foos.at(0).a == 42); - BOOST_TEST(foos.at(1).a == 43); - BOOST_TEST(foos.at(2).a == 44); - BOOST_TEST(foos.at(3).a == 45); - - BOOST_TEST(foos.at(0).b == "baz"); - BOOST_TEST(foos.at(1).b == "qux"); - BOOST_TEST(foos.at(2).b == "quux"); - BOOST_TEST(foos.at(3).b == "foobar"); - - const auto bars = toml::get>(v); - BOOST_TEST(bars.size() == 4ul); - BOOST_TEST(bars.at(0).a == 42); - BOOST_TEST(bars.at(1).a == 43); - BOOST_TEST(bars.at(2).a == 44); - BOOST_TEST(bars.at(3).a == 45); - - BOOST_TEST(bars.at(0).b == "baz"); - BOOST_TEST(bars.at(1).b == "qux"); - BOOST_TEST(bars.at(2).b == "quux"); - BOOST_TEST(bars.at(3).b == "foobar"); - } - { - const toml::value v{ - toml::table{{"a", 42}, {"b", "baz"}}, - toml::table{{"a", 43}, {"b", "qux"}}, - toml::table{{"a", 44}, {"b", "quux"}}, - toml::table{{"a", 45}, {"b", "foobar"}}, - }; - - const auto foos = toml::get>(v); - BOOST_TEST(foos.size() == 4ul); - BOOST_TEST(foos.at(0).a == 42); - BOOST_TEST(foos.at(1).a == 43); - BOOST_TEST(foos.at(2).a == 44); - BOOST_TEST(foos.at(3).a == 45); - - BOOST_TEST(foos.at(0).b == "baz"); - BOOST_TEST(foos.at(1).b == "qux"); - BOOST_TEST(foos.at(2).b == "quux"); - BOOST_TEST(foos.at(3).b == "foobar"); - - const auto bars = toml::get>(v); - BOOST_TEST(bars.size() == 4ul); - BOOST_TEST(bars.at(0).a == 42); - BOOST_TEST(bars.at(1).a == 43); - BOOST_TEST(bars.at(2).a == 44); - BOOST_TEST(bars.at(3).a == 45); - - BOOST_TEST(bars.at(0).b == "baz"); - BOOST_TEST(bars.at(1).b == "qux"); - BOOST_TEST(bars.at(2).b == "quux"); - BOOST_TEST(bars.at(3).b == "foobar"); - } - - { - const toml::basic_value - v{ - toml::table{{"a", 42}, {"b", "baz"}}, - toml::table{{"a", 43}, {"b", "qux"}}, - toml::table{{"a", 44}, {"b", "quux"}}, - toml::table{{"a", 45}, {"b", "foobar"}} - }; - - const auto foos = toml::get>(v); - BOOST_TEST(foos.size() == 4ul); - BOOST_TEST(foos.at(0).a == 42); - BOOST_TEST(foos.at(1).a == 43); - BOOST_TEST(foos.at(2).a == 44); - BOOST_TEST(foos.at(3).a == 45); - - BOOST_TEST(foos.at(0).b == "baz"); - BOOST_TEST(foos.at(1).b == "qux"); - BOOST_TEST(foos.at(2).b == "quux"); - BOOST_TEST(foos.at(3).b == "foobar"); - - const auto bars = toml::get>(v); - BOOST_TEST(bars.size() == 4ul); - BOOST_TEST(bars.at(0).a == 42); - BOOST_TEST(bars.at(1).a == 43); - BOOST_TEST(bars.at(2).a == 44); - BOOST_TEST(bars.at(3).a == 45); - - BOOST_TEST(bars.at(0).b == "baz"); - BOOST_TEST(bars.at(1).b == "qux"); - BOOST_TEST(bars.at(2).b == "quux"); - BOOST_TEST(bars.at(3).b == "foobar"); - } - - // via constructor - { - const toml::value v{ - toml::table{{"a", 42}, {"b", "baz"}}, - toml::table{{"a", 43}, {"b", "qux"}}, - toml::table{{"a", 44}, {"b", "quux"}}, - toml::table{{"a", 45}, {"b", "foobar"}} - }; - - { - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at(0).a == 42); - BOOST_TEST(foobars.at(1).a == 43); - BOOST_TEST(foobars.at(2).a == 44); - BOOST_TEST(foobars.at(3).a == 45); - - BOOST_TEST(foobars.at(0).b == "baz"); - BOOST_TEST(foobars.at(1).b == "qux"); - BOOST_TEST(foobars.at(2).b == "quux"); - BOOST_TEST(foobars.at(3).b == "foobar"); - } - { - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at(0).a == 42); - BOOST_TEST(foobars.at(1).a == 43); - BOOST_TEST(foobars.at(2).a == 44); - BOOST_TEST(foobars.at(3).a == 45); - - BOOST_TEST(foobars.at(0).b == "baz"); - BOOST_TEST(foobars.at(1).b == "qux"); - BOOST_TEST(foobars.at(2).b == "quux"); - BOOST_TEST(foobars.at(3).b == "foobar"); - } - } - { - const toml::basic_value - v{ - toml::table{{"a", 42}, {"b", "baz"}}, - toml::table{{"a", 43}, {"b", "qux"}}, - toml::table{{"a", 44}, {"b", "quux"}}, - toml::table{{"a", 45}, {"b", "foobar"}} - }; - - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at(0).a == 42); - BOOST_TEST(foobars.at(1).a == 43); - BOOST_TEST(foobars.at(2).a == 44); - BOOST_TEST(foobars.at(3).a == 45); - - BOOST_TEST(foobars.at(0).b == "baz"); - BOOST_TEST(foobars.at(1).b == "qux"); - BOOST_TEST(foobars.at(2).b == "quux"); - BOOST_TEST(foobars.at(3).b == "foobar"); - } - - // via constructor - { - const toml::value v{ - {"0", toml::table{{"a", 42}, {"b", "baz"}}}, - {"1", toml::table{{"a", 43}, {"b", "qux"}}}, - {"2", toml::table{{"a", 44}, {"b", "quux"}}}, - {"3", toml::table{{"a", 45}, {"b", "foobar"}}} - }; - - { - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at("0").a == 42); - BOOST_TEST(foobars.at("1").a == 43); - BOOST_TEST(foobars.at("2").a == 44); - BOOST_TEST(foobars.at("3").a == 45); - - BOOST_TEST(foobars.at("0").b == "baz"); - BOOST_TEST(foobars.at("1").b == "qux"); - BOOST_TEST(foobars.at("2").b == "quux"); - BOOST_TEST(foobars.at("3").b == "foobar"); - } - { - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at("0").a == 42); - BOOST_TEST(foobars.at("1").a == 43); - BOOST_TEST(foobars.at("2").a == 44); - BOOST_TEST(foobars.at("3").a == 45); - - BOOST_TEST(foobars.at("0").b == "baz"); - BOOST_TEST(foobars.at("1").b == "qux"); - BOOST_TEST(foobars.at("2").b == "quux"); - BOOST_TEST(foobars.at("3").b == "foobar"); - } - } - { - const toml::basic_value - v{ - {"0", toml::table{{"a", 42}, {"b", "baz"}}}, - {"1", toml::table{{"a", 43}, {"b", "qux"}}}, - {"2", toml::table{{"a", 44}, {"b", "quux"}}}, - {"3", toml::table{{"a", 45}, {"b", "foobar"}}} - }; - - const auto foobars = toml::get>(v); - BOOST_TEST(foobars.size() == 4ul); - BOOST_TEST(foobars.at("0").a == 42); - BOOST_TEST(foobars.at("1").a == 43); - BOOST_TEST(foobars.at("2").a == 44); - BOOST_TEST(foobars.at("3").a == 45); - - BOOST_TEST(foobars.at("0").b == "baz"); - BOOST_TEST(foobars.at("1").b == "qux"); - BOOST_TEST(foobars.at("2").b == "quux"); - BOOST_TEST(foobars.at("3").b == "foobar"); - } - -} - -// =========================================================================== - -#ifndef TOML11_WITHOUT_DEFINE_NON_INTRUSIVE - -namespace extlib3 -{ -struct foo -{ - int a; - std::string b; -}; -struct bar -{ - int a; - std::string b; - foo f; -}; - -} // extlib3 - -TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::foo, a, b) -TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::bar, a, b, f) - -BOOST_AUTO_TEST_CASE(test_conversion_via_macro) -{ - { - const toml::value v{{"a", 42}, {"b", "baz"}}; - - const auto foo = toml::get(v); - BOOST_TEST(foo.a == 42); - BOOST_TEST(foo.b == "baz"); - - const toml::value v2(foo); - BOOST_TEST(v2 == v); - } - { - const toml::basic_value v{ - {"a", 42}, {"b", "baz"} - }; - - const auto foo = toml::get(v); - BOOST_TEST(foo.a == 42); - BOOST_TEST(foo.b == "baz"); - - const toml::basic_value v2(foo); - BOOST_TEST(v2 == v); - } - - // ----------------------------------------------------------------------- - - { - const toml::value v{ - {"a", 42}, - {"b", "bar.b"}, - {"f", toml::table{{"a", 42}, {"b", "foo.b"}}} - }; - - const auto bar = toml::get(v); - BOOST_TEST(bar.a == 42); - BOOST_TEST(bar.b == "bar.b"); - BOOST_TEST(bar.f.a == 42); - BOOST_TEST(bar.f.b == "foo.b"); - - const toml::value v2(bar); - BOOST_TEST(v2 == v); - } - { - const toml::basic_value v{ - {"a", 42}, - {"b", "bar.b"}, - {"f", toml::table{{"a", 42}, {"b", "foo.b"}}} - }; - - const auto bar = toml::get(v); - BOOST_TEST(bar.a == 42); - BOOST_TEST(bar.b == "bar.b"); - BOOST_TEST(bar.f.a == 42); - BOOST_TEST(bar.f.b == "foo.b"); - - const toml::basic_value v2(bar); - BOOST_TEST(v2 == v); - } -} -#endif // TOML11_WITHOUT_DEFINE_NON_INTRUSIVE diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 944b8e8..5899b91 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -1,6 +1,10 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include "utility.hpp" + +#include +#include #include #include @@ -9,41 +13,184 @@ #include #include -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L +#if defined(TOML11_HAS_STRING_VIEW) #include #endif -using test_value_types = std::tuple< - toml::basic_value, - toml::basic_value, - toml::basic_value, - toml::basic_value - >; - -BOOST_AUTO_TEST_CASE(test_find_throws) +TEST_CASE("testing toml::find with toml type") { + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + { + value_type v(toml::table{{"a", true}}); + CHECK_EQ(true, toml::find(v, "a")); + + toml::find(v, "a") = false; + CHECK_EQ(false, toml::find(v, "a")); + + boolean_type x = toml::find(std::move(v), "a"); + CHECK_EQ(false, x); + } + { + value_type v(toml::table{{"a", 42}}); + CHECK_EQ(integer_type(42), toml::find(v, "a")); + + toml::find(v, "a") = 54; + CHECK_EQ(integer_type(54), toml::find(v, "a")); + + integer_type x = toml::find(std::move(v), "a"); + CHECK_EQ(integer_type(54), x); + } + { + value_type v(toml::table{{"a", 3.14}}); + CHECK_EQ(floating_type(3.14), toml::find(v, "a")); + + toml::find(v, "a") = 2.71; + CHECK_EQ(floating_type(2.71), toml::find(v, "a")); + + floating_type x = toml::find(std::move(v), "a"); + CHECK_EQ(floating_type(2.71), x); + } + { + value_type v(toml::table{{"a", "foo"}}); + CHECK_EQ("foo", toml::find(v, "a")); + + toml::find(v, "a") += "bar"; + CHECK_EQ("foobar", toml::find(v, "a")); + + string_type x = toml::find(std::move(v), "a"); + CHECK_EQ("foobar", x); + } + { + local_date_type d(2018, toml::month_t::Apr, 22); + value_type v(toml::table{{"a", d}}); + CHECK_EQ(d, toml::find(v, "a")); + + toml::find(v, "a").year = 2017; + d.year = 2017; + CHECK_EQ(d, toml::find(v, "a")); + + local_date_type x = toml::find(std::move(v), "a"); + CHECK_EQ(d, x); + } + { + local_time_type t(12, 30, 45); + value_type v(toml::table{{"a", t}}); + CHECK_EQ(t, toml::find(v, "a")); + + toml::find(v, "a").hour = 9; + t.hour = 9; + CHECK_EQ(t, toml::find(v, "a")); + + local_time_type x = toml::find(std::move(v), "a"); + CHECK_EQ(t, x); + } + { + local_datetime_type dt(toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)); + value_type v(toml::table{{"a", dt}}); + CHECK_EQ(dt, toml::find(v, "a")); + + toml::find(v, "a").date.year = 2017; + dt.date.year = 2017; + CHECK_EQ(dt, toml::find(v, "a")); + + toml::local_datetime x = toml::find(std::move(v), "a"); + CHECK_EQ(dt, x); + } + { + offset_datetime_type dt(toml::local_datetime( + toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); + value_type v(toml::table{{"a", dt}}); + CHECK_EQ(dt, toml::find(v, "a")); + + toml::find(v, "a").date.year = 2017; + dt.date.year = 2017; + CHECK_EQ(dt, toml::find(v, "a")); + + offset_datetime_type x = toml::find(std::move(v), "a"); + CHECK_EQ(dt, x); + } + { + array_type vec; + vec.push_back(value_type(42)); + vec.push_back(value_type(54)); + value_type v(toml::table{{"a", vec}}); + CHECK_EQ(vec, toml::find(v, "a")); + + toml::find(v, "a").push_back(value_type(123)); + vec.push_back(value_type(123)); + CHECK_EQ(vec, toml::find(v, "a")); + + array_type x = toml::find(std::move(v), "a"); + CHECK_EQ(vec, x); + } + { + table_type tab; + tab["key1"] = value_type(42); + tab["key2"] = value_type(3.14); + value_type v(toml::table{{"a", tab}}); + CHECK_EQ(tab, toml::find(v, "a")); + + toml::find(v, "a")["key3"] = value_type(123); + tab["key3"] = value_type(123); + CHECK_EQ(tab, toml::find(v, "a")); + + table_type x = toml::find(std::move(v), "a"); + CHECK_EQ(tab, x); + } + { + value_type v1(toml::table{{"a", 42}}); + CHECK_EQ(toml::value(42), toml::find(v1, "a")); + + value_type v2(54); + toml::find(v1, "a") = v2; + CHECK_EQ(v2, toml::find(v1, "a")); + + value_type x = toml::find(std::move(v1), "a"); + CHECK_EQ(v2, x); + } +} + +TEST_CASE("testing find throws") +{ + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + // ----------------------------------------------------------------------- // const-reference version { // value is not a table const toml::value v(true); - BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + CHECK_THROWS_AS(toml::find(v, "key"), toml::type_error); } { // the value corresponding to the key is not the expected type - const toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + const toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(v, "key"), toml::type_error); } { // the value corresponding to the key is not found - const toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(v, "different_key"), + const toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(v, "different_key"), std::out_of_range); } { // the positive control. - const toml::value v{{"key", 42}}; - BOOST_TEST(42 == toml::find(v, "key")); + const toml::value v = toml::table{{"key", 42}}; + CHECK_EQ(42, toml::find(v, "key")); } // ----------------------------------------------------------------------- @@ -51,23 +198,23 @@ BOOST_AUTO_TEST_CASE(test_find_throws) { // value is not a table toml::value v(true); - BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + CHECK_THROWS_AS(toml::find(v, "key"), toml::type_error); } { // the value corresponding to the key is not the expected type - toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(v, "key"), toml::type_error); + toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(v, "key"), toml::type_error); } { // the value corresponding to the key is not found - toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(v, "different_key"), + toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(v, "different_key"), std::out_of_range); } { // the positive control. - toml::value v{{"key", 42}}; - BOOST_TEST(42 == toml::find(v, "key")); + toml::value v = toml::table{{"key", 42}}; + CHECK_EQ(42, toml::find(v, "key")); } // ----------------------------------------------------------------------- @@ -76,49 +223,53 @@ BOOST_AUTO_TEST_CASE(test_find_throws) { // value is not a table toml::value v(true); - BOOST_CHECK_THROW(toml::find(std::move(v), "key"), toml::type_error); + CHECK_THROWS_AS(toml::find(std::move(v), "key"), toml::type_error); } { // the value corresponding to the key is not the expected type - toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(std::move(v), "key"), toml::type_error); + toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(std::move(v), "key"), toml::type_error); } { // the value corresponding to the key is not found - toml::value v{{"key", 42}}; - BOOST_CHECK_THROW(toml::find(std::move(v), "different_key"), + toml::value v = toml::table{{"key", 42}}; + CHECK_THROWS_AS(toml::find(std::move(v), "different_key"), std::out_of_range); } { // the positive control. - toml::value v{{"key", 42}}; - BOOST_TEST(42 == toml::find(std::move(v), "key")); + toml::value v = toml::table{{"key", 42}}; + CHECK_EQ(42, toml::find(std::move(v), "key")); } } -BOOST_AUTO_TEST_CASE(test_find_array_throws) +TEST_CASE("testing toml::find(v, idx) throws") { + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + // ----------------------------------------------------------------------- // const-reference version { // value is not an array const toml::value v(true); - BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + CHECK_THROWS_AS(toml::find(v, 0), toml::type_error); } { // the value corresponding to the key is not the expected type - const toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + const toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(v, 0), toml::type_error); } { // the value corresponding to the key is not found - const toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(v, 6), std::out_of_range); + const toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(v, 6), std::out_of_range); } { // the positive control. - const toml::value v{1, 2, 3, 4, 5}; - BOOST_TEST(3 == toml::find(v, 2)); + const toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_EQ(3, toml::find(v, 2)); } // ----------------------------------------------------------------------- @@ -126,22 +277,22 @@ BOOST_AUTO_TEST_CASE(test_find_array_throws) { // value is not an array toml::value v(true); - BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + CHECK_THROWS_AS(toml::find(v, 0), toml::type_error); } { // the value corresponding to the key is not the expected type - toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(v, 0), toml::type_error); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(v, 0), toml::type_error); } { // the value corresponding to the key is not found - toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(v, 6), std::out_of_range); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(v, 6), std::out_of_range); } { // the positive control. - toml::value v{1, 2, 3, 4, 5}; - BOOST_TEST(3 == toml::find(v, 2)); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_EQ(3, toml::find(v, 2)); } // ----------------------------------------------------------------------- @@ -149,83 +300,86 @@ BOOST_AUTO_TEST_CASE(test_find_array_throws) { // value is not an array toml::value v(true); - BOOST_CHECK_THROW(toml::find(std::move(v), 0), toml::type_error); + CHECK_THROWS_AS(toml::find(std::move(v), 0), toml::type_error); } { // the value corresponding to the key is not the expected type - toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(std::move(v), 0), toml::type_error); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(std::move(v), 0), toml::type_error); } { // the value corresponding to the key is not found - toml::value v{1, 2, 3, 4, 5}; - BOOST_CHECK_THROW(toml::find(std::move(v), 6), std::out_of_range); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_THROWS_AS(toml::find(std::move(v), 6), std::out_of_range); } { // the positive control. - toml::value v{1, 2, 3, 4, 5}; - BOOST_TEST(3 == toml::find(std::move(v), 2)); + toml::value v = toml::array{1, 2, 3, 4, 5}; + CHECK_EQ(3, toml::find(std::move(v), 2)); } } -BOOST_AUTO_TEST_CASE(test_find_recursive) +TEST_CASE("testing toml::find with recursive table/array") { + using value_type = toml::value; + using integer_type = typename value_type::integer_type ; + // recursively search tables { - toml::value v{ - {"a", { - {"b", { - {"c", { + toml::value v = toml::table{ + {"a", toml::table{ + {"b", toml::table{ + {"c", toml::table{ {"d", 42} }} }} }} }; - BOOST_TEST(42 == toml::find(v, "a", "b", "c", "d")); + CHECK_EQ(42, toml::find(v, "a", "b", "c", "d")); // reference that can be used to modify the content - auto& num = toml::find(v, "a", "b", "c", "d"); + auto& num = toml::find(v, "a", "b", "c", "d"); num = 54; - BOOST_TEST(54 == toml::find(v, "a", "b", "c", "d")); + CHECK_EQ(54, toml::find(v, "a", "b", "c", "d")); const std::string a("a"), b("b"), c("c"), d("d"); - auto& num2 = toml::find(v, a, b, c, d); + auto& num2 = toml::find(v, a, b, c, d); num2 = 42; - BOOST_TEST(42 == toml::find(v, a, b, c, d)); + CHECK_EQ(42, toml::find(v, a, b, c, d)); - auto num3 = toml::find(v, a, "b", c, "d"); - BOOST_TEST(42 == num3); + auto num3 = toml::find(v, a, "b", c, "d"); + CHECK_EQ(42, num3); - auto num4 = toml::find(std::move(v), a, b, c, d); - BOOST_TEST(42 == num4); + auto num4 = toml::find(std::move(v), a, b, c, d); + CHECK_EQ(42, num4); } // recursively search arrays { - toml::value v{ + toml::value v = toml::array{ toml::array{"array", "of", "string"}, toml::array{toml::array{1, 2, 3}, toml::array{3.14, 2.71}} }; - BOOST_TEST("array" == toml::find(v, 0, 0)); - BOOST_TEST("of" == toml::find(v, 0, 1)); - BOOST_TEST("string" == toml::find(v, 0, 2)); + CHECK_EQ("array" , toml::find(v, 0, 0)); + CHECK_EQ("of" , toml::find(v, 0, 1)); + CHECK_EQ("string", toml::find(v, 0, 2)); - BOOST_TEST(1 == toml::find(v, 1, 0, 0)); - BOOST_TEST(2 == toml::find(v, 1, 0, 1)); - BOOST_TEST(3 == toml::find(v, 1, 0, 2)); + CHECK_EQ(1, toml::find(v, 1, 0, 0)); + CHECK_EQ(2, toml::find(v, 1, 0, 1)); + CHECK_EQ(3, toml::find(v, 1, 0, 2)); - BOOST_TEST(3.14 == toml::find(v, 1, 1, 0)); - BOOST_TEST(2.71 == toml::find(v, 1, 1, 1)); + CHECK_EQ(3.14, toml::find(v, 1, 1, 0)); + CHECK_EQ(2.71, toml::find(v, 1, 1, 1)); // reference that can be used to modify the content - auto& num = toml::find(v, 1, 0, 2); + auto& num = toml::find(v, 1, 0, 2); num = 42; - BOOST_TEST( 1 == toml::find(v, 1, 0, 0)); - BOOST_TEST( 2 == toml::find(v, 1, 0, 1)); - BOOST_TEST(42 == toml::find(v, 1, 0, 2)); + CHECK_EQ( 1, toml::find(v, 1, 0, 0)); + CHECK_EQ( 2, toml::find(v, 1, 0, 1)); + CHECK_EQ(42, toml::find(v, 1, 0, 2)); // move value - auto num2 = toml::find(std::move(v), 1, 0, 2); - BOOST_TEST(42 == num2); + auto num2 = toml::find(std::move(v), 1, 0, 2); + CHECK_EQ(42, num2); } // recursively search mixtures { @@ -237,15 +391,15 @@ BOOST_AUTO_TEST_CASE(test_find_recursive) }} }}; - BOOST_TEST(1 == toml::find(v, "array", 0, 0)); - BOOST_TEST(2 == toml::find(v, "array", 0, 1)); - BOOST_TEST(3 == toml::find(v, "array", 0, 2)); + CHECK_EQ(1, toml::find(v, "array", 0, 0)); + CHECK_EQ(2, toml::find(v, "array", 0, 1)); + CHECK_EQ(3, toml::find(v, "array", 0, 2)); - BOOST_TEST("bar" == toml::find(v, "array", 1, 0, "foo")); - BOOST_TEST("qux" == toml::find(v, "array", 1, 0, "baz")); + CHECK_EQ("bar", toml::find(v, "array", 1, 0, "foo")); + CHECK_EQ("qux", toml::find(v, "array", 1, 0, "baz")); - BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, "pi")); - BOOST_TEST(2.71 == toml::find(v, "array", 1, 1, "e")); + CHECK_EQ(3.14, toml::find(v, "array", 1, 1, "pi")); + CHECK_EQ(2.71, toml::find(v, "array", 1, 1, "e")); const std::string ar("array"); const auto ar_c = "array"; @@ -253,419 +407,417 @@ BOOST_AUTO_TEST_CASE(test_find_recursive) const std::string pi("pi"); const auto pi_c = "pi"; - BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, "pi")); - BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, pi)); - BOOST_TEST(3.14 == toml::find(v, ar, 1, 1, pi_c)); + CHECK_EQ(3.14, toml::find(v, ar, 1, 1, "pi")); + CHECK_EQ(3.14, toml::find(v, ar, 1, 1, pi)); + CHECK_EQ(3.14, toml::find(v, ar, 1, 1, pi_c)); - BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, "pi")); - BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, pi)); - BOOST_TEST(3.14 == toml::find(v, ar_c, 1, 1, pi_c)); + CHECK_EQ(3.14, toml::find(v, ar_c, 1, 1, "pi")); + CHECK_EQ(3.14, toml::find(v, ar_c, 1, 1, pi)); + CHECK_EQ(3.14, toml::find(v, ar_c, 1, 1, pi_c)); - BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, pi)); - BOOST_TEST(3.14 == toml::find(v, "array", 1, 1, pi_c)); + CHECK_EQ(3.14, toml::find(v, "array", 1, 1, pi)); + CHECK_EQ(3.14, toml::find(v, "array", 1, 1, pi_c)); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) +TEST_CASE("testing toml::find with toml types") { + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + { - value_type v{{"key", true}}; - BOOST_TEST(true == toml::find(v, "key")); + value_type v = toml::table{{"key", true}}; + CHECK(true == toml::find(v, "key")); - toml::find(v, "key") = false; - BOOST_TEST(false == toml::find(v, "key")); + toml::find(v, "key") = false; + CHECK(false == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST(false == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(false == moved); } { - value_type v{{"key", 42}}; - BOOST_TEST(toml::integer(42) == toml::find(v, "key")); + value_type v = toml::table{{"key", 42}}; + CHECK(integer_type(42) == toml::find(v, "key")); - toml::find(v, "key") = 54; - BOOST_TEST(toml::integer(54) == toml::find(v, "key")); + toml::find(v, "key") = 54; + CHECK(integer_type(54) == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST(toml::integer(54) == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(integer_type(54) == moved); } { - value_type v{{"key", 3.14}}; - BOOST_TEST(toml::floating(3.14) == toml::find(v, "key")); + value_type v = toml::table{{"key", 3.14}}; + CHECK(floating_type(3.14) == toml::find(v, "key")); - toml::find(v, "key") = 2.71; - BOOST_TEST(toml::floating(2.71) == toml::find(v, "key")); + toml::find(v, "key") = 2.71; + CHECK(floating_type(2.71) == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST(toml::floating(2.71) == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(floating_type(2.71) == moved); } { - value_type v{{"key", "foo"}}; - BOOST_TEST(toml::string("foo", toml::string_t::basic) == - toml::find(v, "key")); + value_type v = toml::table{{"key", "foo"}}; + CHECK("foo" == toml::find(v, "key")); - toml::find(v, "key").str += "bar"; - BOOST_TEST(toml::string("foobar", toml::string_t::basic) == - toml::find(v, "key")); + toml::find(v, "key") += "bar"; + CHECK("foobar" == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST(toml::string("foobar", toml::string_t::basic) == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK("foobar" == moved); } { - value_type v{{"key", value_type("foo", toml::string_t::literal)}}; - BOOST_TEST(toml::string("foo", toml::string_t::literal) == - toml::find(v, "key")); + local_date_type d(2018, toml::month_t::Apr, 22); + value_type v = toml::table{{"key", d}}; + CHECK(d == toml::find(v, "key")); - toml::find(v, "key").str += "bar"; - BOOST_TEST(toml::string("foobar", toml::string_t::literal) == - toml::find(v, "key")); - - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST(toml::string("foobar", toml::string_t::literal) == moved); - } - { - toml::local_date d(2018, toml::month_t::Apr, 22); - value_type v{{"key", d}}; - BOOST_CHECK(d == toml::find(v, "key")); - - toml::find(v, "key").year = 2017; + toml::find(v, "key").year = 2017; d.year = 2017; - BOOST_CHECK(d == toml::find(v, "key")); + CHECK(d == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_CHECK(d == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(d == moved); } { - toml::local_time t(12, 30, 45); - value_type v{{"key", t}}; - BOOST_CHECK(t == toml::find(v, "key")); + local_time_type t(12, 30, 45); + value_type v = toml::table{{"key", t}}; + CHECK(t == toml::find(v, "key")); - toml::find(v, "key").hour = 9; + toml::find(v, "key").hour = 9; t.hour = 9; - BOOST_CHECK(t == toml::find(v, "key")); + CHECK(t == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_CHECK(t == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(t == moved); } { - toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), - toml::local_time(12, 30, 45)); - value_type v{{"key", dt}}; - BOOST_CHECK(dt == toml::find(v, "key")); + local_datetime_type dt(toml::local_date(2018, toml::month_t::Apr, 22), + local_time_type(12, 30, 45)); + value_type v = toml::table{{"key", dt}}; + CHECK(dt == toml::find(v, "key")); - toml::find(v, "key").date.year = 2017; + toml::find(v, "key").date.year = 2017; dt.date.year = 2017; - BOOST_CHECK(dt == toml::find(v, "key")); + CHECK(dt == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_CHECK(dt == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(dt == moved); } { - toml::offset_datetime dt(toml::local_datetime( + offset_datetime_type dt(local_datetime_type( toml::local_date(2018, toml::month_t::Apr, 22), - toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); - value_type v{{"key", dt}}; - BOOST_CHECK(dt == toml::find(v, "key")); + local_time_type(12, 30, 45)), toml::time_offset(9, 0)); + value_type v = toml::table{{"key", dt}}; + CHECK(dt == toml::find(v, "key")); - toml::find(v, "key").date.year = 2017; + toml::find(v, "key").date.year = 2017; dt.date.year = 2017; - BOOST_CHECK(dt == toml::find(v, "key")); + CHECK(dt == toml::find(v, "key")); - const auto moved = toml::find(std::move(v), "key"); - BOOST_CHECK(dt == moved); + const auto moved = toml::find(std::move(v), "key"); + CHECK(dt == moved); } { - typename value_type::array_type vec; + array_type vec; vec.push_back(value_type(42)); vec.push_back(value_type(54)); - value_type v{{"key", vec}}; + value_type v = toml::table{{"key", vec}}; - const bool result1 = (vec == toml::find(v, "key")); - BOOST_CHECK(result1); + const bool result1 = (vec == toml::find(v, "key")); + CHECK(result1); - toml::find(v, "key").push_back(value_type(123)); + toml::find(v, "key").push_back(value_type(123)); vec.push_back(value_type(123)); - const bool result2 = (vec == toml::find(v, "key")); - BOOST_CHECK(result2); + const bool result2 = (vec == toml::find(v, "key")); + CHECK(result2); - const auto moved = toml::find(std::move(v), "key"); + const auto moved = toml::find(std::move(v), "key"); const bool result3 = (vec == moved); - BOOST_CHECK(result3); + CHECK(result3); } { - typename value_type::table_type tab; + table_type tab; tab["key1"] = value_type(42); tab["key2"] = value_type(3.14); - value_type v{{"key", tab}}; - const bool result1 = (tab == toml::find(v, "key")); - BOOST_CHECK(result1); + value_type v = toml::table{{"key", tab}}; + const bool result1 = (tab == toml::find(v, "key")); + CHECK(result1); - toml::find(v, "key")["key3"] = value_type(123); + toml::find(v, "key")["key3"] = value_type(123); tab["key3"] = value_type(123); - const bool result2 = (tab == toml::find(v, "key")); - BOOST_CHECK(result2); + const bool result2 = (tab == toml::find(v, "key")); + CHECK(result2); - const auto moved = toml::find(std::move(v), "key"); + const auto moved = toml::find(std::move(v), "key"); const bool result3 = (tab == moved); - BOOST_CHECK(result3); + CHECK(result3); } { value_type v1(42); - value_type v{{"key", v1}}; - BOOST_CHECK(v1 == toml::find(v, "key")); + value_type v = toml::table{{"key", v1}}; + CHECK(v1 == toml::find(v, "key")); value_type v2(54); toml::find(v, "key") = v2; - BOOST_CHECK(v2 == toml::find(v, "key")); + CHECK(v2 == toml::find(v, "key")); const auto moved = toml::find(std::move(v), "key"); - BOOST_CHECK(v2 == moved); + CHECK(v2 == moved); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_integer_type, value_type, test_value_types) +TEST_CASE("testing toml::find integer conversion") { + using value_type = toml::value; + { - value_type v{{"key", 42}}; - BOOST_TEST(int(42) == toml::find(v, "key")); - BOOST_TEST(short(42) == toml::find(v, "key")); - BOOST_TEST(char(42) == toml::find(v, "key")); - BOOST_TEST(unsigned(42) == toml::find(v, "key")); - BOOST_TEST(long(42) == toml::find(v, "key")); - BOOST_TEST(std::int64_t(42) == toml::find(v, "key")); - BOOST_TEST(std::uint64_t(42) == toml::find(v, "key")); - BOOST_TEST(std::int16_t(42) == toml::find(v, "key")); - BOOST_TEST(std::uint16_t(42) == toml::find(v, "key")); - BOOST_TEST(std::uint16_t(42) == toml::find(std::move(v), "key")); + value_type v = toml::table{{"key", 42}}; + CHECK_EQ(int(42) , toml::find(v, "key")); + CHECK_EQ(short(42) , toml::find(v, "key")); + CHECK_EQ(char(42) , toml::find(v, "key")); + CHECK_EQ(unsigned(42) , toml::find(v, "key")); + CHECK_EQ(long(42) , toml::find(v, "key")); + CHECK_EQ(std::int64_t(42) , toml::find(v, "key")); + CHECK_EQ(std::uint64_t(42), toml::find(v, "key")); + CHECK_EQ(std::int16_t(42) , toml::find(v, "key")); + CHECK_EQ(std::uint16_t(42), toml::find(v, "key")); + CHECK_EQ(std::uint16_t(42), toml::find(std::move(v), "key")); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_types) +TEST_CASE("testing toml::find floating conversion") { + using value_type = toml::value; + { - value_type v{{"key", 3.14}}; + value_type v = toml::table{{"key", 3.14}}; const double ref(3.14); - BOOST_TEST(static_cast(ref) == toml::find(v, "key")); - BOOST_TEST( ref == toml::find(v, "key")); - BOOST_TEST(static_cast(ref) == toml::find(v, "key")); - BOOST_TEST(static_cast(ref) == toml::find(std::move(v), "key")); + CHECK_EQ(static_cast(ref), toml::find(v, "key")); + CHECK_EQ( ref , toml::find(v, "key")); + CHECK_EQ(static_cast(ref), toml::find(v, "key")); + CHECK_EQ(static_cast(ref), toml::find(std::move(v), "key")); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_types) +TEST_CASE("testing toml::find string conversion") { + using value_type = toml::value; + { - value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; - BOOST_TEST("foo" == toml::find(v, "key")); + value_type v = toml::table{{"key", "foo"}}; + CHECK_EQ("foo", toml::find(v, "key")); toml::find(v, "key") += "bar"; - BOOST_TEST("foobar" == toml::find(v, "key")); - } - { - value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; - BOOST_TEST("foo" == toml::find(v, "key")); - toml::find(v, "key") += "bar"; - BOOST_TEST("foobar" == toml::find(v, "key")); - } - { - value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; - const auto moved = toml::find(std::move(v), "key"); - BOOST_TEST("foo" == moved); + CHECK_EQ("foobar", toml::find(v, "key")); } #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L { - value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; - BOOST_TEST("foo" == toml::find(v, "key")); - } - { - value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; - BOOST_TEST("foo" == toml::find(v, "key")); + value_type v = toml::table{{"key", "foo"}}; + CHECK_EQ("foo", toml::find(v, "key")); } #endif } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array, value_type, test_value_types) +TEST_CASE("testing toml::find array conversion") { - value_type v{{"key", {42, 54, 69, 72}}}; + using value_type = toml::value; + + value_type v = toml::table{{"key", toml::array{42, 54, 69, 72}}}; const std::vector vec = toml::find>(v, "key"); const std::list lst = toml::find>(v, "key"); const std::deque deq = toml::find>(v, "key"); - BOOST_TEST(42 == vec.at(0)); - BOOST_TEST(54 == vec.at(1)); - BOOST_TEST(69 == vec.at(2)); - BOOST_TEST(72 == vec.at(3)); + CHECK_EQ(42, vec.at(0)); + CHECK_EQ(54, vec.at(1)); + CHECK_EQ(69, vec.at(2)); + CHECK_EQ(72, vec.at(3)); std::list::const_iterator iter = lst.begin(); - BOOST_TEST(static_cast(42) == *(iter++)); - BOOST_TEST(static_cast(54) == *(iter++)); - BOOST_TEST(static_cast(69) == *(iter++)); - BOOST_TEST(static_cast(72) == *(iter++)); + CHECK_EQ(static_cast(42), *(iter++)); + CHECK_EQ(static_cast(54), *(iter++)); + CHECK_EQ(static_cast(69), *(iter++)); + CHECK_EQ(static_cast(72), *(iter++)); - BOOST_TEST(static_cast(42) == deq.at(0)); - BOOST_TEST(static_cast(54) == deq.at(1)); - BOOST_TEST(static_cast(69) == deq.at(2)); - BOOST_TEST(static_cast(72) == deq.at(3)); + CHECK_EQ(static_cast(42), deq.at(0)); + CHECK_EQ(static_cast(54), deq.at(1)); + CHECK_EQ(static_cast(69), deq.at(2)); + CHECK_EQ(static_cast(72), deq.at(3)); std::array ary = toml::find>(v, "key"); - BOOST_TEST(42 == ary.at(0)); - BOOST_TEST(54 == ary.at(1)); - BOOST_TEST(69 == ary.at(2)); - BOOST_TEST(72 == ary.at(3)); + CHECK_EQ(42, ary.at(0)); + CHECK_EQ(54, ary.at(1)); + CHECK_EQ(69, ary.at(2)); + CHECK_EQ(72, ary.at(3)); std::tuple tpl = toml::find>(v, "key"); - BOOST_TEST( 42 == std::get<0>(tpl)); - BOOST_TEST(static_cast(54) == std::get<1>(tpl)); - BOOST_TEST(static_cast(69) == std::get<2>(tpl)); - BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + CHECK_EQ( 42 , std::get<0>(tpl)); + CHECK_EQ(static_cast(54), std::get<1>(tpl)); + CHECK_EQ(static_cast(69), std::get<2>(tpl)); + CHECK_EQ(static_cast(72), std::get<3>(tpl)); - value_type p{{"key", {3.14, 2.71}}}; + value_type p = toml::table{{"key", toml::array{3.14, 2.71}}}; std::pair pr = toml::find >(p, "key"); - BOOST_TEST(3.14 == pr.first); - BOOST_TEST(2.71 == pr.second); + CHECK_EQ(3.14, pr.first); + CHECK_EQ(2.71, pr.second); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array, value_type, test_value_types) +TEST_CASE("testing toml::find array move conversion") { - value_type v1{{"key", {42, 54, 69, 72}}}; - value_type v2{{"key", {42, 54, 69, 72}}}; - value_type v3{{"key", {42, 54, 69, 72}}}; - value_type v4{{"key", {42, 54, 69, 72}}}; - value_type v5{{"key", {42, 54, 69, 72}}}; + using value_type = toml::value; + + value_type v1 = toml::table{{"key", toml::array{42, 54, 69, 72}}}; + value_type v2 = toml::table{{"key", toml::array{42, 54, 69, 72}}}; + value_type v3 = toml::table{{"key", toml::array{42, 54, 69, 72}}}; + value_type v4 = toml::table{{"key", toml::array{42, 54, 69, 72}}}; + value_type v5 = toml::table{{"key", toml::array{42, 54, 69, 72}}}; const std::vector vec = toml::find>(std::move(v1), "key"); const std::list lst = toml::find>(std::move(v2), "key"); const std::deque deq = toml::find>(std::move(v3), "key"); - BOOST_TEST(42 == vec.at(0)); - BOOST_TEST(54 == vec.at(1)); - BOOST_TEST(69 == vec.at(2)); - BOOST_TEST(72 == vec.at(3)); + CHECK_EQ(42, vec.at(0)); + CHECK_EQ(54, vec.at(1)); + CHECK_EQ(69, vec.at(2)); + CHECK_EQ(72, vec.at(3)); std::list::const_iterator iter = lst.begin(); - BOOST_TEST(static_cast(42) == *(iter++)); - BOOST_TEST(static_cast(54) == *(iter++)); - BOOST_TEST(static_cast(69) == *(iter++)); - BOOST_TEST(static_cast(72) == *(iter++)); + CHECK_EQ(static_cast(42), *(iter++)); + CHECK_EQ(static_cast(54), *(iter++)); + CHECK_EQ(static_cast(69), *(iter++)); + CHECK_EQ(static_cast(72), *(iter++)); - BOOST_TEST(static_cast(42) == deq.at(0)); - BOOST_TEST(static_cast(54) == deq.at(1)); - BOOST_TEST(static_cast(69) == deq.at(2)); - BOOST_TEST(static_cast(72) == deq.at(3)); + CHECK_EQ(static_cast(42), deq.at(0)); + CHECK_EQ(static_cast(54), deq.at(1)); + CHECK_EQ(static_cast(69), deq.at(2)); + CHECK_EQ(static_cast(72), deq.at(3)); std::array ary = toml::find>(std::move(v4), "key"); - BOOST_TEST(42 == ary.at(0)); - BOOST_TEST(54 == ary.at(1)); - BOOST_TEST(69 == ary.at(2)); - BOOST_TEST(72 == ary.at(3)); + CHECK_EQ(42, ary.at(0)); + CHECK_EQ(54, ary.at(1)); + CHECK_EQ(69, ary.at(2)); + CHECK_EQ(72, ary.at(3)); std::tuple tpl = toml::find>(std::move(v5), "key"); - BOOST_TEST( 42 == std::get<0>(tpl)); - BOOST_TEST(static_cast(54) == std::get<1>(tpl)); - BOOST_TEST(static_cast(69) == std::get<2>(tpl)); - BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + CHECK_EQ( 42 , std::get<0>(tpl)); + CHECK_EQ(static_cast(54), std::get<1>(tpl)); + CHECK_EQ(static_cast(69), std::get<2>(tpl)); + CHECK_EQ(static_cast(72), std::get<3>(tpl)); - value_type p{{"key", {3.14, 2.71}}}; + value_type p = toml::table{{"key", toml::array{3.14, 2.71}}}; std::pair pr = toml::find >(std::move(p), "key"); - BOOST_TEST(3.14 == pr.first); - BOOST_TEST(2.71 == pr.second); + CHECK_EQ(3.14, pr.first); + CHECK_EQ(2.71, pr.second); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_value_types) +TEST_CASE("testing toml::find array of array conversion") { - value_type v1{42, 54, 69, 72}; - value_type v2{"foo", "bar", "baz"}; - value_type v{{"key", {v1, v2}}}; + using value_type = toml::value; + + value_type v1 = toml::array{42, 54, 69, 72}; + value_type v2 = toml::array{"foo", "bar", "baz"}; + value_type v = toml::table{{"key", toml::array{v1, v2}}}; std::pair, std::vector> p = toml::find, std::vector>>(v, "key"); - BOOST_TEST(p.first.at(0) == 42); - BOOST_TEST(p.first.at(1) == 54); - BOOST_TEST(p.first.at(2) == 69); - BOOST_TEST(p.first.at(3) == 72); + CHECK_EQ(p.first.at(0), 42); + CHECK_EQ(p.first.at(1), 54); + CHECK_EQ(p.first.at(2), 69); + CHECK_EQ(p.first.at(3), 72); - BOOST_TEST(p.second.at(0) == "foo"); - BOOST_TEST(p.second.at(1) == "bar"); - BOOST_TEST(p.second.at(2) == "baz"); + CHECK_EQ(p.second.at(0), "foo"); + CHECK_EQ(p.second.at(1), "bar"); + CHECK_EQ(p.second.at(2), "baz"); std::tuple, std::vector> t = toml::find, std::vector>>(v, "key"); - BOOST_TEST(std::get<0>(t).at(0) == 42); - BOOST_TEST(std::get<0>(t).at(1) == 54); - BOOST_TEST(std::get<0>(t).at(2) == 69); - BOOST_TEST(std::get<0>(t).at(3) == 72); + CHECK_EQ(std::get<0>(t).at(0), 42); + CHECK_EQ(std::get<0>(t).at(1), 54); + CHECK_EQ(std::get<0>(t).at(2), 69); + CHECK_EQ(std::get<0>(t).at(3), 72); - BOOST_TEST(std::get<1>(t).at(0) == "foo"); - BOOST_TEST(std::get<1>(t).at(1) == "bar"); - BOOST_TEST(std::get<1>(t).at(2) == "baz"); + CHECK_EQ(std::get<1>(t).at(0), "foo"); + CHECK_EQ(std::get<1>(t).at(1), "bar"); + CHECK_EQ(std::get<1>(t).at(2), "baz"); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array_of_array, value_type, test_value_types) +TEST_CASE("testing toml::find array of array move conversion") { - value_type a1{42, 54, 69, 72}; - value_type a2{"foo", "bar", "baz"}; - value_type v1{{"key", {a1, a2}}}; - value_type v2{{"key", {a1, a2}}}; + using value_type = toml::value; + + value_type a1 = toml::array{42, 54, 69, 72}; + value_type a2 = toml::array{"foo", "bar", "baz"}; + value_type v1 = toml::table{{"key", toml::array{a1, a2}}}; + value_type v2 = toml::table{{"key", toml::array{a1, a2}}}; std::pair, std::vector> p = toml::find, std::vector>>(std::move(v1), "key"); - BOOST_TEST(p.first.at(0) == 42); - BOOST_TEST(p.first.at(1) == 54); - BOOST_TEST(p.first.at(2) == 69); - BOOST_TEST(p.first.at(3) == 72); + CHECK_EQ(p.first.at(0), 42); + CHECK_EQ(p.first.at(1), 54); + CHECK_EQ(p.first.at(2), 69); + CHECK_EQ(p.first.at(3), 72); - BOOST_TEST(p.second.at(0) == "foo"); - BOOST_TEST(p.second.at(1) == "bar"); - BOOST_TEST(p.second.at(2) == "baz"); + CHECK_EQ(p.second.at(0), "foo"); + CHECK_EQ(p.second.at(1), "bar"); + CHECK_EQ(p.second.at(2), "baz"); std::tuple, std::vector> t = toml::find, std::vector>>(std::move(v2), "key"); - BOOST_TEST(std::get<0>(t).at(0) == 42); - BOOST_TEST(std::get<0>(t).at(1) == 54); - BOOST_TEST(std::get<0>(t).at(2) == 69); - BOOST_TEST(std::get<0>(t).at(3) == 72); + CHECK_EQ(std::get<0>(t).at(0), 42); + CHECK_EQ(std::get<0>(t).at(1), 54); + CHECK_EQ(std::get<0>(t).at(2), 69); + CHECK_EQ(std::get<0>(t).at(3), 72); - BOOST_TEST(std::get<1>(t).at(0) == "foo"); - BOOST_TEST(std::get<1>(t).at(1) == "bar"); - BOOST_TEST(std::get<1>(t).at(2) == "baz"); + CHECK_EQ(std::get<1>(t).at(0), "foo"); + CHECK_EQ(std::get<1>(t).at(1), "bar"); + CHECK_EQ(std::get<1>(t).at(2), "baz"); } - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_table, value_type, test_value_types) +TEST_CASE("testing toml::find table conversion") { + using value_type = toml::value; { - value_type v1{{"key", { + value_type v1 = toml::table{{"key", toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} }}}; const auto v = toml::find>(v1, "key"); - BOOST_TEST(v.at("key1") == 1); - BOOST_TEST(v.at("key2") == 2); - BOOST_TEST(v.at("key3") == 3); - BOOST_TEST(v.at("key4") == 4); + CHECK_EQ(v.at("key1"), 1); + CHECK_EQ(v.at("key2"), 2); + CHECK_EQ(v.at("key3"), 3); + CHECK_EQ(v.at("key4"), 4); } { - value_type v1{{"key", { + value_type v1 = toml::table{{"key", toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} }}}; const auto v = toml::find>(std::move(v1), "key"); - BOOST_TEST(v.at("key1") == 1); - BOOST_TEST(v.at("key2") == 2); - BOOST_TEST(v.at("key3") == 3); - BOOST_TEST(v.at("key4") == 4); + CHECK_EQ(v.at("key1"), 1); + CHECK_EQ(v.at("key2"), 2); + CHECK_EQ(v.at("key3"), 3); + CHECK_EQ(v.at("key4"), 4); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_types) +TEST_CASE("testing toml::find local_date") { + using value_type = toml::value; { - value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; + value_type v1 = toml::table{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; const auto date = std::chrono::system_clock::to_time_t( toml::find(v1, "key")); @@ -678,10 +830,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_ t.tm_sec = 0; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } { - value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; + value_type v1 = toml::table{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; const auto date = std::chrono::system_clock::to_time_t( toml::find(std::move(v1), "key")); @@ -694,30 +846,32 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_ t.tm_sec = 0; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_time, value_type, test_value_types) +TEST_CASE("testing toml::find local_time") { + using value_type = toml::value; { - value_type v1{{"key", toml::local_time{12, 30, 45}}}; + value_type v1 = toml::table{{"key", toml::local_time{12, 30, 45}}}; const auto time = toml::find(v1, "key"); - BOOST_CHECK(time == std::chrono::hours(12) + + CHECK_EQ(time, std::chrono::hours(12) + std::chrono::minutes(30) + std::chrono::seconds(45)); } { - value_type v1{{"key", toml::local_time{12, 30, 45}}}; + value_type v1 = toml::table{{"key", toml::local_time{12, 30, 45}}}; const auto time = toml::find(std::move(v1), "key"); - BOOST_CHECK(time == std::chrono::hours(12) + + CHECK_EQ(time, std::chrono::hours(12) + std::chrono::minutes(30) + std::chrono::seconds(45)); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_value_types) +TEST_CASE("testing toml::find local_datetime") { + using value_type = toml::value; { - value_type v1{{"key", toml::local_datetime( + value_type v1 = toml::table{{"key", toml::local_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 45})}}; @@ -732,10 +886,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_va t.tm_sec = 45; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } { - value_type v1{{"key", toml::local_datetime( + value_type v1 = toml::table{{"key", toml::local_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 45})}}; @@ -750,78 +904,79 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_va t.tm_sec = 45; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) +TEST_CASE("testing toml::find offset_datetime") { + using value_type = toml::value; { - value_type v1{{"key", toml::offset_datetime( + value_type v1 = toml::table{{"key", toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{9, 0})}}; // 2018-04-01T12:30:00+09:00 - // == 2018-04-01T03:30:00Z + //, 2018-04-01T03:30:00Z const auto date = toml::find(v1, "key"); const auto timet = std::chrono::system_clock::to_time_t(date); // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_CHECK(tmp); + CHECK_UNARY(tmp); const auto tm = *tmp; - BOOST_TEST(tm.tm_year + 1900 == 2018); - BOOST_TEST(tm.tm_mon + 1 == 4); - BOOST_TEST(tm.tm_mday == 1); - BOOST_TEST(tm.tm_hour == 3); - BOOST_TEST(tm.tm_min == 30); - BOOST_TEST(tm.tm_sec == 0); + CHECK_EQ(tm.tm_year + 1900, 2018); + CHECK_EQ(tm.tm_mon + 1, 4); + CHECK_EQ(tm.tm_mday, 1); + CHECK_EQ(tm.tm_hour, 3); + CHECK_EQ(tm.tm_min, 30); + CHECK_EQ(tm.tm_sec, 0); } { - value_type v1{{"key", toml::offset_datetime( + value_type v1 = toml::table{{"key", toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{-8, 0})}}; // 2018-04-01T12:30:00-08:00 - // == 2018-04-01T20:30:00Z + //, 2018-04-01T20:30:00Z const auto date = toml::find(v1, "key"); const auto timet = std::chrono::system_clock::to_time_t(date); // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_CHECK(tmp); + CHECK_UNARY(tmp); const auto tm = *tmp; - BOOST_TEST(tm.tm_year + 1900 == 2018); - BOOST_TEST(tm.tm_mon + 1 == 4); - BOOST_TEST(tm.tm_mday == 1); - BOOST_TEST(tm.tm_hour == 20); - BOOST_TEST(tm.tm_min == 30); - BOOST_TEST(tm.tm_sec == 0); + CHECK_EQ(tm.tm_year + 1900, 2018); + CHECK_EQ(tm.tm_mon + 1, 4); + CHECK_EQ(tm.tm_mday, 1); + CHECK_EQ(tm.tm_hour, 20); + CHECK_EQ(tm.tm_min, 30); + CHECK_EQ(tm.tm_sec, 0); } { - value_type v1{{"key", toml::offset_datetime( + value_type v1 = toml::table{{"key", toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{-8, 0})}}; // 2018-04-01T12:30:00-08:00 - // == 2018-04-01T20:30:00Z + //, 2018-04-01T20:30:00Z const auto date = toml::find(std::move(v1), "key"); const auto timet = std::chrono::system_clock::to_time_t(date); // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_CHECK(tmp); + CHECK_UNARY(tmp); const auto tm = *tmp; - BOOST_TEST(tm.tm_year + 1900 == 2018); - BOOST_TEST(tm.tm_mon + 1 == 4); - BOOST_TEST(tm.tm_mday == 1); - BOOST_TEST(tm.tm_hour == 20); - BOOST_TEST(tm.tm_min == 30); - BOOST_TEST(tm.tm_sec == 0); + CHECK_EQ(tm.tm_year + 1900, 2018); + CHECK_EQ(tm.tm_mon + 1, 4); + CHECK_EQ(tm.tm_mday, 1); + CHECK_EQ(tm.tm_hour, 20); + CHECK_EQ(tm.tm_min, 30); + CHECK_EQ(tm.tm_sec, 0); } } diff --git a/tests/test_find_or.cpp b/tests/test_find_or.cpp index 8348f2f..a3dea0c 100644 --- a/tests/test_find_or.cpp +++ b/tests/test_find_or.cpp @@ -1,6 +1,10 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include "utility.hpp" + +#include +#include #include #include @@ -13,235 +17,179 @@ #include #endif -using test_value_types = std::tuple< - toml::basic_value, - toml::basic_value, - toml::basic_value, - toml::basic_value ->; +#define TOML11_TEST_FIND_OR_EXACT(ty, init_expr, opt_expr)\ + { \ + const ty init init_expr ; \ + const ty opt opt_expr ; \ + const value_type v = toml::table{{"key", init}}; \ + CHECK_NE(init, opt); \ + CHECK_EQ(init, toml::find_or(v, "key", opt)); \ + } -namespace test +TEST_CASE("testing toml::find_or with toml types") { -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::vector& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::deque& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::list& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::unordered_map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -} // test + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; -#define TOML11_TEST_FIND_OR_EXACT(toml_type, init_expr, opt_expr)\ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - const toml::toml_type opt opt_expr ; \ - const value_type v{{"key", init}}; \ - BOOST_TEST(init != opt); \ - BOOST_TEST(init == toml::find_or(v, "key", opt)); \ - } \ - /**/ - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types) -{ - TOML11_TEST_FIND_OR_EXACT(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_EXACT(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_EXACT(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_EXACT(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_EXACT(local_datetime, + TOML11_TEST_FIND_OR_EXACT(boolean_type, ( true), (false)) + TOML11_TEST_FIND_OR_EXACT(integer_type, ( 42), ( 54)) + TOML11_TEST_FIND_OR_EXACT(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_EXACT(string_type, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_EXACT(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_EXACT(local_date_type, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_FIND_OR_EXACT(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) ) - TOML11_TEST_FIND_OR_EXACT(offset_datetime, + TOML11_TEST_FIND_OR_EXACT(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) ) - { - const typename value_type::array_type init{1,2,3,4,5}; - const typename value_type::array_type opt {6,7,8,9,10}; - const value_type v{{"key", init}}; - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::find_or(v, "key", opt)); - } - { - const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - const value_type v{{"key", init}}; - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::find_or(v, "key", opt)); - } + TOML11_TEST_FIND_OR_EXACT(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_FIND_OR_EXACT(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); } #undef TOML11_TEST_FIND_OR_EXACT -#define TOML11_TEST_FIND_OR_MOVE(toml_type, init_expr, opt_expr) \ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt opt_expr ; \ - value_type v{{"key", init}}; \ - BOOST_TEST(init != opt); \ +#define TOML11_TEST_FIND_OR_MOVE(ty, init_expr, opt_expr) \ + { \ + const ty init init_expr ; \ + ty opt opt_expr ; \ + value_type v = toml::table{{"key", init}}; \ + CHECK_NE(init, opt); \ const auto moved = toml::find_or(std::move(v), "key", std::move(opt));\ - BOOST_TEST(init == moved); \ - } \ - /**/ + CHECK_EQ(init, moved); \ + } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move, value_type, test_value_types) +TEST_CASE("testing toml::find_or with moved argument") { - TOML11_TEST_FIND_OR_MOVE(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_MOVE(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_MOVE(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_MOVE(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_MOVE(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_MOVE(local_date, (2019, toml::month_t::Apr, 1), + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + + TOML11_TEST_FIND_OR_MOVE(boolean_type, ( true), (false)) + TOML11_TEST_FIND_OR_MOVE(integer_type, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MOVE(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MOVE(string_type, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MOVE(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MOVE(local_date_type, (2019, toml::month_t::Apr, 1), (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_MOVE(local_datetime, + TOML11_TEST_FIND_OR_MOVE(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) ) - TOML11_TEST_FIND_OR_MOVE(offset_datetime, + TOML11_TEST_FIND_OR_MOVE(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) ) - { - typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt {6,7,8,9,10}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt); - const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); - BOOST_TEST(init == moved); - } - { - typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt); - const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); - BOOST_TEST(init == moved); - } + TOML11_TEST_FIND_OR_MOVE(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_FIND_OR_MOVE(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); } #undef TOML11_TEST_FIND_OR_MOVE -#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt1 opt_expr ; \ - toml::toml_type opt2 opt_expr ; \ - value_type v{{"key", init}}; \ - BOOST_TEST(init != opt1); \ - toml::find_or(v, "key", opt2) = opt1; \ - BOOST_TEST(opt1 == toml::find(v, "key"));\ - } \ - /**/ -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_modify, value_type, test_value_types) +#define TOML11_TEST_FIND_OR_MODIFY(ty, init_expr, opt_expr)\ + { \ + const ty init init_expr ; \ + ty opt1 opt_expr ; \ + ty opt2 opt_expr ; \ + value_type v = toml::table{{"key", init}}; \ + CHECK_NE(init, opt1); \ + toml::find_or(v, "key", opt2) = opt1; \ + CHECK_EQ(opt1, toml::find(v, "key")); \ + } + +TEST_CASE("testing find_or with modification") { - TOML11_TEST_FIND_OR_MODIFY(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_MODIFY(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_MODIFY(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_MODIFY(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + TOML11_TEST_FIND_OR_MODIFY(boolean_type, ( true), (false)) + TOML11_TEST_FIND_OR_MODIFY(integer_type, ( 42), ( 54)) + TOML11_TEST_FIND_OR_MODIFY(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_FIND_OR_MODIFY(string_type, ("foo"), ("bar")) + TOML11_TEST_FIND_OR_MODIFY(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_FIND_OR_MODIFY(local_date_type, (2019, toml::month_t::Apr, 1), (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_MODIFY(local_datetime, + TOML11_TEST_FIND_OR_MODIFY(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) ) - TOML11_TEST_FIND_OR_MODIFY(offset_datetime, + TOML11_TEST_FIND_OR_MODIFY(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) ) - { - typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt1{6,7,8,9,10}; - typename value_type::array_type opt2{6,7,8,9,10}; - BOOST_TEST(init != opt1); - value_type v{{"key", init}}; - toml::find_or(v, "key", opt2) = opt1; - BOOST_TEST(opt1 == toml::find(v, "key")); - } - { - typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; - typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt1); - toml::find_or(v, "key", opt2) = opt1; - BOOST_TEST(opt1 == toml::find(v, "key")); - } + + TOML11_TEST_FIND_OR_MODIFY(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_FIND_OR_MODIFY(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); } #undef TOML11_TEST_FIND_OR_MODIFY -#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \ - { \ - using namespace test; \ - value_type v(init_type); \ - BOOST_TEST(opt_type == toml::find_or(v, "key", opt_type));\ - } \ - /**/ +#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \ + { \ + value_type v1(init_type); \ + CHECK_EQ(opt_type, toml::find_or(v1, "key", opt_type)); \ + value_type v2 = toml::table{{"different_key", init_type}}; \ + CHECK_EQ(opt_type, toml::find_or(v2, "key", opt_type)); \ + } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_types) +TEST_CASE("testing toml::find_or returns fallback if failed") { - const toml::boolean boolean (true); - const toml::integer integer (42); - const toml::floating floating (3.14); - const toml::string string ("foo"); - const toml::local_time local_time (12, 30, 45); - const toml::local_date local_date (2019, toml::month_t::Apr, 1); - const toml::local_datetime local_datetime ( + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + const boolean_type boolean (true); + const integer_type integer (42); + const floating_type floating (3.14); + const string_type string ("foo"); + const local_time_type local_time (12, 30, 45); + const local_date_type local_date (2019, toml::month_t::Apr, 1); + const local_datetime_type local_datetime ( toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)); - const toml::offset_datetime offset_datetime( + const offset_datetime_type offset_datetime( toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); - using array_type = typename value_type::array_type; - using table_type = typename value_type::table_type; const array_type array{1, 2, 3, 4, 5}; const table_type table{{"key1", 42}, {"key2", "foo"}}; @@ -347,46 +295,46 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_type } #undef TOML11_TEST_FIND_OR_FALLBACK -BOOST_AUTO_TEST_CASE(test_find_or_integer) +TEST_CASE("testing find_or; converting to an integer") { { - toml::value v{{"num", 42}}; - BOOST_TEST(42u == toml::find_or(v, "num", 0u)); - BOOST_TEST(0u == toml::find_or(v, "foo", 0u)); + toml::value v = toml::table{{"num", 42}}; + CHECK_EQ(42u, toml::find_or(v, "num", 0u)); + CHECK_EQ(0u , toml::find_or(v, "foo", 0u)); } { - toml::value v{{"num", 42}}; + toml::value v = toml::table{{"num", 42}}; const auto moved = toml::find_or(std::move(v), "num", 0u); - BOOST_TEST(42u == moved); + CHECK_EQ(42u, moved); } { - toml::value v{{"num", 42}}; + toml::value v = toml::table{{"num", 42}}; const auto moved = toml::find_or(std::move(v), "foo", 0u); - BOOST_TEST(0u == moved); + CHECK_EQ(0u, moved); } } -BOOST_AUTO_TEST_CASE(test_find_or_floating) +TEST_CASE("testing find_or; converting to a floating") { { - toml::value v1{{"key", 42}}; - toml::value v2{{"key", 3.14}}; - BOOST_TEST(2.71f == toml::find_or(v1, "key", 2.71f)); + toml::value v1 = toml::table{{"key", 42}}; + toml::value v2 = toml::table{{"key", 3.14}}; + CHECK_EQ(2.71f, toml::find_or(v1, "key", 2.71f)); const double ref(3.14); - BOOST_TEST(static_cast(ref) == toml::find_or(v2, "key", 2.71f)); + CHECK_EQ(static_cast(ref), toml::find_or(v2, "key", 2.71f)); } { - toml::value v1{{"key", 42}}; - toml::value v2{{"key", 3.14}}; + toml::value v1 = toml::table{{"key", 42}}; + toml::value v2 = toml::table{{"key", 3.14}}; const auto moved1 = toml::find_or(std::move(v1), "key", 2.71f); const auto moved2 = toml::find_or(std::move(v2), "key", 2.71f); - BOOST_TEST(2.71f == moved1); + CHECK_EQ(2.71f, moved1); const double ref(3.14); - BOOST_TEST(static_cast(ref) == moved2); + CHECK_EQ(static_cast(ref), moved2); } } -BOOST_AUTO_TEST_CASE(test_find_or_string) +TEST_CASE("testing find_or; converting to a string") { { toml::value v1 = toml::table{{"key", "foobar"}}; @@ -395,21 +343,21 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) std::string s1("bazqux"); const std::string s2("bazqux"); - BOOST_TEST("foobar" == toml::find_or(v1, "key", s1)); - BOOST_TEST("bazqux" == toml::find_or(v2, "key", s1)); + CHECK_EQ("foobar", toml::find_or(v1, "key", s1)); + CHECK_EQ("bazqux", toml::find_or(v2, "key", s1)); std::string& v1r = toml::find_or(v1, "key", s1); std::string& s1r = toml::find_or(v2, "key", s1); - BOOST_TEST("foobar" == v1r); - BOOST_TEST("bazqux" == s1r); + CHECK_EQ("foobar", v1r); + CHECK_EQ("bazqux", s1r); - BOOST_TEST("foobar" == toml::find_or(v1, "key", s2)); - BOOST_TEST("bazqux" == toml::find_or(v2, "key", s2)); + CHECK_EQ("foobar", toml::find_or(v1, "key", s2)); + CHECK_EQ("bazqux", toml::find_or(v2, "key", s2)); - BOOST_TEST("foobar" == toml::find_or(std::move(v1), "key", std::move(s1))); + CHECK_EQ("foobar", toml::find_or(std::move(v1), "key", std::move(s1))); s1 = "bazqux"; // restoring moved value - BOOST_TEST("bazqux" == toml::find_or(std::move(v2), "key", std::move(s1))); + CHECK_EQ("bazqux", toml::find_or(std::move(v2), "key", std::move(s1))); } { toml::value v1 = toml::table{{"key", "foobar"}}; @@ -420,8 +368,8 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) const auto moved1 = toml::find_or(std::move(v1), "key", s1); const auto moved2 = toml::find_or(std::move(v2), "key", s1); - BOOST_TEST("foobar" == moved1); - BOOST_TEST("bazqux" == moved2); + CHECK_EQ("foobar", moved1); + CHECK_EQ("bazqux", moved2); } { toml::value v1 = toml::table{{"key", "foobar"}}; @@ -433,8 +381,8 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) const auto moved1 = toml::find_or(std::move(v1), "key", std::move(s1)); const auto moved2 = toml::find_or(std::move(v2), "key", std::move(s2)); - BOOST_TEST("foobar" == moved1); - BOOST_TEST("bazqux" == moved2); + CHECK_EQ("foobar", moved1); + CHECK_EQ("bazqux", moved2); } // string literal @@ -442,12 +390,12 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) toml::value v1 = toml::table{{"key", "foobar"}}; toml::value v2 = toml::table{{"key",42}}; - BOOST_TEST("foobar" == toml::find_or(v1, "key", "bazqux")); - BOOST_TEST("bazqux" == toml::find_or(v2, "key", "bazqux")); + CHECK_EQ("foobar", toml::find_or(v1, "key", "bazqux")); + CHECK_EQ("bazqux", toml::find_or(v2, "key", "bazqux")); - const char* lit = "bazqux"; - BOOST_TEST("foobar" == toml::find_or(v1, "key", lit)); - BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit)); + const auto lit = "bazqux"; + CHECK_EQ("foobar", toml::find_or(v1, "key", lit)); + CHECK_EQ("bazqux", toml::find_or(v2, "key", lit)); } { toml::value v1 = toml::table{{"key", "foobar"}}; @@ -456,8 +404,8 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) const auto moved1 = toml::find_or(std::move(v1), "key", "bazqux"); const auto moved2 = toml::find_or(std::move(v2), "key", "bazqux"); - BOOST_TEST("foobar" == moved1); - BOOST_TEST("bazqux" == moved2); + CHECK_EQ("foobar", moved1); + CHECK_EQ("bazqux", moved2); } { toml::value v1 = toml::table{{"key", "foobar"}}; @@ -467,72 +415,155 @@ BOOST_AUTO_TEST_CASE(test_find_or_string) const auto moved1 = toml::find_or(std::move(v1), "key", lit); const auto moved2 = toml::find_or(std::move(v2), "key", lit); - BOOST_TEST("foobar" == moved1); - BOOST_TEST("bazqux" == moved2); + CHECK_EQ("foobar", moved1); + CHECK_EQ("bazqux", moved2); } - } -BOOST_AUTO_TEST_CASE(test_find_or_map) +TEST_CASE("testing find_or; converting to a map") { using map_type = std::map; { - const toml::value v1{ - {"key", {{"key", "value"}}} + const toml::value v1 = toml::table{ + {"key", toml::table{{"key", "value"}}} }; const auto key = toml::find_or(v1, "key", map_type{}); const auto key2 = toml::find_or(v1, "key2", map_type{}); - BOOST_TEST(!key.empty()); - BOOST_TEST(key2.empty()); + CHECK_UNARY(!key.empty()); + CHECK_UNARY(key2.empty()); - BOOST_TEST(key.size() == 1u); - BOOST_TEST(key.at("key") == "value"); + CHECK_EQ(key.size() , 1u); + CHECK_EQ(key.at("key"), "value"); } { - toml::value v1{ - {"key", {{"key", "value"}}} + toml::value v1 = toml::table{ + {"key", toml::table{{"key", "value"}}} }; const auto key = toml::find_or(v1, "key", map_type{}); const auto key2 = toml::find_or(v1, "key2", map_type{}); - BOOST_TEST(!key.empty()); - BOOST_TEST(key2.empty()); + CHECK_UNARY(!key.empty()); + CHECK_UNARY(key2.empty()); - BOOST_TEST(key.size() == 1u); - BOOST_TEST(key.at("key") == "value"); + CHECK_EQ(key.size() , 1u); + CHECK_EQ(key.at("key"), "value"); } { - toml::value v1{ - {"key", {{"key", "value"}}} + toml::value v1 = toml::table{ + {"key", toml::table{{"key", "value"}}} }; toml::value v2(v1); const auto key = toml::find_or(std::move(v1), "key", map_type{}); const auto key2 = toml::find_or(std::move(v2), "key2", map_type{}); - BOOST_TEST(!key.empty()); - BOOST_TEST(key2.empty()); + CHECK_UNARY(!key.empty()); + CHECK_UNARY(key2.empty()); - BOOST_TEST(key.size() == 1u); - BOOST_TEST(key.at("key") == "value"); + CHECK_EQ(key.size() , 1u); + CHECK_EQ(key.at("key"), "value"); } { - toml::value v1{ - {"key", {{"key", "value"}}} + toml::value v1 = toml::table{ + {"key", toml::table{{"key", "value"}}} }; toml::value v2(v1); const auto key = toml::find_or(std::move(v1), "key", map_type{}); const auto key2 = toml::find_or(std::move(v2), "key2", map_type{}); - BOOST_TEST(!key.empty()); - BOOST_TEST(key2.empty()); + CHECK_UNARY(!key.empty()); + CHECK_UNARY(key2.empty()); - BOOST_TEST(key.size() == 1u); - BOOST_TEST(key.at("key") == "value"); + CHECK_EQ(key.size() , 1u); + CHECK_EQ(key.at("key"), "value"); + } +} + +TEST_CASE("testing find_or(val, keys..., opt)") +{ + // &, using type deduction + { + toml::value v( + toml::table{ {"foo", + toml::table{ {"bar", + toml::table{ {"baz", + "qux" + } } + } } + } } + ); + std::string opt("hoge"); + + auto& v1 = toml::find_or(v, "foo", "bar", "baz", opt); + auto& v2 = toml::find_or(v, "foo", "bar", "qux", opt); + + CHECK_EQ(v1, "qux"); + CHECK_EQ(v2, "hoge"); + + v1 = "hoge"; + v2 = "fuga"; + + CHECK_EQ(v1, "hoge"); + CHECK_EQ(v2, "fuga"); + } + + // const&, type deduction + { + const toml::value v( + toml::table{ {"foo", + toml::table{ {"bar", + toml::table{ {"baz", + "qux" + } } + } } + } } + ); + std::string opt("hoge"); + + const auto& v1 = toml::find_or(v, "foo", "bar", "baz", opt); + const auto& v2 = toml::find_or(v, "foo", "bar", "qux", opt); + + CHECK_EQ(v1, "qux"); + CHECK_EQ(v2, "hoge"); + } + + // explicitly specify type, doing type conversion + { + const toml::value v( + toml::table{ {"foo", + toml::table{ {"bar", + toml::table{ {"baz", + 42 + } } + } } + } } + ); + int opt = 6 * 9; + + auto v1 = toml::find_or(v, "foo", "bar", "baz", opt); + auto v2 = toml::find_or(v, "foo", "bar", "qux", opt); + + CHECK_EQ(v1, 42); + CHECK_EQ(v2, 6*9); + } + + { + const toml::value v( + toml::table{ {"foo", + toml::table{ {"bar", + toml::table{ {"baz", + 42 + } } + } } + } } + ); + auto v1 = toml::find_or(v, "foo", "bar", "baz", "hoge"); + + CHECK_EQ(v1, "hoge"); } } diff --git a/tests/test_find_or_recursive.cpp b/tests/test_find_or_recursive.cpp deleted file mode 100644 index 1f2f480..0000000 --- a/tests/test_find_or_recursive.cpp +++ /dev/null @@ -1,393 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include -#include -#include -#include -#include - -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L -#include -#endif - -using test_value_types = std::tuple< - toml::basic_value, - toml::basic_value, - toml::basic_value, - toml::basic_value ->; - -namespace test -{ -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::vector& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::deque& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::list& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::unordered_map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -} // test - -#define TOML11_TEST_FIND_OR_EXACT(toml_type, init_expr, opt_expr) \ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - const toml::toml_type opt opt_expr ; \ - const value_type v{{"key1", value_type{{"key2", init}} }};\ - BOOST_TEST(init != opt); \ - BOOST_TEST(init == toml::find_or(v, "key1", "key2", opt));\ - } \ - /**/ - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types) -{ - TOML11_TEST_FIND_OR_EXACT(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_EXACT(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_EXACT(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_EXACT(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_EXACT(local_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) - ) - TOML11_TEST_FIND_OR_EXACT(offset_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) - ) - { - const typename value_type::array_type init{1,2,3,4,5}; - const typename value_type::array_type opt {6,7,8,9,10}; - const value_type v{{"key", init}}; - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::find_or(v, "key", opt)); - } - { - const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - const value_type v{{"key", init}}; - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::find_or(v, "key", opt)); - } -} -#undef TOML11_TEST_FIND_OR_EXACT - -#define TOML11_TEST_FIND_OR_MOVE(toml_type, init_expr, opt_expr) \ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt opt_expr ; \ - value_type v{{"key1", value_type{{"key2", init}} }}; \ - BOOST_TEST(init != opt); \ - const auto moved = toml::find_or(std::move(v), "key1", "key2", std::move(opt));\ - BOOST_TEST(init == moved); \ - } \ - /**/ - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move, value_type, test_value_types) -{ - TOML11_TEST_FIND_OR_MOVE(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_MOVE(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_MOVE(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_MOVE(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_MOVE(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_MOVE(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_MOVE(local_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) - ) - TOML11_TEST_FIND_OR_MOVE(offset_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) - ) - { - typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt {6,7,8,9,10}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt); - const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); - BOOST_TEST(init == moved); - } - { - typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt); - const auto moved = toml::find_or(std::move(v), "key", std::move(opt)); - BOOST_TEST(init == moved); - } -} -#undef TOML11_TEST_FIND_OR_MOVE - - -#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt1 opt_expr ; \ - toml::toml_type opt2 opt_expr ; \ - value_type v{{"key1", value_type{{"key2", init}} }}; \ - BOOST_TEST(init != opt1); \ - toml::find_or(v, "key1", "key2", opt2) = opt1; \ - BOOST_TEST(opt1 == toml::find(v, "key1", "key2"));\ - } \ - /**/ -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_modify, value_type, test_value_types) -{ - TOML11_TEST_FIND_OR_MODIFY(boolean, ( true), (false)) - TOML11_TEST_FIND_OR_MODIFY(integer, ( 42), ( 54)) - TOML11_TEST_FIND_OR_MODIFY(floating, ( 3.14), ( 2.71)) - TOML11_TEST_FIND_OR_MODIFY(string, ("foo"), ("bar")) - TOML11_TEST_FIND_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_FIND_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_FIND_OR_MODIFY(local_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) - ) - TOML11_TEST_FIND_OR_MODIFY(offset_datetime, - (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), - (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) - ) - { - typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt1{6,7,8,9,10}; - typename value_type::array_type opt2{6,7,8,9,10}; - BOOST_TEST(init != opt1); - value_type v{{"key", init}}; - toml::find_or(v, "key", opt2) = opt1; - BOOST_TEST(opt1 == toml::find(v, "key")); - } - { - typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; - typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; - value_type v{{"key", init}}; - BOOST_TEST(init != opt1); - toml::find_or(v, "key", opt2) = opt1; - BOOST_TEST(opt1 == toml::find(v, "key")); - } -} -#undef TOML11_TEST_FIND_OR_MODIFY - -#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \ - { \ - using namespace test; \ - value_type v1{{"key1", value_type{{"key3", "foo"}}}}; \ - BOOST_TEST(opt_type == toml::find_or(v1, "key1", "key2", opt_type));\ - value_type v2{{"key1", "foo"}}; \ - BOOST_TEST(opt_type == toml::find_or(v2, "key1", "key3", opt_type));\ - } \ - /**/ - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_types) -{ - const toml::boolean boolean (true); - const toml::integer integer (42); - const toml::floating floating (3.14); - const toml::string string ("foo"); - const toml::local_time local_time (12, 30, 45); - const toml::local_date local_date (2019, toml::month_t::Apr, 1); - const toml::local_datetime local_datetime ( - toml::local_date(2019, toml::month_t::Apr, 1), - toml::local_time(12, 30, 45)); - const toml::offset_datetime offset_datetime( - toml::local_date(2019, toml::month_t::Apr, 1), - toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); - - using array_type = typename value_type::array_type; - using table_type = typename value_type::table_type; - const array_type array{1, 2, 3, 4, 5}; - const table_type table{{"key1", 42}, {"key2", "foo"}}; - - TOML11_TEST_FIND_OR_FALLBACK(boolean, integer ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, floating ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, string ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(boolean, array ); - TOML11_TEST_FIND_OR_FALLBACK(boolean, table ); - - TOML11_TEST_FIND_OR_FALLBACK(integer, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(integer, floating ); - TOML11_TEST_FIND_OR_FALLBACK(integer, string ); - TOML11_TEST_FIND_OR_FALLBACK(integer, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(integer, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(integer, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(integer, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(integer, array ); - TOML11_TEST_FIND_OR_FALLBACK(integer, table ); - - TOML11_TEST_FIND_OR_FALLBACK(floating, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(floating, integer ); - TOML11_TEST_FIND_OR_FALLBACK(floating, string ); - TOML11_TEST_FIND_OR_FALLBACK(floating, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(floating, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(floating, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(floating, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(floating, array ); - TOML11_TEST_FIND_OR_FALLBACK(floating, table ); - - TOML11_TEST_FIND_OR_FALLBACK(string, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(string, integer ); - TOML11_TEST_FIND_OR_FALLBACK(string, floating ); - TOML11_TEST_FIND_OR_FALLBACK(string, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(string, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(string, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(string, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(string, array ); - TOML11_TEST_FIND_OR_FALLBACK(string, table ); - - TOML11_TEST_FIND_OR_FALLBACK(local_time, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, integer ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, floating ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, string ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(local_time, array ); - TOML11_TEST_FIND_OR_FALLBACK(local_time, table ); - - TOML11_TEST_FIND_OR_FALLBACK(local_date, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, integer ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, floating ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, string ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(local_date, array ); - TOML11_TEST_FIND_OR_FALLBACK(local_date, table ); - - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, integer ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, floating ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, string ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, array ); - TOML11_TEST_FIND_OR_FALLBACK(local_datetime, table ); - - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, integer ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, floating ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, string ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, array ); - TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, table ); - - TOML11_TEST_FIND_OR_FALLBACK(array, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(array, integer ); - TOML11_TEST_FIND_OR_FALLBACK(array, floating ); - TOML11_TEST_FIND_OR_FALLBACK(array, string ); - TOML11_TEST_FIND_OR_FALLBACK(array, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(array, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(array, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(array, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(array, table ); - - TOML11_TEST_FIND_OR_FALLBACK(table, boolean ); - TOML11_TEST_FIND_OR_FALLBACK(table, integer ); - TOML11_TEST_FIND_OR_FALLBACK(table, floating ); - TOML11_TEST_FIND_OR_FALLBACK(table, string ); - TOML11_TEST_FIND_OR_FALLBACK(table, local_time ); - TOML11_TEST_FIND_OR_FALLBACK(table, local_date ); - TOML11_TEST_FIND_OR_FALLBACK(table, local_datetime ); - TOML11_TEST_FIND_OR_FALLBACK(table, offset_datetime); - TOML11_TEST_FIND_OR_FALLBACK(table, array ); -} -#undef TOML11_TEST_FIND_OR_FALLBACK - -struct move_only_type -{ - explicit move_only_type(const std::string& n): name_(n) {} - - void from_toml(const toml::value& v) - { - this->name_ = toml::find(v, "name"); - return; - } - - move_only_type(): name_("default"){} - ~move_only_type() = default; - move_only_type(move_only_type&&) = default; - move_only_type& operator=(move_only_type&&) = default; - move_only_type(const move_only_type&) = delete; - move_only_type& operator=(const move_only_type&) = delete; - - bool operator==(const move_only_type& other) const noexcept {return this->name_ == other.name_;} - bool operator!=(const move_only_type& other) const noexcept {return this->name_ != other.name_;} - bool operator< (const move_only_type& other) const noexcept {return this->name_ < other.name_;} - bool operator<=(const move_only_type& other) const noexcept {return this->name_ <= other.name_;} - bool operator> (const move_only_type& other) const noexcept {return this->name_ > other.name_;} - bool operator>=(const move_only_type& other) const noexcept {return this->name_ >= other.name_;} - - std::string name_; -}; - -std::ostream& operator<<(std::ostream& os, const move_only_type& mot) -{ - os << mot.name_; - return os; -} - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move_only, value_type, test_value_types) -{ - const move_only_type ref("reference"); - move_only_type opt("optional"); - { - const value_type v{{"key1", value_type{{"key2", value_type{{"name", "reference"}} }} }}; - 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 deleted file mode 100644 index c00f845..0000000 --- a/tests/test_format_error.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include - -// to check it successfully compiles. it does not check the formatted string. - -BOOST_AUTO_TEST_CASE(test_1_value) -{ - toml::value val(42); - - { - const std::string pretty_error = - toml::format_error("[error] test error", val, "this is a value"); - std::cout << pretty_error << std::endl; - } - - { - const std::string pretty_error = - toml::format_error("[error] test error", val, "this is a value", - {"this is a hint"}); - std::cout << pretty_error << std::endl; - } -} - -BOOST_AUTO_TEST_CASE(test_2_values) -{ - toml::value v1(42); - toml::value v2(3.14); - { - const std::string pretty_error = - toml::format_error("[error] test error with two values", - v1, "this is the answer", - v2, "this is the pi"); - std::cout << pretty_error << std::endl; - } - - { - const std::string pretty_error = - toml::format_error("[error] test error with two values", - v1, "this is the answer", - v2, "this is the pi", - {"hint"}); - std::cout << pretty_error << std::endl; - } -} - -BOOST_AUTO_TEST_CASE(test_3_values) -{ - toml::value v1(42); - toml::value v2(3.14); - toml::value v3("foo"); - { - const std::string pretty_error = - toml::format_error("[error] test error with two values", - v1, "this is the answer", - v2, "this is the pi", - v3, "this is a meta-syntactic variable"); - std::cout << pretty_error << std::endl; - } - - { - const std::string pretty_error = - toml::format_error("[error] test error with two values", - v1, "this is the answer", - v2, "this is the pi", - v3, "this is a meta-syntactic variable", - {"hint 1", "hint 2"}); - std::cout << pretty_error << std::endl; - } -} diff --git a/tests/test_format_floating.cpp b/tests/test_format_floating.cpp new file mode 100644 index 0000000..275bc53 --- /dev/null +++ b/tests/test_format_floating.cpp @@ -0,0 +1,143 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include +#include +#include + +TEST_CASE("testing fractional float") +{ + auto fmt = [](std::size_t prec) { + toml::floating_format_info f; + f.fmt = toml::floating_format::fixed; + f.prec = prec; + return f; + }; + + auto format_as = [](const double f, int w) -> std::string { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << std::fixed << std::setprecision(w) << f; + return oss.str(); + }; + + CHECK_EQ(format_as( 1.0 , 1), toml::format(toml::value( 1.0 , fmt( 1)))); + CHECK_EQ(format_as( 0.1 , 1), toml::format(toml::value( 0.1 , fmt( 1)))); + CHECK_EQ(format_as( 0.001 , 3), toml::format(toml::value( 0.001 , fmt( 3)))); + CHECK_EQ(format_as( 0.1 , 3), toml::format(toml::value( 0.1 , fmt( 3)))); + CHECK_EQ(format_as( 3.14 , 2), toml::format(toml::value( 3.14 , fmt( 2)))); + CHECK_EQ(format_as(-3.14 , 2), toml::format(toml::value(-3.14 , fmt( 2)))); + CHECK_EQ(format_as( 3.141592653589, 12), toml::format(toml::value( 3.141592653589, fmt(12)))); + CHECK_EQ(format_as(-3.141592653589, 12), toml::format(toml::value(-3.141592653589, fmt(12)))); +} + +TEST_CASE("testing scientific float") +{ + auto fmt = [](std::size_t prec) { + toml::floating_format_info f; + f.fmt = toml::floating_format::scientific; + f.prec = prec; + return f; + }; + + auto format_as = [](const double f, int w) -> std::string { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << std::scientific << std::setprecision(w) << f; + return oss.str(); + }; + + CHECK_EQ(format_as( 1.0 , 1), toml::format(toml::value( 1.0 , fmt( 1)))); + CHECK_EQ(format_as( 0.1 , 1), toml::format(toml::value( 0.1 , fmt( 1)))); + CHECK_EQ(format_as( 0.001 , 3), toml::format(toml::value( 0.001 , fmt( 3)))); + CHECK_EQ(format_as( 0.1 , 3), toml::format(toml::value( 0.1 , fmt( 3)))); + CHECK_EQ(format_as( 3.14 , 2), toml::format(toml::value( 3.14 , fmt( 2)))); + CHECK_EQ(format_as(-3.14 , 2), toml::format(toml::value(-3.14 , fmt( 2)))); + CHECK_EQ(format_as( 3.141592653589, 12), toml::format(toml::value( 3.141592653589, fmt(12)))); + CHECK_EQ(format_as(-3.141592653589, 12), toml::format(toml::value(-3.141592653589, fmt(12)))); +} + +TEST_CASE("testing hex float") +{ + toml::spec s = toml::spec::v(1,0,0); + s.ext_hex_float = true; + + toml::floating_format_info fmt; + fmt.fmt = toml::floating_format::hex; + + auto format_as = [](const double f) -> std::string { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << std::hexfloat << f; + return oss.str(); + }; + + CHECK_EQ(format_as( 1.0 ), toml::format(toml::value( 1.0 , fmt), s)); + CHECK_EQ(format_as( 0.1 ), toml::format(toml::value( 0.1 , fmt), s)); + CHECK_EQ(format_as( 0.001 ), toml::format(toml::value( 0.001 , fmt), s)); + CHECK_EQ(format_as( 0.1 ), toml::format(toml::value( 0.1 , fmt), s)); + CHECK_EQ(format_as( 3.14 ), toml::format(toml::value( 3.14 , fmt), s)); + CHECK_EQ(format_as(-3.14 ), toml::format(toml::value(-3.14 , fmt), s)); + CHECK_EQ(format_as( 3.141592653589), toml::format(toml::value( 3.141592653589, fmt), s)); + CHECK_EQ(format_as(-3.141592653589), toml::format(toml::value(-3.141592653589, fmt), s)); +} + +TEST_CASE("testing suffix + fractional") +{ + toml::spec s = toml::spec::v(1,0,0); + s.ext_hex_float = true; + s.ext_num_suffix = true; + + auto fmt = [](std::string sfx) { + toml::floating_format_info f; + f.fmt = toml::floating_format::fixed; + f.suffix = sfx; + return f; + }; + + auto format_as = [](const double f, std::string sfx) -> std::string { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << std::fixed << f << "_" << sfx; + return oss.str(); + }; + + CHECK_EQ(format_as( 1.0 , "m" ), toml::format(toml::value( 1.0 , fmt("m" )), s)); + CHECK_EQ(format_as( 0.1 , "m" ), toml::format(toml::value( 0.1 , fmt("m" )), s)); + CHECK_EQ(format_as( 0.001 , "mm" ), toml::format(toml::value( 0.001 , fmt("mm" )), s)); + CHECK_EQ(format_as( 0.1 , "mm" ), toml::format(toml::value( 0.1 , fmt("mm" )), s)); + CHECK_EQ(format_as( 3.14 , "rad"), toml::format(toml::value( 3.14 , fmt("rad")), s)); + CHECK_EQ(format_as(-3.14 , "rad"), toml::format(toml::value(-3.14 , fmt("rad")), s)); + CHECK_EQ(format_as( 3.141592653589, "rad"), toml::format(toml::value( 3.141592653589, fmt("rad")), s)); + CHECK_EQ(format_as(-3.141592653589, "rad"), toml::format(toml::value(-3.141592653589, fmt("rad")), s)); +} + +TEST_CASE("testing suffix + scientific") +{ + toml::spec s = toml::spec::v(1,0,0); + s.ext_hex_float = true; + s.ext_num_suffix = true; + + auto fmt = [](std::string sfx) { + toml::floating_format_info f; + f.fmt = toml::floating_format::scientific; + f.suffix = sfx; + return f; + }; + + auto format_as = [](const double f, std::string sfx) -> std::string { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << std::scientific << f << "_" << sfx; + return oss.str(); + }; + + CHECK_EQ(format_as( 1.0 , "m" ), toml::format(toml::value( 1.0 , fmt("m" )), s)); + CHECK_EQ(format_as( 0.1 , "m" ), toml::format(toml::value( 0.1 , fmt("m" )), s)); + CHECK_EQ(format_as( 0.001 , "mm" ), toml::format(toml::value( 0.001 , fmt("mm" )), s)); + CHECK_EQ(format_as( 0.1 , "mm" ), toml::format(toml::value( 0.1 , fmt("mm" )), s)); + CHECK_EQ(format_as( 3.14 , "rad"), toml::format(toml::value( 3.14 , fmt("rad")), s)); + CHECK_EQ(format_as(-3.14 , "rad"), toml::format(toml::value(-3.14 , fmt("rad")), s)); + CHECK_EQ(format_as( 3.141592653589, "rad"), toml::format(toml::value( 3.141592653589, fmt("rad")), s)); + CHECK_EQ(format_as(-3.141592653589, "rad"), toml::format(toml::value(-3.141592653589, fmt("rad")), s)); +} diff --git a/tests/test_format_integer.cpp b/tests/test_format_integer.cpp new file mode 100644 index 0000000..5ea915a --- /dev/null +++ b/tests/test_format_integer.cpp @@ -0,0 +1,89 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include +#include +#include + +TEST_CASE("testing decimal") +{ + const auto decimal_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::dec; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + CHECK_EQ( "0", toml::format(toml::value( 0, decimal_fmt(1, 0)))); + CHECK_EQ( "1234", toml::format(toml::value( 1234, decimal_fmt(0, 0)))); + CHECK_EQ( "-1234", toml::format(toml::value( -1234, decimal_fmt(0, 0)))); + CHECK_EQ( "1_2_3_4", toml::format(toml::value( 1234, decimal_fmt(4, 1)))); + CHECK_EQ( "-1_2_3_4", toml::format(toml::value( -1234, decimal_fmt(5, 1)))); + CHECK_EQ("123_456_789", toml::format(toml::value(123456789, decimal_fmt(9, 3)))); +} + +TEST_CASE("testing hex") +{ + const auto hex_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::hex; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + CHECK_EQ("0xdeadbeef", toml::format(toml::value(0xDEADBEEF, hex_fmt(8, 0)))); + CHECK_EQ("0xdead_beef", toml::format(toml::value(0xDEADBEEF, hex_fmt(8, 4)))); + CHECK_EQ("0xff", toml::format(toml::value(0xFF, hex_fmt(2, 0)))); + CHECK_EQ("0x00ff", toml::format(toml::value(0xFF, hex_fmt(4, 0)))); + CHECK_EQ("0x0000ff", toml::format(toml::value(0xFF, hex_fmt(6, 0)))); +} + +TEST_CASE("testing oct") +{ + const auto oct_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::oct; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + CHECK_EQ("0o644", toml::format(toml::value(64*6+8*4+4, oct_fmt(3, 0)))); + CHECK_EQ("0o7_7_7", toml::format(toml::value(64*7+8*7+7, oct_fmt(3, 1)))); + CHECK_EQ("0o000644", toml::format(toml::value(64*6+8*4+4, oct_fmt(6, 0)))); +} + +TEST_CASE("testing bin") +{ + const auto bin_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::bin; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + CHECK_EQ("0b1000", toml::format(toml::value(8, bin_fmt(4, 0)))); + CHECK_EQ("0b00001000", toml::format(toml::value(8, bin_fmt(8, 0)))); + CHECK_EQ("0b0000_1000", toml::format(toml::value(8, bin_fmt(8, 4)))); +} + +TEST_CASE("testing decimal with suffix") +{ + toml::spec sp = toml::spec::v(1,0,0); + sp.ext_num_suffix = true; + + const auto decimal_fmt = [](std::size_t w, std::size_t s, std::string sfx) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::dec; + fmt.width = w; + fmt.spacer = s; + fmt.suffix = sfx; + return fmt; + }; + + CHECK_EQ( "0_J", toml::format(toml::value( 0, decimal_fmt(1, 0, "J")), sp)); + CHECK_EQ( "1234_kcal", toml::format(toml::value( 1234, decimal_fmt(0, 0, "kcal")), sp)); + CHECK_EQ("1_2_3_4_μm", toml::format(toml::value( 1234, decimal_fmt(4, 1, "μm")), sp)); +} diff --git a/tests/test_format_table.cpp b/tests/test_format_table.cpp new file mode 100644 index 0000000..b12b310 --- /dev/null +++ b/tests/test_format_table.cpp @@ -0,0 +1,78 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include +#include +#include + +TEST_CASE("testing multiline table") +{ + const auto table_fmt = [](toml::indent_char c, std::int32_t body, std::int32_t name) { + toml::table_format_info fmt; + fmt.fmt = toml::table_format::multiline; + fmt.indent_type = c; + fmt.body_indent = body; + fmt.name_indent = name; + fmt.closing_indent = 0; + return fmt; + }; + + toml::value v(toml::table{ + {"a", 42}, + {"b", 3.14}, + {"c", "foobar"}, + }); + + v.as_table_fmt() = table_fmt(toml::indent_char::space, 0, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::space, 0, 2); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::space, 2, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::space, 2, 2); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + + v.as_table_fmt() = table_fmt(toml::indent_char::tab, 0, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::tab, 0, 2); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::tab, 2, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.as_table_fmt() = table_fmt(toml::indent_char::tab, 2, 2); + CHECK_EQ(v, toml::parse_str(toml::format(v))); +} + +TEST_CASE("testing multiline table") +{ + const auto table_fmt = [](toml::indent_char c, std::int32_t body, std::int32_t name) { + toml::table_format_info fmt; + fmt.fmt = toml::table_format::dotted; + fmt.indent_type = c; + fmt.body_indent = body; + fmt.name_indent = name; + fmt.closing_indent = 0; + return fmt; + }; + + { + toml::value v(toml::table{}); + v["a"]["b"]["c"] = "foobar"; + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.at("a").as_table_fmt() = table_fmt(toml::indent_char::space, 0, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.at("a").at("b").as_table_fmt() = table_fmt(toml::indent_char::space, 0, 0); + CHECK_EQ(v, toml::parse_str(toml::format(v))); + + v.at("a").as_table_fmt().fmt = toml::table_format::multiline; + CHECK_EQ(v, toml::parse_str(toml::format(v))); + } +} diff --git a/tests/test_get.cpp b/tests/test_get.cpp index 4a16e34..2807072 100644 --- a/tests/test_get.cpp +++ b/tests/test_get.cpp @@ -1,6 +1,10 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include "utility.hpp" + +#include +#include #include #include @@ -13,402 +17,411 @@ #include #endif -using test_value_types = std::tuple< - toml::basic_value, - toml::basic_value, - toml::basic_value, - toml::basic_value ->; - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types) +TEST_CASE("testing toml::get with toml types") { + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + { value_type v(true); - BOOST_TEST(true == toml::get(v)); + CHECK_EQ(true, toml::get(v)); - toml::get(v) = false; - BOOST_TEST(false == toml::get(v)); + toml::get(v) = false; + CHECK_EQ(false, toml::get(v)); - toml::boolean x = toml::get(std::move(v)); - BOOST_TEST(false == x); + boolean_type x = toml::get(std::move(v)); + CHECK_EQ(false, x); } { value_type v(42); - BOOST_TEST(toml::integer(42) == toml::get(v)); + CHECK_EQ(integer_type(42), toml::get(v)); - toml::get(v) = 54; - BOOST_TEST(toml::integer(54) == toml::get(v)); + toml::get(v) = 54; + CHECK_EQ(integer_type(54), toml::get(v)); - toml::integer x = toml::get(std::move(v)); - BOOST_TEST(toml::integer(54) == x); + integer_type x = toml::get(std::move(v)); + CHECK_EQ(integer_type(54), x); } { value_type v(3.14); - BOOST_TEST(toml::floating(3.14) == toml::get(v)); + CHECK_EQ(floating_type(3.14), toml::get(v)); - toml::get(v) = 2.71; - BOOST_TEST(toml::floating(2.71) == toml::get(v)); + toml::get(v) = 2.71; + CHECK_EQ(floating_type(2.71), toml::get(v)); - toml::floating x = toml::get(std::move(v)); - BOOST_TEST(toml::floating(2.71) == x); + floating_type x = toml::get(std::move(v)); + CHECK_EQ(floating_type(2.71), x); } { value_type v("foo"); - BOOST_TEST(toml::string("foo", toml::string_t::basic) == - toml::get(v)); + CHECK_EQ("foo", toml::get(v)); - toml::get(v).str += "bar"; - BOOST_TEST(toml::string("foobar", toml::string_t::basic) == - toml::get(v)); + toml::get(v) += "bar"; + CHECK_EQ("foobar", toml::get(v)); - toml::string x = toml::get(std::move(v)); - BOOST_TEST(toml::string("foobar") == x); + string_type x = toml::get(std::move(v)); + CHECK_EQ("foobar", x); } { - value_type v("foo", toml::string_t::literal); - BOOST_TEST(toml::string("foo", toml::string_t::literal) == - toml::get(v)); - - toml::get(v).str += "bar"; - BOOST_TEST(toml::string("foobar", toml::string_t::literal) == - toml::get(v)); - - toml::string x = toml::get(std::move(v)); - BOOST_TEST(toml::string("foobar", toml::string_t::literal) == x); - } - { - toml::local_date d(2018, toml::month_t::Apr, 22); + local_date_type d(2018, toml::month_t::Apr, 22); value_type v(d); - BOOST_TEST(d == toml::get(v)); + CHECK_EQ(d, toml::get(v)); - toml::get(v).year = 2017; + toml::get(v).year = 2017; d.year = 2017; - BOOST_TEST(d == toml::get(v)); + CHECK_EQ(d, toml::get(v)); - toml::local_date x = toml::get(std::move(v)); - BOOST_TEST(d == x); + local_date_type x = toml::get(std::move(v)); + CHECK_EQ(d, x); } { - toml::local_time t(12, 30, 45); + local_time_type t(12, 30, 45); value_type v(t); - BOOST_TEST(t == toml::get(v)); + CHECK_EQ(t, toml::get(v)); - toml::get(v).hour = 9; + toml::get(v).hour = 9; t.hour = 9; - BOOST_TEST(t == toml::get(v)); + CHECK_EQ(t, toml::get(v)); - toml::local_time x = toml::get(std::move(v)); - BOOST_TEST(t == x); + local_time_type x = toml::get(std::move(v)); + CHECK_EQ(t, x); } { - toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), - toml::local_time(12, 30, 45)); + local_datetime_type dt(toml::local_date(2018, toml::month_t::Apr, 22), + toml::local_time(12, 30, 45)); value_type v(dt); - BOOST_TEST(dt == toml::get(v)); + CHECK_EQ(dt, toml::get(v)); - toml::get(v).date.year = 2017; + toml::get(v).date.year = 2017; dt.date.year = 2017; - BOOST_TEST(dt == toml::get(v)); + CHECK_EQ(dt, toml::get(v)); - toml::local_datetime x = toml::get(std::move(v)); - BOOST_TEST(dt == x); + toml::local_datetime x = toml::get(std::move(v)); + CHECK_EQ(dt, x); } { - toml::offset_datetime dt(toml::local_datetime( + offset_datetime_type dt(toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 22), toml::local_time(12, 30, 45)), toml::time_offset(9, 0)); value_type v(dt); - BOOST_TEST(dt == toml::get(v)); + CHECK_EQ(dt, toml::get(v)); toml::get(v).date.year = 2017; dt.date.year = 2017; - BOOST_TEST(dt == toml::get(v)); + CHECK_EQ(dt, toml::get(v)); - toml::offset_datetime x = toml::get(std::move(v)); - BOOST_TEST(dt == x); + offset_datetime_type x = toml::get(std::move(v)); + CHECK_EQ(dt, x); } { - using array_type = typename value_type::array_type; array_type vec; vec.push_back(value_type(42)); vec.push_back(value_type(54)); value_type v(vec); - BOOST_TEST(vec == toml::get(v)); + CHECK_EQ(vec, toml::get(v)); toml::get(v).push_back(value_type(123)); vec.push_back(value_type(123)); - BOOST_TEST(vec == toml::get(v)); + CHECK_EQ(vec, toml::get(v)); array_type x = toml::get(std::move(v)); - BOOST_TEST(vec == x); + CHECK_EQ(vec, x); } { - using table_type = typename value_type::table_type; table_type tab; tab["key1"] = value_type(42); tab["key2"] = value_type(3.14); value_type v(tab); - BOOST_TEST(tab == toml::get(v)); + CHECK_EQ(tab, toml::get(v)); toml::get(v)["key3"] = value_type(123); tab["key3"] = value_type(123); - BOOST_TEST(tab == toml::get(v)); + CHECK_EQ(tab, toml::get(v)); table_type x = toml::get(std::move(v)); - BOOST_TEST(tab == x); + CHECK_EQ(tab, x); } { value_type v1(42); - BOOST_TEST(v1 == toml::get(v1)); + CHECK_EQ(v1, toml::get(v1)); value_type v2(54); toml::get(v1) = v2; - BOOST_TEST(v2 == toml::get(v1)); + CHECK_EQ(v2, toml::get(v1)); value_type x = toml::get(std::move(v1)); - BOOST_TEST(v2 == x); + CHECK_EQ(v2, x); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_integer_type, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; { value_type v(42); - BOOST_TEST(int(42) == toml::get(v)); - BOOST_TEST(short(42) == toml::get(v)); - BOOST_TEST(char(42) == toml::get(v)); - BOOST_TEST(unsigned(42) == toml::get(v)); - BOOST_TEST(long(42) == toml::get(v)); - BOOST_TEST(std::int64_t(42) == toml::get(v)); - BOOST_TEST(std::uint64_t(42) == toml::get(v)); - BOOST_TEST(std::int16_t(42) == toml::get(v)); - BOOST_TEST(std::uint16_t(42) == toml::get(v)); - BOOST_TEST(std::uint16_t(42) == toml::get(std::move(v))); + CHECK_EQ(int(42), toml::get(v)); + CHECK_EQ(short(42), toml::get(v)); + CHECK_EQ(char(42), toml::get(v)); + CHECK_EQ(unsigned(42), toml::get(v)); + CHECK_EQ(long(42), toml::get(v)); + CHECK_EQ(std::int64_t(42), toml::get(v)); + CHECK_EQ(std::uint64_t(42), toml::get(v)); + CHECK_EQ(std::int16_t(42), toml::get(v)); + CHECK_EQ(std::uint16_t(42), toml::get(v)); + + CHECK_EQ(int(42), toml::get(as_const(v))); + CHECK_EQ(short(42), toml::get(as_const(v))); + CHECK_EQ(char(42), toml::get(as_const(v))); + CHECK_EQ(unsigned(42), toml::get(as_const(v))); + CHECK_EQ(long(42), toml::get(as_const(v))); + CHECK_EQ(std::int64_t(42), toml::get(as_const(v))); + CHECK_EQ(std::uint64_t(42), toml::get(as_const(v))); + CHECK_EQ(std::int16_t(42), toml::get(as_const(v))); + CHECK_EQ(std::uint16_t(42), toml::get(as_const(v))); + + value_type v1(v); + value_type v2(v); + value_type v3(v); + value_type v4(v); + value_type v5(v); + value_type v6(v); + value_type v7(v); + value_type v8(v); + value_type v9(v); + + CHECK_EQ(int(42), toml::get(v1)); + CHECK_EQ(short(42), toml::get(v2)); + CHECK_EQ(char(42), toml::get(v3)); + CHECK_EQ(unsigned(42), toml::get(v4)); + CHECK_EQ(long(42), toml::get(v5)); + CHECK_EQ(std::int64_t(42), toml::get(v6)); + CHECK_EQ(std::uint64_t(42), toml::get(v7)); + CHECK_EQ(std::int16_t(42), toml::get(v8)); + CHECK_EQ(std::uint16_t(42), toml::get(v9)); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_floating_type, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; { - value_type v(3.14); const double ref(3.14); - BOOST_TEST(static_cast(ref) == toml::get(v)); - BOOST_TEST( ref == toml::get(v)); - BOOST_TEST(static_cast(ref) == toml::get(v)); - BOOST_TEST(static_cast(ref) == toml::get(std::move(v))); + + value_type v(ref); + CHECK_EQ(static_cast(ref), toml::get(v)); + CHECK_EQ( ref , toml::get(v)); + CHECK_EQ(static_cast(ref), toml::get(v)); + + value_type v1(ref); + value_type v2(ref); + value_type v3(ref); + CHECK_EQ(static_cast(ref), toml::get(std::move(v1))); + CHECK_EQ( ref , toml::get(std::move(v2))); + CHECK_EQ(static_cast(ref), toml::get(std::move(v3))); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types) -{ - { - value_type v("foo", toml::string_t::basic); - BOOST_TEST("foo" == toml::get(v)); - toml::get(v) += "bar"; - BOOST_TEST("foobar" == toml::get(v)); - - const auto x = toml::get(std::move(v)); - BOOST_TEST("foobar" == x); - } - { - value_type v("foo", toml::string_t::literal); - BOOST_TEST("foo" == toml::get(v)); - toml::get(v) += "bar"; - BOOST_TEST("foobar" == toml::get(v)); - - const auto x = toml::get(std::move(v)); - BOOST_TEST("foobar" == x); - } - #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L - { - value_type v("foo", toml::string_t::basic); - BOOST_TEST("foo" == toml::get(v)); - } - { - value_type v("foo", toml::string_t::literal); - BOOST_TEST("foo" == toml::get(v)); - } -#endif -} - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; { - const value_type v{42, 54, 69, 72}; + value_type v("foo"); + CHECK_EQ("foo", toml::get(v)); + } +} +#endif + +TEST_CASE("testing toml::get") +{ + using value_type = toml::value; + { + const value_type v(toml::array{42, 54, 69, 72}); const std::vector vec = toml::get>(v); const std::list lst = toml::get>(v); const std::deque deq = toml::get>(v); - BOOST_TEST(42 == vec.at(0)); - BOOST_TEST(54 == vec.at(1)); - BOOST_TEST(69 == vec.at(2)); - BOOST_TEST(72 == vec.at(3)); + CHECK_EQ(42, vec.at(0)); + CHECK_EQ(54, vec.at(1)); + CHECK_EQ(69, vec.at(2)); + CHECK_EQ(72, vec.at(3)); std::list::const_iterator iter = lst.begin(); - BOOST_TEST(static_cast(42) == *(iter++)); - BOOST_TEST(static_cast(54) == *(iter++)); - BOOST_TEST(static_cast(69) == *(iter++)); - BOOST_TEST(static_cast(72) == *(iter++)); + CHECK_EQ(static_cast(42), *(iter++)); + CHECK_EQ(static_cast(54), *(iter++)); + CHECK_EQ(static_cast(69), *(iter++)); + CHECK_EQ(static_cast(72), *(iter++)); - BOOST_TEST(static_cast(42) == deq.at(0)); - BOOST_TEST(static_cast(54) == deq.at(1)); - BOOST_TEST(static_cast(69) == deq.at(2)); - BOOST_TEST(static_cast(72) == deq.at(3)); + CHECK_EQ(static_cast(42), deq.at(0)); + CHECK_EQ(static_cast(54), deq.at(1)); + CHECK_EQ(static_cast(69), deq.at(2)); + CHECK_EQ(static_cast(72), deq.at(3)); std::array ary = toml::get>(v); - BOOST_TEST(42 == ary.at(0)); - BOOST_TEST(54 == ary.at(1)); - BOOST_TEST(69 == ary.at(2)); - BOOST_TEST(72 == ary.at(3)); + CHECK_EQ(42, ary.at(0)); + CHECK_EQ(54, ary.at(1)); + CHECK_EQ(69, ary.at(2)); + CHECK_EQ(72, ary.at(3)); std::tuple tpl = toml::get>(v); - BOOST_TEST( 42 == std::get<0>(tpl)); - BOOST_TEST(static_cast(54) == std::get<1>(tpl)); - BOOST_TEST(static_cast(69) == std::get<2>(tpl)); - BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + CHECK_EQ( 42 , std::get<0>(tpl)); + CHECK_EQ(static_cast(54), std::get<1>(tpl)); + CHECK_EQ(static_cast(69), std::get<2>(tpl)); + CHECK_EQ(static_cast(72), std::get<3>(tpl)); - const value_type p{3.14, 2.71}; + const value_type p(toml::array{3.14, 2.71}); std::pair pr = toml::get >(p); - BOOST_TEST(3.14 == pr.first); - BOOST_TEST(2.71 == pr.second); + CHECK_EQ(3.14, pr.first); + CHECK_EQ(2.71, pr.second); } { - value_type v{42, 54, 69, 72}; + value_type v(toml::array{42, 54, 69, 72}); const std::vector vec = toml::get>(std::move(v)); - BOOST_TEST(42 == vec.at(0)); - BOOST_TEST(54 == vec.at(1)); - BOOST_TEST(69 == vec.at(2)); - BOOST_TEST(72 == vec.at(3)); + CHECK_EQ(42, vec.at(0)); + CHECK_EQ(54, vec.at(1)); + CHECK_EQ(69, vec.at(2)); + CHECK_EQ(72, vec.at(3)); } { - value_type v{42, 54, 69, 72}; + value_type v(toml::array{42, 54, 69, 72}); const std::deque deq = toml::get>(std::move(v)); - BOOST_TEST(42 == deq.at(0)); - BOOST_TEST(54 == deq.at(1)); - BOOST_TEST(69 == deq.at(2)); - BOOST_TEST(72 == deq.at(3)); + CHECK_EQ(42, deq.at(0)); + CHECK_EQ(54, deq.at(1)); + CHECK_EQ(69, deq.at(2)); + CHECK_EQ(72, deq.at(3)); } { - value_type v{42, 54, 69, 72}; + value_type v(toml::array{42, 54, 69, 72}); const std::list lst = toml::get>(std::move(v)); std::list::const_iterator iter = lst.begin(); - BOOST_TEST(42 == *(iter++)); - BOOST_TEST(54 == *(iter++)); - BOOST_TEST(69 == *(iter++)); - BOOST_TEST(72 == *(iter++)); + CHECK_EQ(42, *(iter++)); + CHECK_EQ(54, *(iter++)); + CHECK_EQ(69, *(iter++)); + CHECK_EQ(72, *(iter++)); } { - value_type v{42, 54, 69, 72}; + value_type v(toml::array{42, 54, 69, 72}); std::array ary = toml::get>(std::move(v)); - BOOST_TEST(42 == ary.at(0)); - BOOST_TEST(54 == ary.at(1)); - BOOST_TEST(69 == ary.at(2)); - BOOST_TEST(72 == ary.at(3)); + CHECK_EQ(42, ary.at(0)); + CHECK_EQ(54, ary.at(1)); + CHECK_EQ(69, ary.at(2)); + CHECK_EQ(72, ary.at(3)); } { - value_type v{42, 54, 69, 72}; + value_type v(toml::array{42, 54, 69, 72}); std::tuple tpl = toml::get>(std::move(v)); - BOOST_TEST( 42 == std::get<0>(tpl)); - BOOST_TEST(static_cast(54) == std::get<1>(tpl)); - BOOST_TEST(static_cast(69) == std::get<2>(tpl)); - BOOST_TEST(static_cast(72) == std::get<3>(tpl)); + CHECK_EQ( 42 , std::get<0>(tpl)); + CHECK_EQ(static_cast(54), std::get<1>(tpl)); + CHECK_EQ(static_cast(69), std::get<2>(tpl)); + CHECK_EQ(static_cast(72), std::get<3>(tpl)); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array_of_array, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; { - const value_type v1{42, 54, 69, 72}; - const value_type v2{"foo", "bar", "baz"}; - const value_type v{v1, v2}; + const value_type v1(toml::array{42, 54, 69, 72}); + const value_type v2(toml::array{"foo", "bar", "baz"}); + const value_type v (toml::array{v1, v2}); std::pair, std::vector> p = toml::get, std::vector>>(v); - BOOST_TEST(p.first.size() == 4u); - BOOST_TEST(p.first.at(0) == 42); - BOOST_TEST(p.first.at(1) == 54); - BOOST_TEST(p.first.at(2) == 69); - BOOST_TEST(p.first.at(3) == 72); + CHECK_EQ(p.first.size(), 4u); + CHECK_EQ(p.first.at(0), 42); + CHECK_EQ(p.first.at(1), 54); + CHECK_EQ(p.first.at(2), 69); + CHECK_EQ(p.first.at(3), 72); - BOOST_TEST(p.second.size() == 3u); - BOOST_TEST(p.second.at(0) == "foo"); - BOOST_TEST(p.second.at(1) == "bar"); - BOOST_TEST(p.second.at(2) == "baz"); + CHECK_EQ(p.second.size(), 3u); + CHECK_EQ(p.second.at(0), "foo"); + CHECK_EQ(p.second.at(1), "bar"); + CHECK_EQ(p.second.at(2), "baz"); std::tuple, std::vector> t = toml::get, std::vector>>(v); - BOOST_TEST(std::get<0>(t).at(0) == 42); - BOOST_TEST(std::get<0>(t).at(1) == 54); - BOOST_TEST(std::get<0>(t).at(2) == 69); - BOOST_TEST(std::get<0>(t).at(3) == 72); + CHECK_EQ(std::get<0>(t).at(0), 42); + CHECK_EQ(std::get<0>(t).at(1), 54); + CHECK_EQ(std::get<0>(t).at(2), 69); + CHECK_EQ(std::get<0>(t).at(3), 72); - BOOST_TEST(std::get<1>(t).at(0) == "foo"); - BOOST_TEST(std::get<1>(t).at(1) == "bar"); - BOOST_TEST(std::get<1>(t).at(2) == "baz"); + CHECK_EQ(std::get<1>(t).at(0), "foo"); + CHECK_EQ(std::get<1>(t).at(1), "bar"); + CHECK_EQ(std::get<1>(t).at(2), "baz"); } { - const value_type v1{42, 54, 69, 72}; - const value_type v2{"foo", "bar", "baz"}; - value_type v{v1, v2}; + const value_type v1(toml::array{42, 54, 69, 72}); + const value_type v2(toml::array{"foo", "bar", "baz"}); + value_type v (toml::array{v1, v2}); std::pair, std::vector> p = toml::get, std::vector>>(std::move(v)); - BOOST_TEST(p.first.size() == 4u); - BOOST_TEST(p.first.at(0) == 42); - BOOST_TEST(p.first.at(1) == 54); - BOOST_TEST(p.first.at(2) == 69); - BOOST_TEST(p.first.at(3) == 72); + CHECK_EQ(p.first.size(), 4u); + CHECK_EQ(p.first.at(0), 42); + CHECK_EQ(p.first.at(1), 54); + CHECK_EQ(p.first.at(2), 69); + CHECK_EQ(p.first.at(3), 72); - BOOST_TEST(p.second.size() == 3u); - BOOST_TEST(p.second.at(0) == "foo"); - BOOST_TEST(p.second.at(1) == "bar"); - BOOST_TEST(p.second.at(2) == "baz"); + CHECK_EQ(p.second.size(), 3u); + CHECK_EQ(p.second.at(0), "foo"); + CHECK_EQ(p.second.at(1), "bar"); + CHECK_EQ(p.second.at(2), "baz"); } } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_table, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; { - const value_type v1{ + const value_type v1(toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} - }; + }); const auto v = toml::get>(v1); - BOOST_TEST(v.at("key1") == 1); - BOOST_TEST(v.at("key2") == 2); - BOOST_TEST(v.at("key3") == 3); - BOOST_TEST(v.at("key4") == 4); + CHECK_EQ(v.at("key1"), 1); + CHECK_EQ(v.at("key2"), 2); + CHECK_EQ(v.at("key3"), 3); + CHECK_EQ(v.at("key4"), 4); } { - value_type v1{ + value_type v1(toml::table{ {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} - }; + }); const auto v = toml::get>(std::move(v1)); - BOOST_TEST(v.at("key1") == 1); - BOOST_TEST(v.at("key2") == 2); - BOOST_TEST(v.at("key3") == 3); - BOOST_TEST(v.at("key4") == 4); + CHECK_EQ(v.at("key1"), 1); + CHECK_EQ(v.at("key2"), 2); + CHECK_EQ(v.at("key3"), 3); + CHECK_EQ(v.at("key4"), 4); } - } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_types) +TEST_CASE("testing toml::get(local_date)") { + using value_type = toml::value; + value_type v1(toml::local_date{2018, toml::month_t::Apr, 1}); const auto date = std::chrono::system_clock::to_time_t( toml::get(v1)); @@ -422,27 +435,32 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_t t.tm_sec = 0; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_time, value_type, test_value_types) +TEST_CASE("testing toml::get") { + using value_type = toml::value; + value_type v1(toml::local_time{12, 30, 45}); const auto time = toml::get(v1); const bool result = time == std::chrono::hours(12) + std::chrono::minutes(30) + std::chrono::seconds(45); - BOOST_TEST(result); + CHECK_UNARY(result); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_datetime, value_type, test_value_types) +TEST_CASE("testing toml::get(local_datetime)") { + using value_type = toml::value; + value_type v1(toml::local_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 45})); const auto date = std::chrono::system_clock::to_time_t( toml::get(v1)); + std::tm t; t.tm_year = 2018 - 1900; t.tm_mon = 4 - 1; @@ -452,54 +470,55 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_datetime, value_type, test_val t.tm_sec = 45; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_TEST(c == date); + CHECK_EQ(c, date); } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) +TEST_CASE("testing toml::get(offset_datetime)") { + using value_type = toml::value; { - value_type v1(toml::offset_datetime( - toml::local_date{2018, toml::month_t::Apr, 1}, - toml::local_time{12, 30, 0}, - toml::time_offset{9, 0})); - // 2018-04-01T12:30:00+09:00 - // == 2018-04-01T03:30:00Z + value_type v1(toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{9, 0})); + // 2018-04-01T12:30:00+09:00 + // == 2018-04-01T03:30:00Z - const auto date = toml::get(v1); - const auto timet = std::chrono::system_clock::to_time_t(date); + const auto date = toml::get(v1); + const auto timet = std::chrono::system_clock::to_time_t(date); - // get time_t as gmtime (2018-04-01T03:30:00Z) - const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_TEST(tmp); - const auto tm = *tmp; - BOOST_TEST(tm.tm_year + 1900 == 2018); - BOOST_TEST(tm.tm_mon + 1 == 4); - BOOST_TEST(tm.tm_mday == 1); - BOOST_TEST(tm.tm_hour == 3); - BOOST_TEST(tm.tm_min == 30); - BOOST_TEST(tm.tm_sec == 0); + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + CHECK_UNARY(tmp); + const auto tm = *tmp; + CHECK_EQ(tm.tm_year + 1900, 2018); + CHECK_EQ(tm.tm_mon + 1, 4); + CHECK_EQ(tm.tm_mday, 1); + CHECK_EQ(tm.tm_hour, 3); + CHECK_EQ(tm.tm_min, 30); + CHECK_EQ(tm.tm_sec, 0); } { - value_type v1(toml::offset_datetime( - toml::local_date{2018, toml::month_t::Apr, 1}, - toml::local_time{12, 30, 0}, - toml::time_offset{-8, 0})); - // 2018-04-01T12:30:00-08:00 - // == 2018-04-01T20:30:00Z + value_type v1(toml::offset_datetime( + toml::local_date{2018, toml::month_t::Apr, 1}, + toml::local_time{12, 30, 0}, + toml::time_offset{-8, 0})); + // 2018-04-01T12:30:00-08:00 + //, 2018-04-01T20:30:00Z - const auto date = toml::get(v1); - const auto timet = std::chrono::system_clock::to_time_t(date); + const auto date = toml::get(v1); + const auto timet = std::chrono::system_clock::to_time_t(date); - // get time_t as gmtime (2018-04-01T03:30:00Z) - const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_TEST(tmp); - const auto tm = *tmp; - BOOST_TEST(tm.tm_year + 1900 == 2018); - BOOST_TEST(tm.tm_mon + 1 == 4); - BOOST_TEST(tm.tm_mday == 1); - BOOST_TEST(tm.tm_hour == 20); - BOOST_TEST(tm.tm_min == 30); - BOOST_TEST(tm.tm_sec == 0); + // get time_t as gmtime (2018-04-01T03:30:00Z) + const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! + CHECK_UNARY(tmp); + const auto tm = *tmp; + CHECK_EQ(tm.tm_year + 1900, 2018); + CHECK_EQ(tm.tm_mon + 1, 4); + CHECK_EQ(tm.tm_mday, 1); + CHECK_EQ(tm.tm_hour, 20); + CHECK_EQ(tm.tm_min, 30); + CHECK_EQ(tm.tm_sec, 0); } } diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp index 9ecb36e..601ca03 100644 --- a/tests/test_get_or.cpp +++ b/tests/test_get_or.cpp @@ -1,6 +1,10 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include "utility.hpp" + +#include +#include #include #include @@ -13,240 +17,180 @@ #include #endif -using test_value_types = std::tuple< - toml::basic_value, - toml::basic_value, - toml::basic_value, - toml::basic_value ->; +#define TOML11_TEST_GET_OR_EXACT(ty, init_expr, opt_expr)\ + { \ + const ty init init_expr ; \ + const ty opt opt_expr ; \ + const value_type v(init); \ + CHECK_NE(init, opt); \ + CHECK_EQ(init, toml::get_or(v, opt)); \ + } -namespace test +TEST_CASE("testing get_or with exact types") { -// to compare result values in BOOST_TEST(). -// -// BOOST_TEST outputs the expected and actual values. Thus it includes the -// output stream operator inside. To compile it, we need operator< -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::vector& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::deque& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const std::list& v) -{ - os << "[ "; - for(const auto& i : v) {os << i << ' ';} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::unordered_map& v) -{ - os << "[ "; - for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} - os << ']'; - return os; -} -} // test + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; -#define TOML11_TEST_GET_OR_EXACT(toml_type, init_expr, opt_expr)\ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - const toml::toml_type opt opt_expr ; \ - const value_type v(init); \ - BOOST_TEST(init != opt); \ - BOOST_TEST(init == toml::get_or(v, opt)); \ - } \ - /**/ - -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_exact, value_type, test_value_types) -{ - TOML11_TEST_GET_OR_EXACT(boolean, ( true), (false)) - TOML11_TEST_GET_OR_EXACT(integer, ( 42), ( 54)) - TOML11_TEST_GET_OR_EXACT(floating, ( 3.14), ( 2.71)) - TOML11_TEST_GET_OR_EXACT(string, ("foo"), ("bar")) - TOML11_TEST_GET_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_GET_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_GET_OR_EXACT(local_datetime, + TOML11_TEST_GET_OR_EXACT(boolean_type, ( true), (false)) + TOML11_TEST_GET_OR_EXACT(integer_type, ( 42), ( 54)) + TOML11_TEST_GET_OR_EXACT(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_EXACT(string_type, ("foo"), ("bar")) + TOML11_TEST_GET_OR_EXACT(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_EXACT(local_date_type, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_EXACT(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) ) - TOML11_TEST_GET_OR_EXACT(offset_datetime, + TOML11_TEST_GET_OR_EXACT(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) ) - { - const typename value_type::array_type init{1,2,3,4,5}; - const typename value_type::array_type opt {6,7,8,9,10}; - const value_type v(init); - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::get_or(v, opt)); - } - { - const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - const value_type v(init); - BOOST_TEST(init != opt); - BOOST_TEST(init == toml::get_or(v, opt)); - } + + TOML11_TEST_GET_OR_EXACT(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_GET_OR_EXACT(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); } #undef TOML11_TEST_GET_OR_EXACT -#define TOML11_TEST_GET_OR_MOVE_EXACT(toml_type, init_expr, opt_expr)\ +#define TOML11_TEST_GET_OR_MOVE_EXACT(ty, init_expr, opt_expr) \ { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt opt_expr ; \ + const ty init init_expr ; \ + ty opt opt_expr ; \ value_type v(init); \ - BOOST_TEST(init != opt); \ + CHECK_NE(init, opt); \ const auto opt_ = toml::get_or(std::move(v), std::move(opt));\ - BOOST_TEST(init == opt_); \ - } \ - /**/ + CHECK_EQ(init, opt_); \ + } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_move, value_type, test_value_types) +TEST_CASE("testing toml::get_or with moved argument") { - TOML11_TEST_GET_OR_MOVE_EXACT(boolean, ( true), (false)) - TOML11_TEST_GET_OR_MOVE_EXACT(integer, ( 42), ( 54)) - TOML11_TEST_GET_OR_MOVE_EXACT(floating, ( 3.14), ( 2.71)) - TOML11_TEST_GET_OR_MOVE_EXACT(string, ("foo"), ("bar")) - TOML11_TEST_GET_OR_MOVE_EXACT(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_GET_OR_MOVE_EXACT(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_GET_OR_MOVE_EXACT(local_datetime, + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + TOML11_TEST_GET_OR_MOVE_EXACT(boolean_type, ( true), (false)) + TOML11_TEST_GET_OR_MOVE_EXACT(integer_type, ( 42), ( 54)) + TOML11_TEST_GET_OR_MOVE_EXACT(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_MOVE_EXACT(string_type, ("foo"), ("bar")) + TOML11_TEST_GET_OR_MOVE_EXACT(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_MOVE_EXACT(local_date_type, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_MOVE_EXACT(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) - ) - TOML11_TEST_GET_OR_MOVE_EXACT(offset_datetime, + ) + TOML11_TEST_GET_OR_MOVE_EXACT(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) - ) - { - const typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt {6,7,8,9,10}; - value_type v(init); - BOOST_TEST(init != opt); - const auto opt_ = toml::get_or(std::move(v), std::move(opt)); - BOOST_TEST(init == opt_); - } - { - const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}}; - value_type v(init); - BOOST_TEST(init != opt); - const auto opt_ = toml::get_or(std::move(v), std::move(opt)); - BOOST_TEST(init == opt_); - } + ) + + TOML11_TEST_GET_OR_MOVE_EXACT(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_GET_OR_MOVE_EXACT(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); + } #undef TOML11_TEST_GET_OR_MOVE_EXACT -#define TOML11_TEST_GET_OR_MODIFY(toml_type, init_expr, opt_expr)\ - { \ - using namespace test; \ - const toml::toml_type init init_expr ; \ - toml::toml_type opt1 opt_expr ; \ - toml::toml_type opt2 opt_expr ; \ - value_type v(init); \ - BOOST_TEST(init != opt1); \ - toml::get_or(v, opt2) = opt1; \ - BOOST_TEST(opt1 == toml::get(v)); \ - } \ - /**/ -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_modify, value_type, test_value_types) +#define TOML11_TEST_GET_OR_MODIFY(ty, init_expr, opt_expr)\ + { \ + const ty init init_expr ; \ + ty opt1 opt_expr ; \ + ty opt2 opt_expr ; \ + value_type v(init); \ + CHECK_NE(init, opt1); \ + toml::get_or(v, opt2) = opt1; \ + CHECK_EQ(opt1, toml::get(v)); \ + } + +TEST_CASE("testing if get_or can modify value") { - TOML11_TEST_GET_OR_MODIFY(boolean, ( true), (false)) - TOML11_TEST_GET_OR_MODIFY(integer, ( 42), ( 54)) - TOML11_TEST_GET_OR_MODIFY(floating, ( 3.14), ( 2.71)) - TOML11_TEST_GET_OR_MODIFY(string, ("foo"), ("bar")) - TOML11_TEST_GET_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30)) - TOML11_TEST_GET_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1), - (1999, toml::month_t::Jan, 2)) - TOML11_TEST_GET_OR_MODIFY(local_datetime, + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + TOML11_TEST_GET_OR_MODIFY(boolean_type, ( true), (false)) + TOML11_TEST_GET_OR_MODIFY(integer_type, ( 42), ( 54)) + TOML11_TEST_GET_OR_MODIFY(floating_type, ( 3.14), ( 2.71)) + TOML11_TEST_GET_OR_MODIFY(string_type, ("foo"), ("bar")) + TOML11_TEST_GET_OR_MODIFY(local_time_type, (12, 30, 45), (6, 0, 30)) + TOML11_TEST_GET_OR_MODIFY(local_date_type, (2019, toml::month_t::Apr, 1), + (1999, toml::month_t::Jan, 2)) + TOML11_TEST_GET_OR_MODIFY(local_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30)) - ) - TOML11_TEST_GET_OR_MODIFY(offset_datetime, + ) + TOML11_TEST_GET_OR_MODIFY(offset_datetime_type, (toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)), (toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0)) - ) - { - typename value_type::array_type init{1,2,3,4,5}; - typename value_type::array_type opt1{6,7,8,9,10}; - typename value_type::array_type opt2{6,7,8,9,10}; - BOOST_TEST(init != opt1); - value_type v(init); - toml::get_or(v, opt2) = opt1; - BOOST_TEST(opt1 == toml::get(v)); - } - { - typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}}; - typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}}; - typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}}; - value_type v(init); - BOOST_TEST(init != opt1); - toml::get_or(v, opt2) = opt1; - BOOST_TEST(opt1 == toml::get(v)); - } + ) + + TOML11_TEST_GET_OR_MODIFY(array_type, ({1,2,3,4,5}), ({6,7,8,9,10})); + TOML11_TEST_GET_OR_MODIFY(table_type, ({{"key1", 42}, {"key2", "foo"}}), + ({{"key1", 54}, {"key2", "bar"}})); } #undef TOML11_TEST_GET_OR_MODIFY #define TOML11_TEST_GET_OR_FALLBACK(init_type, opt_type) \ { \ - using namespace test; \ value_type v(init_type); \ - BOOST_TEST(opt_type == toml::get_or(v, opt_type));\ - } \ - /**/ + CHECK_EQ(opt_type, toml::get_or(v, opt_type)); \ + } -BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_fallback, value_type, test_value_types) +TEST_CASE("testing get_or can return optional value on failure") { - const toml::boolean boolean (true); - const toml::integer integer (42); - const toml::floating floating (3.14); - const toml::string string ("foo"); - const toml::local_time local_time (12, 30, 45); - const toml::local_date local_date (2019, toml::month_t::Apr, 1); - const toml::local_datetime local_datetime ( + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + const boolean_type boolean (true); + const integer_type integer (42); + const floating_type floating (3.14); + const string_type string ("foo"); + const local_time_type local_time (12, 30, 45); + const local_date_type local_date (2019, toml::month_t::Apr, 1); + const local_datetime_type local_datetime ( toml::local_date(2019, toml::month_t::Apr, 1), - toml::local_time(12, 30, 45)); - const toml::offset_datetime offset_datetime( + toml::local_time(12, 30, 45) + ); + const offset_datetime_type offset_datetime( toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)); - using array_type = typename value_type::array_type; - using table_type = typename value_type::table_type; const array_type array{1, 2, 3, 4, 5}; const table_type table{{"key1", 42}, {"key2", "foo"}}; @@ -352,98 +296,52 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_fallback, value_type, test_value_types } #undef TOML11_TEST_GET_OR_FALLBACK -BOOST_AUTO_TEST_CASE(test_get_or_integer) +TEST_CASE("testing get_or with optional integer") { { toml::value v1(42); toml::value v2(3.14); - BOOST_TEST(42u == toml::get_or(v1, 0u)); - BOOST_TEST(0u == toml::get_or(v2, 0u)); + CHECK_EQ(42u, toml::get_or(v1, 0u)); + CHECK_EQ(0u , toml::get_or(v2, 0u)); } { toml::value v1(42); toml::value v2(3.14); - BOOST_TEST(42u == toml::get_or(std::move(v1), 0u)); - BOOST_TEST(0u == toml::get_or(std::move(v2), 0u)); + CHECK_EQ(42u, toml::get_or(std::move(v1), 0u)); + CHECK_EQ( 0u, toml::get_or(std::move(v2), 0u)); } - } -BOOST_AUTO_TEST_CASE(test_get_or_floating) +TEST_CASE("testing get_or with optional float") { { toml::value v1(42); toml::value v2(3.14); - BOOST_TEST(2.71f == toml::get_or(v1, 2.71f)); - BOOST_TEST(static_cast(v2.as_floating()) == toml::get_or(v2, 2.71f)); + CHECK_EQ(2.71f, toml::get_or(v1, 2.71f)); + CHECK_EQ(static_cast(v2.as_floating()), toml::get_or(v2, 2.71f)); } { toml::value v1(42); toml::value v2(3.14); - BOOST_TEST(2.71f == toml::get_or(std::move(v1), 2.71f)); - BOOST_TEST(static_cast(3.14) == toml::get_or(std::move(v2), 2.71f)); + CHECK_EQ(2.71f , toml::get_or(std::move(v1), 2.71f)); + CHECK_EQ(static_cast(3.14), toml::get_or(std::move(v2), 2.71f)); } } -BOOST_AUTO_TEST_CASE(test_get_or_string) +TEST_CASE("testing get_or with optional string literal") { { toml::value v1("foobar"); toml::value v2(42); - std::string s1("bazqux"); - const std::string s2("bazqux"); - - BOOST_TEST("foobar" == toml::get_or(v1, s1)); - BOOST_TEST("bazqux" == toml::get_or(v2, s1)); - - std::string& v1r = toml::get_or(v1, s1); - std::string& s1r = toml::get_or(v2, s1); - - BOOST_TEST("foobar" == v1r); - BOOST_TEST("bazqux" == s1r); - - BOOST_TEST("foobar" == toml::get_or(v1, s2)); - BOOST_TEST("bazqux" == toml::get_or(v2, s2)); - - BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1))); - BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1))); + CHECK_EQ("foobar", toml::get_or(v1, "bazqux")); + CHECK_EQ("bazqux", toml::get_or(v2, "bazqux")); } { toml::value v1("foobar"); toml::value v2(42); - std::string s1("bazqux"); - const std::string s2("bazqux"); - - BOOST_TEST("foobar" == toml::get_or(std::move(v1), s1)); - BOOST_TEST("bazqux" == toml::get_or(std::move(v2), s1)); + CHECK_EQ("foobar", toml::get_or(std::move(v1), "bazqux")); + CHECK_EQ("bazqux", toml::get_or(std::move(v2), "bazqux")); } - { - toml::value v1("foobar"); - toml::value v2(42); - - BOOST_TEST("foobar" == toml::get_or(v1, "bazqux")); - BOOST_TEST("bazqux" == toml::get_or(v2, "bazqux")); - - const char* lit = "bazqux"; - BOOST_TEST("foobar" == toml::get_or(v1, lit)); - BOOST_TEST("bazqux" == toml::get_or(v2, lit)); - } - { - toml::value v1("foobar"); - toml::value v2(42); - - BOOST_TEST("foobar" == toml::get_or(std::move(v1), "bazqux")); - BOOST_TEST("bazqux" == toml::get_or(std::move(v2), "bazqux")); - } - { - toml::value v1("foobar"); - toml::value v2(42); - - const char* lit = "bazqux"; - BOOST_TEST("foobar" == toml::get_or(v1, lit)); - BOOST_TEST("bazqux" == toml::get_or(v2, lit)); - } - } diff --git a/tests/test_lex_aux.hpp b/tests/test_lex_aux.hpp deleted file mode 100644 index 77f2a9b..0000000 --- a/tests/test_lex_aux.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include - -#define TOML11_TEST_LEX_ACCEPT(lxr, tkn, expct) \ -do { \ - const std::string token (tkn); \ - const std::string expected(expct); \ - toml::detail::location loc("test", token); \ - const auto result = lxr::invoke(loc); \ - BOOST_TEST(result.is_ok()); \ - if(result.is_ok()){ \ - const auto region = result.unwrap(); \ - BOOST_TEST(region.str() == expected); \ - BOOST_TEST(region.str().size() == expected.size()); \ - BOOST_TEST(static_cast(std::distance( \ - loc.begin(), loc.iter())) == region.size()); \ - } else { \ - std::cerr << "lexer failed with input `"; \ - std::cerr << token << "`. expected `" << expected << "`\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ - } \ -} while(false); \ -/**/ - -#define TOML11_TEST_LEX_REJECT(lxr, tkn) \ -do { \ - const std::string token (tkn); \ - toml::detail::location loc("test", token); \ - const auto result = lxr::invoke(loc); \ - BOOST_TEST(result.is_err()); \ - const bool loc_same = (loc.begin() == loc.iter()); \ - BOOST_TEST(loc_same); \ -} while(false); /**/ diff --git a/tests/test_lex_boolean.cpp b/tests/test_lex_boolean.cpp deleted file mode 100644 index deecffe..0000000 --- a/tests/test_lex_boolean.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_lex_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_correct) -{ - TOML11_TEST_LEX_ACCEPT(lex_boolean, "true", "true"); - TOML11_TEST_LEX_ACCEPT(lex_boolean, "false", "false"); - TOML11_TEST_LEX_ACCEPT(lex_boolean, "true # trailing", "true"); - TOML11_TEST_LEX_ACCEPT(lex_boolean, "false # trailing", "false"); -} - -BOOST_AUTO_TEST_CASE(test_invalid) -{ - TOML11_TEST_LEX_REJECT(lex_boolean, "TRUE"); - TOML11_TEST_LEX_REJECT(lex_boolean, "FALSE"); - TOML11_TEST_LEX_REJECT(lex_boolean, "True"); - TOML11_TEST_LEX_REJECT(lex_boolean, "False"); -} diff --git a/tests/test_lex_datetime.cpp b/tests/test_lex_datetime.cpp deleted file mode 100644 index 8e33d38..0000000 --- a/tests/test_lex_datetime.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_lex_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_offset_datetime) -{ - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27T07:32:00Z", - "1979-05-27T07:32:00Z"); - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27T07:32:00-07:00", - "1979-05-27T07:32:00-07:00"); - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27T07:32:00.999999-07:00", - "1979-05-27T07:32:00.999999-07:00"); - - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27 07:32:00Z", - "1979-05-27 07:32:00Z"); - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27 07:32:00-07:00", - "1979-05-27 07:32:00-07:00"); - TOML11_TEST_LEX_ACCEPT(lex_offset_date_time, - "1979-05-27 07:32:00.999999-07:00", - "1979-05-27 07:32:00.999999-07:00"); -} - -BOOST_AUTO_TEST_CASE(test_local_datetime) -{ - TOML11_TEST_LEX_ACCEPT(lex_local_date_time, - "1979-05-27T07:32:00", - "1979-05-27T07:32:00"); - TOML11_TEST_LEX_ACCEPT(lex_local_date_time, - "1979-05-27T07:32:00.999999", - "1979-05-27T07:32:00.999999"); - - TOML11_TEST_LEX_ACCEPT(lex_local_date_time, - "1979-05-27 07:32:00", - "1979-05-27 07:32:00"); - TOML11_TEST_LEX_ACCEPT(lex_local_date_time, - "1979-05-27 07:32:00.999999", - "1979-05-27 07:32:00.999999"); -} - -BOOST_AUTO_TEST_CASE(test_local_date) -{ - TOML11_TEST_LEX_ACCEPT(lex_local_date, "1979-05-27", "1979-05-27"); -} -BOOST_AUTO_TEST_CASE(test_local_time) -{ - TOML11_TEST_LEX_ACCEPT(lex_local_time, "07:32:00", "07:32:00"); - TOML11_TEST_LEX_ACCEPT(lex_local_time, "07:32:00.999999", "07:32:00.999999"); -} diff --git a/tests/test_lex_floating.cpp b/tests/test_lex_floating.cpp deleted file mode 100644 index 8c9cd20..0000000 --- a/tests/test_lex_floating.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_lex_aux.hpp" - -#include - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_fractional_valid) -{ - TOML11_TEST_LEX_ACCEPT(lex_float, "1.0", "1.0" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "0.1", "0.1" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "0.001", "0.001" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "0.100", "0.100" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "+3.14", "+3.14" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "-3.14", "-3.14" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "3.1415_9265_3589", "3.1415_9265_3589" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "+3.1415_9265_3589", "+3.1415_9265_3589"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-3.1415_9265_3589", "-3.1415_9265_3589"); - TOML11_TEST_LEX_ACCEPT(lex_float, "123_456.789", "123_456.789" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "+123_456.789", "+123_456.789" ); - TOML11_TEST_LEX_ACCEPT(lex_float, "-123_456.789", "-123_456.789" ); -} - -BOOST_AUTO_TEST_CASE(test_fractional_invalid) -{ - TOML11_TEST_LEX_REJECT(lex_float, "0."); - TOML11_TEST_LEX_REJECT(lex_float, ".0"); - TOML11_TEST_LEX_REJECT(lex_float, "01.0"); - TOML11_TEST_LEX_REJECT(lex_float, "3,14"); - TOML11_TEST_LEX_REJECT(lex_float, "+-1.0"); - TOML11_TEST_LEX_REJECT(lex_float, "1._0"); -} - -BOOST_AUTO_TEST_CASE(test_exponential_valid) -{ - TOML11_TEST_LEX_ACCEPT(lex_float, "1e10", "1e10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1e+10", "1e+10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1e-10", "1e-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "+1e10", "+1e10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "+1e+10", "+1e+10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "+1e-10", "+1e-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-1e10", "-1e10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-1e+10", "-1e+10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-1e-10", "-1e-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "123e-10", "123e-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1E10", "1E10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1E+10", "1E+10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1E-10", "1E-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "123E-10", "123E-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-10", "1_2_3E-10"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-1_0", "1_2_3E-1_0"); - -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-01", "1_2_3E-01"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-0_1", "1_2_3E-0_1"); -#endif -} - -BOOST_AUTO_TEST_CASE(test_exponential_invalid) -{ - // accept partially - TOML11_TEST_LEX_ACCEPT(lex_float, "1e1E0", "1e1"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1E1e0", "1E1"); -} - -BOOST_AUTO_TEST_CASE(test_both_valid) -{ - TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e23", "6.02e23"); - TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e+23", "6.02e+23"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1.112_650_06e-17", "1.112_650_06e-17"); - -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e-07", "1.0e-07"); -#endif -} - -BOOST_AUTO_TEST_CASE(test_both_invalid) -{ - TOML11_TEST_LEX_REJECT(lex_float, "01e1.0"); - // accept partially - TOML11_TEST_LEX_ACCEPT(lex_float, "1e1.0", "1e1"); - -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e_01", "1.0"); - TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e0__1", "1.0e0"); -#endif -} - -BOOST_AUTO_TEST_CASE(test_special_floating_point) -{ - TOML11_TEST_LEX_ACCEPT(lex_float, "inf", "inf"); - TOML11_TEST_LEX_ACCEPT(lex_float, "+inf", "+inf"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-inf", "-inf"); - - TOML11_TEST_LEX_ACCEPT(lex_float, "nan", "nan"); - TOML11_TEST_LEX_ACCEPT(lex_float, "+nan", "+nan"); - TOML11_TEST_LEX_ACCEPT(lex_float, "-nan", "-nan"); -} diff --git a/tests/test_lex_integer.cpp b/tests/test_lex_integer.cpp deleted file mode 100644 index 50b9178..0000000 --- a/tests/test_lex_integer.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_lex_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_decimal_correct) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "1234", "1234" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "+1234", "+1234" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "-1234", "-1234" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0", "0" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "1_2_3_4", "1_2_3_4" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "+1_2_3_4", "+1_2_3_4" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "-1_2_3_4", "-1_2_3_4" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "123_456_789", "123_456_789"); -} - -BOOST_AUTO_TEST_CASE(test_decimal_invalid) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "123+45", "123"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "123-45", "123"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "01234", "0"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "123__45", "123"); - - TOML11_TEST_LEX_REJECT(lex_integer, "_1234"); -} - -BOOST_AUTO_TEST_CASE(test_hex_correct) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEADBEEF", "0xDEADBEEF" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdeadbeef", "0xdeadbeef" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEADbeef", "0xDEADbeef" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD_BEEF", "0xDEAD_BEEF"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdead_beef", "0xdead_beef"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xdead_BEEF", "0xdead_BEEF"); - - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xFF", "0xFF" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0x00FF", "0x00FF" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0x0000FF", "0x0000FF"); -} - -BOOST_AUTO_TEST_CASE(test_hex_invalid) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xAPPLE", "0xA"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD+BEEF", "0xDEAD"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0xDEAD__BEEF", "0xDEAD"); - - TOML11_TEST_LEX_REJECT(lex_hex_int, "0x_DEADBEEF"); - TOML11_TEST_LEX_REJECT(lex_hex_int, "0x+DEADBEEF"); - TOML11_TEST_LEX_REJECT(lex_hex_int, "-0xFF" ); - TOML11_TEST_LEX_REJECT(lex_hex_int, "-0x00FF" ); - - TOML11_TEST_LEX_ACCEPT(lex_integer, "0x_DEADBEEF", "0" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0x+DEADBEEF", "0" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "-0xFF" , "-0" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "-0x00FF" , "-0" ); -} - -BOOST_AUTO_TEST_CASE(test_oct_correct) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o777", "0o777" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o7_7_7", "0o7_7_7"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o007", "0o007" ); - -} - -BOOST_AUTO_TEST_CASE(test_oct_invalid) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o77+7", "0o77"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o1__0", "0o1"); - - TOML11_TEST_LEX_REJECT(lex_oct_int, "0o800" ); - TOML11_TEST_LEX_REJECT(lex_oct_int, "-0o777"); - TOML11_TEST_LEX_REJECT(lex_oct_int, "0o+777"); - TOML11_TEST_LEX_REJECT(lex_oct_int, "0o_10" ); - - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o800", "0"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "-0o777", "-0"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o+777", "0"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0o_10", "0"); -} - -BOOST_AUTO_TEST_CASE(test_bin_correct) -{ - TOML11_TEST_LEX_ACCEPT(lex_integer, "0b10000", "0b10000" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0b010000", "0b010000" ); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0b01_00_00", "0b01_00_00"); - TOML11_TEST_LEX_ACCEPT(lex_integer, "0b111111", "0b111111" ); -} - -BOOST_AUTO_TEST_CASE(test_bin_invalid) -{ - TOML11_TEST_LEX_ACCEPT(lex_bin_int, "0b11__11", "0b11"); - TOML11_TEST_LEX_ACCEPT(lex_bin_int, "0b11+11" , "0b11"); - - TOML11_TEST_LEX_REJECT(lex_bin_int, "-0b10000"); - TOML11_TEST_LEX_REJECT(lex_bin_int, "0b_1111" ); -} diff --git a/tests/test_lex_key_comment.cpp b/tests/test_lex_key_comment.cpp deleted file mode 100644 index da123a4..0000000 --- a/tests/test_lex_key_comment.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_lex_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_bare_key) -{ - TOML11_TEST_LEX_ACCEPT(lex_key, "barekey", "barekey"); - TOML11_TEST_LEX_ACCEPT(lex_key, "bare-key", "bare-key"); - TOML11_TEST_LEX_ACCEPT(lex_key, "bare_key", "bare_key"); - TOML11_TEST_LEX_ACCEPT(lex_key, "1234", "1234"); -} - -BOOST_AUTO_TEST_CASE(test_quoted_key) -{ - TOML11_TEST_LEX_ACCEPT(lex_key, "\"127.0.0.1\"", "\"127.0.0.1\""); - TOML11_TEST_LEX_ACCEPT(lex_key, "\"character encoding\"", "\"character encoding\""); - - // UTF-8 codepoint of characters that looks like "key" written upside down - TOML11_TEST_LEX_ACCEPT(lex_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", - "\"\xCA\x8E\xC7\x9D\xCA\x9E\""); - - TOML11_TEST_LEX_ACCEPT(lex_key, "'key2'", "'key2'"); - TOML11_TEST_LEX_ACCEPT(lex_key, "'quoted \"value\"'", "'quoted \"value\"'"); -} - -BOOST_AUTO_TEST_CASE(test_dotted_key) -{ - TOML11_TEST_LEX_ACCEPT(lex_key, "physical.color", "physical.color"); - TOML11_TEST_LEX_ACCEPT(lex_key, "physical.shape", "physical.shape"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x.y", "x.y"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x . y", "x . y"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x.y.z", "x.y.z"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x. y .z", "x. y .z"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x .y. z", "x .y. z"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x . y . z", "x . y . z"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x.y.z.w", "x.y.z.w"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x. y .z. w", "x. y .z. w"); - TOML11_TEST_LEX_ACCEPT(lex_key, "x . y . z . w", "x . y . z . w"); - TOML11_TEST_LEX_ACCEPT(lex_key, "site.\"google.com\"", "site.\"google.com\""); -} - -BOOST_AUTO_TEST_CASE(test_comment) -{ - TOML11_TEST_LEX_ACCEPT(lex_comment, "# hoge", "# hoge"); - TOML11_TEST_LEX_ACCEPT(lex_comment, "# \n", "# "); - TOML11_TEST_LEX_ACCEPT(lex_comment, "# \r\n", "# "); - TOML11_TEST_LEX_ACCEPT(lex_comment, "# # \n", "# # "); -} diff --git a/tests/test_literal.cpp b/tests/test_literal.cpp new file mode 100644 index 0000000..084e3bd --- /dev/null +++ b/tests/test_literal.cpp @@ -0,0 +1,122 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +#include +#include + +TEST_CASE("testing toml value literal") +{ + using namespace toml::literals::toml_literals; + { + const toml::value v1 = "true"_toml; + const toml::value v2 = "false"_toml; + + CHECK_UNARY(v1.is_boolean()); + CHECK_UNARY(v2.is_boolean()); + CHECK_EQ(v1.as_boolean(), true); + CHECK_EQ(v2.as_boolean(), false); + } + { + const toml::value v1 = "123_456"_toml; + const toml::value v2 = "0b0010"_toml; + const toml::value v3 = "0xDEADBEEF"_toml; + + CHECK_UNARY(v1.is_integer()); + CHECK_UNARY(v2.is_integer()); + CHECK_UNARY(v3.is_integer()); + CHECK_EQ(v1.as_integer(), 123456); + CHECK_EQ(v2.as_integer(), 2); + CHECK_EQ(v3.as_integer(), 0xDEADBEEF); + } + { + const toml::value v1 = "3.1415"_toml; + const toml::value v2 = "6.02e+23"_toml; + + CHECK_UNARY(v1.is_floating()); + CHECK_UNARY(v2.is_floating()); + CHECK_EQ(v1.as_floating(), doctest::Approx(3.1415 ).epsilon(0.00001)); + CHECK_EQ(v2.as_floating(), doctest::Approx(6.02e23).epsilon(0.0001 )); + } + { + const toml::value v1 = R"("foo")"_toml; + const toml::value v2 = R"('foo')"_toml; + const toml::value v3 = R"("""foo""")"_toml; + const toml::value v4 = R"('''foo''')"_toml; + + CHECK_UNARY(v1.is_string()); + CHECK_UNARY(v2.is_string()); + CHECK_UNARY(v3.is_string()); + CHECK_UNARY(v4.is_string()); + CHECK_EQ(v1.as_string(), "foo"); + CHECK_EQ(v2.as_string(), "foo"); + CHECK_EQ(v3.as_string(), "foo"); + CHECK_EQ(v4.as_string(), "foo"); + } + { + { + const toml::value v1 = R"([1,2,3])"_toml; + CHECK_UNARY(v1.is_array()); + CHECK_EQ(v1.size(), 3); + CHECK_EQ(v1.at(0).as_integer(), 1); + CHECK_EQ(v1.at(1).as_integer(), 2); + CHECK_EQ(v1.at(2).as_integer(), 3); + } + { + const toml::value v2 = R"([1,])"_toml; + CHECK_UNARY(v2.is_array()); + CHECK_EQ(v2.size(), 1); + CHECK_EQ(v2.at(0).as_integer(), 1); + } + { + const toml::value v3 = R"([[1,]])"_toml; + CHECK_UNARY(v3.is_array()); + CHECK_EQ(v3.size(), 1); + CHECK_UNARY(v3.at(0).is_array()); + CHECK_EQ(v3.at(0).at(0).as_integer(), 1); + } + { + const toml::value v4 = R"([[1],])"_toml; + CHECK_UNARY(v4.is_array()); + CHECK_EQ(v4.size(), 1); + CHECK_UNARY(v4.at(0).is_array()); + CHECK_EQ(v4.at(0).at(0).as_integer(), 1); + } + } + { + const toml::value v1 = R"({a = 42})"_toml; + CHECK_UNARY(v1.is_table()); + CHECK_EQ(v1.size(), 1); + CHECK_UNARY(v1.at("a").is_integer()); + CHECK_EQ(v1.at("a").as_integer(), 42); + } + { + const toml::value v1 = "1979-05-27"_toml; + + CHECK_UNARY(v1.is_local_date()); + CHECK_EQ(v1.as_local_date(), toml::local_date(1979, toml::month_t::May, 27)); + } + { + const toml::value v1 = "12:00:00"_toml; + + CHECK_UNARY(v1.is_local_time()); + CHECK_EQ(v1.as_local_time(), toml::local_time(12, 0, 0)); + } + { + const toml::value v1 = "1979-05-27T07:32:00"_toml; + CHECK_UNARY(v1.is_local_datetime()); + CHECK_EQ(v1.as_local_datetime(), toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0))); + } + { + const toml::value v1 = "1979-05-27T07:32:00Z"_toml; + CHECK_UNARY(v1.is_offset_datetime()); + CHECK_EQ(v1.as_offset_datetime(), toml::offset_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0), + toml::time_offset(0, 0))); + } + +} diff --git a/tests/test_literals.cpp b/tests/test_literals.cpp deleted file mode 100644 index de81f39..0000000 --- a/tests/test_literals.cpp +++ /dev/null @@ -1,336 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include - -BOOST_AUTO_TEST_CASE(test_file_as_literal) -{ - using namespace toml::literals::toml_literals; - - { - const toml::value r{{"a", 42}, {"b", "baz"}}; - const toml::value v = R"( - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"c", 3.14}, - {"table", toml::table{{"a", 42}, {"b", "baz"}}} - }; - const toml::value v = R"( - c = 3.14 - [table] - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"table", toml::table{{"a", 42}, {"b", "baz"}}} - }; - const toml::value v = R"( - [table] - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"array_of_tables", toml::array{toml::table{}}} - }; - const toml::value v = R"( - [[array_of_tables]] - )"_toml; - - BOOST_TEST(r == v); - } -} - -BOOST_AUTO_TEST_CASE(test_value_as_literal) -{ - using namespace toml::literals::toml_literals; - - { - const toml::value v1 = "true"_toml; - const toml::value v2 = "false"_toml; - - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - BOOST_TEST(toml::get(v1)); - BOOST_TEST(!toml::get(v2)); - } - { - const toml::value v1 = "123_456"_toml; - const toml::value v2 = "0b0010"_toml; - const toml::value v3 = "0xDEADBEEF"_toml; - - BOOST_TEST(v1.is_integer()); - BOOST_TEST(v2.is_integer()); - BOOST_TEST(v3.is_integer()); - BOOST_TEST(toml::get(v1) == 123456); - BOOST_TEST(toml::get(v2) == 2); - BOOST_TEST(toml::get(v3) == 0xDEADBEEF); - } - { - const toml::value v1 = "3.1415"_toml; - const toml::value v2 = "6.02e+23"_toml; - - BOOST_TEST(v1.is_floating()); - BOOST_TEST(v2.is_floating()); - BOOST_TEST(toml::get(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); - BOOST_TEST(toml::get(v2) == 6.02e23, boost::test_tools::tolerance(0.0001)); - } - { - const toml::value v1 = R"("foo")"_toml; - const toml::value v2 = R"('foo')"_toml; - const toml::value v3 = R"("""foo""")"_toml; - const toml::value v4 = R"('''foo''')"_toml; - - BOOST_TEST(v1.is_string()); - BOOST_TEST(v2.is_string()); - BOOST_TEST(v3.is_string()); - BOOST_TEST(v4.is_string()); - BOOST_TEST(toml::get(v1) == "foo"); - BOOST_TEST(toml::get(v2) == "foo"); - BOOST_TEST(toml::get(v3) == "foo"); - BOOST_TEST(toml::get(v4) == "foo"); - } - { - { - const toml::value v1 = R"([1,2,3])"_toml; - BOOST_TEST(v1.is_array()); - const bool result = (toml::get>(v1) == std::vector{1,2,3}); - BOOST_TEST(result); - } - { - const toml::value v2 = R"([1,])"_toml; - BOOST_TEST(v2.is_array()); - const bool result = (toml::get>(v2) == std::vector{1}); - BOOST_TEST(result); - } - { - const toml::value v3 = R"([[1,]])"_toml; - BOOST_TEST(v3.is_array()); - const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); - BOOST_TEST(result); - } - { - const toml::value v4 = R"([[1],])"_toml; - BOOST_TEST(v4.is_array()); - const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); - BOOST_TEST(result); - } - } - { - const toml::value v1 = R"({a = 42})"_toml; - - BOOST_TEST(v1.is_table()); - const bool result = toml::get>(v1) == - std::map{{"a", 42}}; - BOOST_TEST(result); - } - { - const toml::value v1 = "1979-05-27"_toml; - - BOOST_TEST(v1.is_local_date()); - BOOST_TEST(toml::get(v1) == - toml::local_date(1979, toml::month_t::May, 27)); - } - { - const toml::value v1 = "12:00:00"_toml; - - BOOST_TEST(v1.is_local_time()); - const bool result = toml::get(v1) == std::chrono::hours(12); - BOOST_TEST(result); - } - { - const toml::value v1 = "1979-05-27T07:32:00"_toml; - BOOST_TEST(v1.is_local_datetime()); - BOOST_TEST(toml::get(v1) == - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0))); - } - { - const toml::value v1 = "1979-05-27T07:32:00Z"_toml; - BOOST_TEST(v1.is_offset_datetime()); - BOOST_TEST(toml::get(v1) == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - } -} - -BOOST_AUTO_TEST_CASE(test_file_as_u8_literal) -{ - using namespace toml::literals::toml_literals; - - { - const toml::value r{{"a", 42}, {"b", "baz"}}; - const toml::value v = u8R"( - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"c", 3.14}, - {"table", toml::table{{"a", 42}, {"b", "baz"}}} - }; - const toml::value v = u8R"( - c = 3.14 - [table] - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"table", toml::table{{"a", 42}, {"b", "baz"}}} - }; - const toml::value v = u8R"( - [table] - a = 42 - b = "baz" - )"_toml; - - BOOST_TEST(r == v); - } - { - const toml::value r{ - {"array_of_tables", toml::array{toml::table{}}} - }; - const toml::value v = u8R"( - [[array_of_tables]] - )"_toml; - - BOOST_TEST(r == v); - } -} - -BOOST_AUTO_TEST_CASE(test_value_as_u8_literal) -{ - using namespace toml::literals::toml_literals; - - { - const toml::value v1 = u8"true"_toml; - const toml::value v2 = u8"false"_toml; - - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - BOOST_TEST(toml::get(v1)); - BOOST_TEST(!toml::get(v2)); - } - { - const toml::value v1 = u8"123_456"_toml; - const toml::value v2 = u8"0b0010"_toml; - const toml::value v3 = u8"0xDEADBEEF"_toml; - - BOOST_TEST(v1.is_integer()); - BOOST_TEST(v2.is_integer()); - BOOST_TEST(v3.is_integer()); - BOOST_TEST(toml::get(v1) == 123456); - BOOST_TEST(toml::get(v2) == 2); - BOOST_TEST(toml::get(v3) == 0xDEADBEEF); - } - { - const toml::value v1 = u8"3.1415"_toml; - const toml::value v2 = u8"6.02e+23"_toml; - - BOOST_TEST(v1.is_floating()); - BOOST_TEST(v2.is_floating()); - BOOST_TEST(toml::get(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); - BOOST_TEST(toml::get(v2) == 6.02e23, boost::test_tools::tolerance(0.0001)); - } - { - const toml::value v1 = u8R"("foo")"_toml; - const toml::value v2 = u8R"('foo')"_toml; - const toml::value v3 = u8R"("""foo""")"_toml; - const toml::value v4 = u8R"('''foo''')"_toml; - const toml::value v5 = u8R"("ひらがな")"_toml; - - BOOST_TEST(v1.is_string()); - BOOST_TEST(v2.is_string()); - BOOST_TEST(v3.is_string()); - BOOST_TEST(v4.is_string()); - BOOST_TEST(v5.is_string()); - BOOST_TEST(toml::get(v1) == "foo"); - BOOST_TEST(toml::get(v2) == "foo"); - BOOST_TEST(toml::get(v3) == "foo"); - BOOST_TEST(toml::get(v4) == "foo"); - BOOST_TEST(toml::get(v5) == "\xE3\x81\xB2\xE3\x82\x89\xE3\x81\x8C\xE3\x81\xAA"); - } - { - { - const toml::value v1 = u8R"([1,2,3])"_toml; - BOOST_TEST(v1.is_array()); - const bool result = (toml::get>(v1) == std::vector{1,2,3}); - BOOST_TEST(result); - } - { - const toml::value v2 = u8R"([1,])"_toml; - BOOST_TEST(v2.is_array()); - const bool result = (toml::get>(v2) == std::vector{1}); - BOOST_TEST(result); - } - { - const toml::value v3 = u8R"([[1,]])"_toml; - BOOST_TEST(v3.is_array()); - const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); - BOOST_TEST(result); - } - { - const toml::value v4 = u8R"([[1],])"_toml; - BOOST_TEST(v4.is_array()); - const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); - BOOST_TEST(result); - } - } - { - const toml::value v1 = u8R"({a = 42})"_toml; - - BOOST_TEST(v1.is_table()); - const bool result = toml::get>(v1) == - std::map{{"a", 42}}; - BOOST_TEST(result); - } - { - const toml::value v1 = u8"1979-05-27"_toml; - - BOOST_TEST(v1.is_local_date()); - BOOST_TEST(toml::get(v1) == - toml::local_date(1979, toml::month_t::May, 27)); - } - { - const toml::value v1 = u8"12:00:00"_toml; - - BOOST_TEST(v1.is_local_time()); - const bool result = toml::get(v1) == std::chrono::hours(12); - BOOST_TEST(result); - } - { - const toml::value v1 = u8"1979-05-27T07:32:00"_toml; - BOOST_TEST(v1.is_local_datetime()); - BOOST_TEST(toml::get(v1) == - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0))); - } - { - const toml::value v1 = u8"1979-05-27T07:32:00Z"_toml; - BOOST_TEST(v1.is_offset_datetime()); - BOOST_TEST(toml::get(v1) == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - } -} diff --git a/tests/test_location.cpp b/tests/test_location.cpp new file mode 100644 index 0000000..108de78 --- /dev/null +++ b/tests/test_location.cpp @@ -0,0 +1,63 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +TEST_CASE("testing location") +{ + const auto first = toml::detail::make_temporary_location("hogefuga"); + + auto loc = first; + loc.advance(4); + + CHECK_UNARY(loc.is_ok()); + CHECK_UNARY( ! loc.eof()); + CHECK_EQ(loc.current(), 'f'); + CHECK_EQ(loc.line_number(), 1); + CHECK_EQ(loc.column_number(), 5); + + const auto loc2 = loc; + CHECK_EQ(loc, loc2); + CHECK_UNARY(loc == loc2); + CHECK_UNARY(!(loc != loc2)); + + loc.advance(4); + CHECK_UNARY(loc.is_ok()); + CHECK_UNARY(loc.eof()); + CHECK_EQ(loc.current(), '\0'); + CHECK_EQ(loc.line_number(), 1); + CHECK_EQ(loc.column_number(), 9); + + CHECK_NE(loc, loc2); + CHECK_UNARY(!(loc == loc2)); + CHECK_UNARY(loc != loc2); + + CHECK_EQ(toml::detail::count(first, loc, 'e'), 1); + CHECK_EQ(toml::detail::count(first, loc, 'g'), 2); +} + +TEST_CASE("testing multiline location") +{ + const auto first = toml::detail::make_temporary_location("hoge\nfuga"); + auto loc = first; + loc.advance(5); + + CHECK_UNARY(loc.is_ok()); + CHECK_UNARY( ! loc.eof()); + CHECK_EQ(loc.current(), 'f'); + CHECK_EQ(loc.line_number(), 2); + CHECK_EQ(loc.column_number(), 1); + + const auto newline_r = toml::detail::rfind(first, loc, '\n'); + CHECK_UNARY(newline_r.is_ok()); + + const auto newline = newline_r.as_ok(); + CHECK_EQ(newline.current(), '\n'); + + loc.advance(4); + CHECK_UNARY(loc.is_ok()); + CHECK_UNARY(loc.eof()); + CHECK_EQ(loc.current(), '\0'); + CHECK_EQ(loc.line_number(), 2); + CHECK_EQ(loc.column_number(), 5); +} diff --git a/tests/test_multiple_translation_unit_1.cpp b/tests/test_multiple_translation_unit_1.cpp deleted file mode 100644 index 08a4f98..0000000 --- a/tests/test_multiple_translation_unit_1.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -int read_a(const toml::table&); - -int main() -{ - const std::string content("a = 0"); - std::istringstream iss(content); - const auto data = toml::parse(iss, "test_multiple_translation_unit.toml"); - return read_a(toml::get(data)); -} diff --git a/tests/test_multiple_translation_unit_2.cpp b/tests/test_multiple_translation_unit_2.cpp deleted file mode 100644 index 2a4cc32..0000000 --- a/tests/test_multiple_translation_unit_2.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int read_a(const toml::table& t) -{ - return toml::get(t.at("a")); -} diff --git a/tests/test_parse_array.cpp b/tests/test_parse_array.cpp index 2d118c2..a367701 100644 --- a/tests/test_parse_array.cpp +++ b/tests/test_parse_array.cpp @@ -1,288 +1,142 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include +#include "utility.hpp" +#include +#include -using namespace toml; -using namespace detail; +#include "doctest.h" -BOOST_AUTO_TEST_CASE(test_oneline_array) +TEST_CASE("testing an array") { - TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[]", array()); - { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[3,1,4,1,5]", a); - } - { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[\"foo\", \"bar\", \"baz\"]", a); - } - { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[3,1,4,1,5,]", a); - } - { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array, "[\"foo\", \"bar\", \"baz\",]", a); - } + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto make_format = [](toml::array_format ty, toml::indent_char ic, std::int32_t i, std::int32_t c) { + toml::array_format_info fmt; + fmt.fmt = ty; + fmt.indent_type = ic; + fmt.body_indent = i; + fmt.closing_indent = c; + return fmt; + }; + + toml11_test_parse_success("[]", (toml::array{}), comments(), make_format(toml::array_format::oneline, toml::indent_char::none, 4, 0), ctx); + toml11_test_parse_success("[1]", (toml::array{1}), comments(), make_format(toml::array_format::oneline, toml::indent_char::none, 4, 0), ctx); + toml11_test_parse_success("[1, 2]", (toml::array{1, 2}), comments(), make_format(toml::array_format::oneline, toml::indent_char::none, 4, 0), ctx); + toml11_test_parse_success("[1, 2, ]", (toml::array{1, 2}), comments(), make_format(toml::array_format::oneline, toml::indent_char::none, 4, 0), ctx); + + toml11_test_parse_success("[\n 1,\n 2,\n]", (toml::array{1, 2}), comments(), make_format(toml::array_format::multiline, toml::indent_char::space, 2, 0), ctx); + toml11_test_parse_success("[\n 1,\n 2,\n ]", (toml::array{1, 2}), comments(), make_format(toml::array_format::multiline, toml::indent_char::space, 2, 2), ctx); + toml11_test_parse_success("[\n\t1,\n\t2,\n]", (toml::array{1, 2}), comments(), make_format(toml::array_format::multiline, toml::indent_char::tab, 1, 0), ctx); + toml11_test_parse_success("[\n\t1,\n\t2,\n\t]", (toml::array{1, 2}), comments(), make_format(toml::array_format::multiline, toml::indent_char::tab, 1, 1), ctx); + + // comment 3 is before comma, so is a comment for `2`. + toml11_test_parse_success(R"([ + 1, # comment 1 + 2, # comment 2 +# comment 3 + # comment 4 +# comment 5 +])", + (toml::array{ + toml::value(1, comments("# comment 1")), + toml::value(2, comments("# comment 2")), + }), comments(), make_format(toml::array_format::multiline, toml::indent_char::space, 4, 0), ctx); + + // comment 3 is before comma, so is a comment for `2`. + toml11_test_parse_success(R"([ + 1, # comment 1 + 2, # comment 2 +# comment 3 + # comment 4 +# comment 5 + ])", + (toml::array{ + toml::value(1, comments("# comment 1")), + toml::value(2, comments("# comment 2")), + }), comments(), make_format(toml::array_format::multiline, toml::indent_char::space, 4, 2), ctx); + + // comment 3 is before comma, so is a comment for `2`. + toml11_test_parse_success(R"([1 # comment 1 +, 2 # comment 2 +# comment 3 +, # comment 4 +# comment 5 (free comment) +])", + (toml::array{ + toml::value(1, comments("# comment 1")), + toml::value(2, comments("# comment 2", "# comment 3", "# comment 4")), + }), comments(), make_format(toml::array_format::multiline, toml::indent_char::none, 4, 0), ctx); + + + toml11_test_parse_success(R"([1 # comment 1 +, # comment 2 +# comment 3 +# ditto + +# comment 4 +2 # comment 5 +# comment 6 +, 3 +# comment 7 +])", + (toml::array{ + toml::value(1, comments("# comment 1", "# comment 2")), + toml::value(2, comments("# comment 4", "# comment 5", "# comment 6")), + toml::value(3, comments("# comment 7")), + }), comments(), make_format(toml::array_format::multiline, toml::indent_char::none, 4, 0), ctx); } -BOOST_AUTO_TEST_CASE(test_oneline_array_value) +TEST_CASE("testing invalid arrays") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[]", toml::value(array())); + using namespace toml::detail; { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5]", toml::value(a)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + auto loc = toml::detail::make_temporary_location("[ 1, hoge ]"); + const auto res = parse_array(loc, ctx); + CHECK_UNARY(res.is_err()); + + for(const auto& e : ctx.errors()) + { + std::cerr << toml::format_error(e) << std::endl; + } } + { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\"]", toml::value(a)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + auto loc = toml::detail::make_temporary_location("[ 1, 2"); + const auto res = parse_array(loc, ctx); + CHECK_UNARY(res.is_err()); + ctx.report_error(res.unwrap_err()); + + for(const auto& e : ctx.errors()) + { + std::cerr << toml::format_error(e) << std::endl; + } } + { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5,]", toml::value(a)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + auto loc = toml::detail::make_temporary_location("["); + const auto res = parse_array(loc, ctx); + CHECK_UNARY(res.is_err()); + ctx.report_error(res.unwrap_err()); + + for(const auto& e : ctx.errors()) + { + std::cerr << toml::format_error(e) << std::endl; + } } + { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\",]", toml::value(a)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + auto loc = toml::detail::make_temporary_location("[ 1, 2, 3\n a = b"); + const auto res = parse_array(loc, ctx); + CHECK_UNARY(res.is_err()); + ctx.report_error(res.unwrap_err()); + + for(const auto& e : ctx.errors()) + { + std::cerr << toml::format_error(e) << std::endl; + } } } - -BOOST_AUTO_TEST_CASE(test_multiline_array) -{ - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\n#comment\n]", typename basic_value< discard_comments>::array_type()); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\n#comment\n]", typename basic_value::array_type()); - - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); - } - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); - } - - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); - } - { - typename basic_value::array_type a(5); - a[0] = basic_value(3, {"comment"}); - a[1] = basic_value(1, {"comment"}); - a[2] = basic_value(4, {"comment"}); - a[3] = basic_value(1, {"comment"}); - a[4] = basic_value(5, {"comment"}); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); - } - - - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("bar"); - a[2] = basic_value("baz"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); - } - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("bar"); - a[2] = basic_value("baz"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); - } - - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("b#r"); - a[2] = basic_value("b#z"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); - } - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo", {"comment"}); - a[1] = basic_value("b#r", {"comment"}); - a[2] = basic_value("b#z", {"comment"}); - TOML11_TEST_PARSE_EQUAL_VAT(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); - } -} - -BOOST_AUTO_TEST_CASE(test_multiline_array_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value< discard_comments>(typename basic_value< discard_comments>::array_type())); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value(typename basic_value::array_type())); - - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); - } - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); - } - - { - typename basic_value::array_type a(5); - a[0] = basic_value(3); - a[1] = basic_value(1); - a[2] = basic_value(4); - a[3] = basic_value(1); - a[4] = basic_value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); - } - { - typename basic_value::array_type a(5); - a[0] = basic_value(3, {"comment"}); - a[1] = basic_value(1, {"comment"}); - a[2] = basic_value(4, {"comment"}); - a[3] = basic_value(1, {"comment"}); - a[4] = basic_value(5, {"comment"}); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); - } - - - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("bar"); - a[2] = basic_value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); - } - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("bar"); - a[2] = basic_value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); - } - - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("b#r"); - a[2] = basic_value("b#z"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); - } - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo", {"comment"}); - a[1] = basic_value("b#r", {"comment"}); - a[2] = basic_value("b#z", {"comment"}); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); - } - -} - -BOOST_AUTO_TEST_CASE(test_heterogeneous_array) -{ -#ifndef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("In strict TOML v0.5.0, heterogeneous arrays are not allowed."); -#else - { - array a(5); - a[0] = toml::value("foo"); - a[1] = toml::value(3.14); - a[2] = toml::value(42); - a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; - a[4] = toml::value{{"key", "value"}}; - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", 3.14, 42, [\"array\", \"of\", \"hetero-array\", 1], {key = \"value\"}]", toml::value(a)); - } - { - array a(5); - a[0] = toml::value("foo"); - a[1] = toml::value(3.14); - a[2] = toml::value(42); - a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; - a[4] = toml::value{{"key", "value"}}; - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n 3.14,\n 42,\n [\"array\", \"of\", \"hetero-array\", 1],\n {key = \"value\"},\n]", toml::value(a)); - } - { - array a(5); - a[0] = toml::value("foo"); - a[1] = toml::value(3.14); - a[2] = toml::value(42); - a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; - a[4] = toml::value{{"key", "value"}}; - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",#comment\n 3.14,#comment\n 42,#comment\n [\"array\", \"of\", \"hetero-array\", 1],#comment\n {key = \"value\"},#comment\n]#comment", toml::value(a)); - } - { - array a(5); - a[0] = toml::value("foo"); - a[1] = toml::value(3.14); - a[2] = toml::value(42); - a[3] = toml::value{toml::value("array"), toml::value("of"), toml::value("hetero-array"), toml::value(1)}; - a[4] = toml::value{{"key", "value"}}; - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n 3.14,\n 42,\n [\"array\",\n \"of\",\n \"hetero-array\",\n 1],\n {key = \"value\"},\n]", toml::value(a)); - } -#endif -} - -BOOST_AUTO_TEST_CASE(test_comments_after_comma) -{ - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo"); - a[1] = basic_value("bar"); - a[2] = basic_value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, - "[ \"foo\" # comment\n" - ", \"bar\" # comment\n" - ", \"baz\" # comment\n" - "]", basic_value(a)); - } - - { - typename basic_value::array_type a(3); - a[0] = basic_value("foo", {" comment"}); - a[1] = basic_value("bar", {" comment"}); - a[2] = basic_value("baz", {" comment"}); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, - "[ \"foo\" # comment\n" - ", \"bar\" # comment\n" - ", \"baz\" # comment\n" - "]", basic_value(a)); - } - -} diff --git a/tests/test_parse_aux.hpp b/tests/test_parse_aux.hpp deleted file mode 100644 index 331d4c8..0000000 --- a/tests/test_parse_aux.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include - -// some of the parsers returns not only a value but also a region. -#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \ -do { \ - const std::string token(tkn); \ - toml::detail::location loc("test", token); \ - const auto result = psr(loc); \ - BOOST_TEST(result.is_ok()); \ - if(result.is_ok()){ \ - BOOST_TEST(result.unwrap().first == expct); \ - } else { \ - std::cerr << "parser " << #psr << " failed with input `"; \ - std::cerr << token << "`.\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ - } \ -} while(false); \ -/**/ - -#define TOML11_TEST_PARSE_EQUAL_VAT(psr, tkn, expct) \ -do { \ - const std::string token(tkn); \ - toml::detail::location loc("test", token); \ - const auto result = psr(loc, 0); \ - BOOST_TEST(result.is_ok()); \ - if(result.is_ok()){ \ - BOOST_TEST(result.unwrap().first == expct); \ - } else { \ - std::cerr << "parser " << #psr << " failed with input `"; \ - std::cerr << token << "`.\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ - } \ -} while(false); \ -/**/ - -#define TOML11_TEST_PARSE_EQUAL_VALUE(psr, tkn, expct) \ -do { \ - const std::string token(tkn); \ - toml::detail::location loc("test", token); \ - const auto result = psr(loc, 0); \ - BOOST_TEST(result.is_ok()); \ - if(result.is_ok()){ \ - BOOST_TEST(result.unwrap() == expct); \ - } else { \ - std::cerr << "parse_value failed with input `"; \ - std::cerr << token << "`.\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ - } \ -} while(false); \ -/**/ - diff --git a/tests/test_parse_boolean.cpp b/tests/test_parse_boolean.cpp index 5ed128c..2a69cc3 100644 --- a/tests/test_parse_boolean.cpp +++ b/tests/test_parse_boolean.cpp @@ -1,19 +1,44 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include "utility.hpp" -using namespace toml; -using namespace detail; +#include +#include -BOOST_AUTO_TEST_CASE(test_boolean) +TEST_CASE("testing valid boolean") { - TOML11_TEST_PARSE_EQUAL(parse_boolean, "true", true); - TOML11_TEST_PARSE_EQUAL(parse_boolean, "false", false); + const toml::detail::context ctx(toml::spec::v(1,0,0)); + { + auto loc = toml::detail::make_temporary_location("true"); + const auto res = toml::detail::parse_boolean(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_boolean()); + + CHECK_EQ(val.as_boolean(), true); + } + { + auto loc = toml::detail::make_temporary_location("false"); + const auto res = toml::detail::parse_boolean(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_boolean()); + + CHECK_EQ(val.as_boolean(), false); + } } -BOOST_AUTO_TEST_CASE(test_boolean_value) +TEST_CASE("testing invalid boolean") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "true", toml::value( true)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "false", toml::value(false)); + using namespace toml::detail; + + const context ctx(toml::spec::v(1,0,0)); + + toml11_test_parse_failure(parse_boolean, "True", ctx); + toml11_test_parse_failure(parse_boolean, "TRUE", ctx); + toml11_test_parse_failure(parse_boolean, "False", ctx); + toml11_test_parse_failure(parse_boolean, "FALSE", ctx); } diff --git a/tests/test_parse_datetime.cpp b/tests/test_parse_datetime.cpp index 46bd78c..f94b13b 100644 --- a/tests/test_parse_datetime.cpp +++ b/tests/test_parse_datetime.cpp @@ -1,246 +1,307 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include "utility.hpp" -using namespace toml; -using namespace detail; +#include -BOOST_AUTO_TEST_CASE(test_time) +TEST_CASE("testing offset_datetime") { - TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00", toml::local_time(7, 32, 0)); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.99", toml::local_time(7, 32, 0, 990, 0)); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.999", toml::local_time(7, 32, 0, 999, 0)); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "07:32:00.999999", toml::local_time(7, 32, 0, 999, 999)); + const auto fmt = [](toml::datetime_delimiter_kind d, bool has_sec, std::size_t prec) { + toml::offset_datetime_format_info f; + f.delimiter = d; + f.has_seconds = has_sec; + f.subsecond_precision = prec; + return f; + }; + + { + toml::detail::context ctx(toml::spec::v(1,0,0)); + + toml11_test_parse_success( + "1979-05-27T07:32:00Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27T07:32:00-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27T07:32:00.999999-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 6), ctx); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "00:00:00.000000", toml::local_time( 0, 0, 0, 0, 0)); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "23:59:59.999999", toml::local_time(23, 59, 59, 999, 999)); - TOML11_TEST_PARSE_EQUAL(parse_local_time, "23:59:60.999999", toml::local_time(23, 59, 60, 999, 999)); // leap second + + toml11_test_parse_success( + "1979-05-27 07:32:00Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27 07:32:00-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27 07:32:00.999999-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 6), ctx); + } + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + toml::detail::context ctx(spec); + + toml11_test_parse_success( + "1979-05-27T07:32Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, false, 0), ctx); + + toml11_test_parse_success( + "1979-05-27T07:32:00Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27T07:32:00-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27T07:32:00.999999-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 6), ctx); + + + toml11_test_parse_success( + "1979-05-27 07:32Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, false, 0), ctx); + + toml11_test_parse_success( + "1979-05-27 07:32:00Z", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(0, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27 07:32:00-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + + toml11_test_parse_success( + "1979-05-27 07:32:00.999999-07:00", + toml::offset_datetime( + toml::local_datetime( + toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 999) + ), + toml::time_offset(-7, 0) + ), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 6), ctx); + } } -BOOST_AUTO_TEST_CASE(test_time_value) +TEST_CASE("testing local_datetime") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00", toml::value(toml::local_time(7, 32, 0))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.99", toml::value(toml::local_time(7, 32, 0, 990, 0))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999", toml::value(toml::local_time(7, 32, 0, 999, 0))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999))); + const auto fmt = [](toml::datetime_delimiter_kind d, bool has_sec, std::size_t prec) { + toml::local_datetime_format_info f; + f.delimiter = d; + f.has_seconds = has_sec; + f.subsecond_precision = prec; + return f; + }; - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "00:00:00.000000", toml::value(toml::local_time( 0, 0, 0, 0, 0))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "23:59:59.999999", toml::value(toml::local_time(23, 59, 59, 999, 999))); + { + toml::detail::context ctx(toml::spec::v(1,0,0)); - std::istringstream stream1(std::string("invalid-datetime = 24:00:00")); - std::istringstream stream2(std::string("invalid-datetime = 00:60:00")); - std::istringstream stream3(std::string("invalid-datetime = 00:00:61")); - BOOST_CHECK_THROW(toml::parse(stream1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream2), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream3), toml::syntax_error); + toml11_test_parse_success( "1979-05-27T07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + toml11_test_parse_success( "1979-05-27T07:32:00.9999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 900, 0)), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 4), ctx); + + toml11_test_parse_success( "1979-05-27 07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + toml11_test_parse_success( "1979-05-27 07:32:00.9999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 900, 0)), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 4), ctx); + } + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + toml::detail::context ctx(spec); + + toml11_test_parse_success( "1979-05-27T07:32", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, false, 0), ctx); + toml11_test_parse_success( "1979-05-27T07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 0), ctx); + toml11_test_parse_success( "1979-05-27T07:32:00.9999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 900, 0)), + comments(), fmt(toml::datetime_delimiter_kind::upper_T, true, 4), ctx); + + toml11_test_parse_success( "1979-05-27 07:32", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::space, false, 0), ctx); + toml11_test_parse_success( "1979-05-27 07:32:00", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0)), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 0), ctx); + toml11_test_parse_success( "1979-05-27 07:32:00.9999", + toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), + toml::local_time(7, 32, 0, 999, 900, 0)), + comments(), fmt(toml::datetime_delimiter_kind::space, true, 4), ctx); + } } -BOOST_AUTO_TEST_CASE(test_date) +TEST_CASE("testing local_date") { - TOML11_TEST_PARSE_EQUAL(parse_local_date, "1979-05-27", toml::local_date(1979, toml::month_t::May, 27)); + toml::detail::context ctx(toml::spec::v(1,0,0)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-01-01", toml::local_date(2000, toml::month_t::Jan, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-01-31", toml::local_date(2000, toml::month_t::Jan, 31)); - std::istringstream stream1_1(std::string("invalid-datetime = 2000-01-00")); - std::istringstream stream1_2(std::string("invalid-datetime = 2000-01-32")); - BOOST_CHECK_THROW(toml::parse(stream1_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream1_2), toml::syntax_error); + toml11_test_parse_success("1979-05-27", toml::local_date(1979, toml::month_t::May, 27), comments(), toml::local_date_format_info{}, ctx); + toml11_test_parse_success("0979-12-27", toml::local_date( 979, toml::month_t::Dec, 27), comments(), toml::local_date_format_info{}, ctx); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-02-01", toml::local_date(2000, toml::month_t::Feb, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-02-29", toml::local_date(2000, toml::month_t::Feb, 29)); - std::istringstream stream2_1(std::string("invalid-datetime = 2000-02-00")); - std::istringstream stream2_2(std::string("invalid-datetime = 2000-02-30")); - BOOST_CHECK_THROW(toml::parse(stream2_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream2_2), toml::syntax_error); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-00-27", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-13-27", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-05-00", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-05-32", ctx); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2001-02-28", toml::local_date(2001, toml::month_t::Feb, 28)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2004-02-29", toml::local_date(2004, toml::month_t::Feb, 29)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2100-02-28", toml::local_date(2100, toml::month_t::Feb, 28)); - std::istringstream stream2_3(std::string("invalid-datetime = 2001-02-29")); - std::istringstream stream2_4(std::string("invalid-datetime = 2004-02-30")); - std::istringstream stream2_5(std::string("invalid-datetime = 2100-02-29")); - BOOST_CHECK_THROW(toml::parse(stream2_3), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream2_4), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream2_5), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-03-01", toml::local_date(2000, toml::month_t::Mar, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-03-31", toml::local_date(2000, toml::month_t::Mar, 31)); - std::istringstream stream3_1(std::string("invalid-datetime = 2000-03-00")); - std::istringstream stream3_2(std::string("invalid-datetime = 2000-03-32")); - BOOST_CHECK_THROW(toml::parse(stream3_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream3_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-04-01", toml::local_date(2000, toml::month_t::Apr, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-04-30", toml::local_date(2000, toml::month_t::Apr, 30)); - std::istringstream stream4_1(std::string("invalid-datetime = 2000-04-00")); - std::istringstream stream4_2(std::string("invalid-datetime = 2000-04-31")); - BOOST_CHECK_THROW(toml::parse(stream4_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream4_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-05-01", toml::local_date(2000, toml::month_t::May, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-05-31", toml::local_date(2000, toml::month_t::May, 31)); - std::istringstream stream5_1(std::string("invalid-datetime = 2000-05-00")); - std::istringstream stream5_2(std::string("invalid-datetime = 2000-05-32")); - BOOST_CHECK_THROW(toml::parse(stream5_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream5_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-06-01", toml::local_date(2000, toml::month_t::Jun, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-06-30", toml::local_date(2000, toml::month_t::Jun, 30)); - std::istringstream stream6_1(std::string("invalid-datetime = 2000-06-00")); - std::istringstream stream6_2(std::string("invalid-datetime = 2000-06-31")); - BOOST_CHECK_THROW(toml::parse(stream6_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream6_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-07-01", toml::local_date(2000, toml::month_t::Jul, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-07-31", toml::local_date(2000, toml::month_t::Jul, 31)); - std::istringstream stream7_1(std::string("invalid-datetime = 2000-07-00")); - std::istringstream stream7_2(std::string("invalid-datetime = 2000-07-32")); - BOOST_CHECK_THROW(toml::parse(stream7_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream7_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-08-01", toml::local_date(2000, toml::month_t::Aug, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-08-31", toml::local_date(2000, toml::month_t::Aug, 31)); - std::istringstream stream8_1(std::string("invalid-datetime = 2000-08-00")); - std::istringstream stream8_2(std::string("invalid-datetime = 2000-08-32")); - BOOST_CHECK_THROW(toml::parse(stream8_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream8_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-09-01", toml::local_date(2000, toml::month_t::Sep, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-09-30", toml::local_date(2000, toml::month_t::Sep, 30)); - std::istringstream stream9_1(std::string("invalid-datetime = 2000-09-00")); - std::istringstream stream9_2(std::string("invalid-datetime = 2000-09-31")); - BOOST_CHECK_THROW(toml::parse(stream9_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream9_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-10-01", toml::local_date(2000, toml::month_t::Oct, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-10-31", toml::local_date(2000, toml::month_t::Oct, 31)); - std::istringstream stream10_1(std::string("invalid-datetime = 2000-10-00")); - std::istringstream stream10_2(std::string("invalid-datetime = 2000-10-32")); - BOOST_CHECK_THROW(toml::parse(stream10_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream10_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-11-01", toml::local_date(2000, toml::month_t::Nov, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-11-30", toml::local_date(2000, toml::month_t::Nov, 30)); - std::istringstream stream11_1(std::string("invalid-datetime = 2000-11-00")); - std::istringstream stream11_2(std::string("invalid-datetime = 2000-11-31")); - BOOST_CHECK_THROW(toml::parse(stream11_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream11_2), toml::syntax_error); - - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-12-01", toml::local_date(2000, toml::month_t::Dec, 1)); - TOML11_TEST_PARSE_EQUAL(parse_local_date, "2000-12-31", toml::local_date(2000, toml::month_t::Dec, 31)); - std::istringstream stream12_1(std::string("invalid-datetime = 2000-12-00")); - std::istringstream stream12_2(std::string("invalid-datetime = 2000-12-32")); - BOOST_CHECK_THROW(toml::parse(stream12_1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream12_2), toml::syntax_error); - - std::istringstream stream13_1(std::string("invalid-datetime = 2000-13-01")); - BOOST_CHECK_THROW(toml::parse(stream13_1), toml::syntax_error); - std::istringstream stream0_1(std::string("invalid-datetime = 2000-00-01")); - BOOST_CHECK_THROW(toml::parse(stream0_1), toml::syntax_error); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-05-2", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-5-02", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "1979-5-2", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "979-5-2", ctx); + toml11_test_parse_failure(toml::detail::parse_local_date, "12345-05-27", ctx); } -BOOST_AUTO_TEST_CASE(test_date_value) +TEST_CASE("testing local_time") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27", value(toml::local_date(1979, toml::month_t::May, 27))); -} - -BOOST_AUTO_TEST_CASE(test_datetime) -{ - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00.99", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27T07:32:00.999999", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); - - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00.99", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27t07:32:00.999999", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); - - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00.99", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))); - TOML11_TEST_PARSE_EQUAL(parse_local_datetime, "1979-05-27 07:32:00.999999", - toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))); -} - -BOOST_AUTO_TEST_CASE(test_datetime_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); - - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.99", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.999999", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); - - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.99", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.999999", - toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999)))); -} - -BOOST_AUTO_TEST_CASE(test_offset_datetime) -{ - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00Z", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.99Z", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0))); - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.999999Z", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0))); - - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00+09:00", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(9, 0))); - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.99+09:00", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0))); - TOML11_TEST_PARSE_EQUAL(parse_offset_datetime, "1979-05-27T07:32:00.999999+09:00", - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0))); - - std::istringstream stream1(std::string("invalid-datetime = 2000-01-01T00:00:00+24:00")); - std::istringstream stream2(std::string("invalid-datetime = 2000-01-01T00:00:00+00:60")); - BOOST_CHECK_THROW(toml::parse(stream1), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(stream2), toml::syntax_error); -} - -BOOST_AUTO_TEST_CASE(test_offset_datetime_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00Z", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99Z", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999Z", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0)))); - - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00+09:00", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(9, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99+09:00", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999+09:00", - toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0)))); + const auto fmt = [](const bool has_sec, const std::size_t sec_prec) { + toml::local_time_format_info f; + f.has_seconds = has_sec; + f.subsecond_precision = sec_prec; + return f; + + }; + { + toml::detail::context ctx(toml::spec::v(1,0,0)); + + toml11_test_parse_success("01:02:03", toml::local_time(1, 2, 3), comments(), fmt(true, 0), ctx); + toml11_test_parse_success("01:23:45", toml::local_time(1, 23, 45), comments(), fmt(true, 0), ctx); + toml11_test_parse_success("01:23:45.1", toml::local_time(1, 23, 45, 100), comments(), fmt(true, 1), ctx); + toml11_test_parse_success("01:23:45.12", toml::local_time(1, 23, 45, 120), comments(), fmt(true, 2), ctx); + toml11_test_parse_success("01:23:45.123", toml::local_time(1, 23, 45, 123), comments(), fmt(true, 3), ctx); + toml11_test_parse_success("01:23:45.1234", toml::local_time(1, 23, 45, 123, 400), comments(), fmt(true, 4), ctx); + toml11_test_parse_success("01:23:45.1234567", toml::local_time(1, 23, 45, 123, 456, 700), comments(), fmt(true, 7), ctx); + toml11_test_parse_success("01:23:45.123456789", toml::local_time(1, 23, 45, 123, 456, 789), comments(), fmt(true, 9), ctx); + } + + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + + toml::detail::context ctx(spec); + + toml11_test_parse_success("01:23", toml::local_time(1, 23, 0), comments(), fmt(false, 0), ctx); + toml11_test_parse_success("01:02", toml::local_time(1, 2, 0), comments(), fmt(false, 0), ctx); + toml11_test_parse_success("01:02:03", toml::local_time(1, 2, 3), comments(), fmt(true, 0), ctx); + toml11_test_parse_success("01:23:45", toml::local_time(1, 23, 45), comments(), fmt(true, 0), ctx); + toml11_test_parse_success("01:23:45.1", toml::local_time(1, 23, 45, 100), comments(), fmt(true, 1), ctx); + toml11_test_parse_success("01:23:45.12", toml::local_time(1, 23, 45, 120), comments(), fmt(true, 2), ctx); + toml11_test_parse_success("01:23:45.123", toml::local_time(1, 23, 45, 123), comments(), fmt(true, 3), ctx); + toml11_test_parse_success("01:23:45.1234", toml::local_time(1, 23, 45, 123, 400), comments(), fmt(true, 4), ctx); + toml11_test_parse_success("01:23:45.1234567", toml::local_time(1, 23, 45, 123, 456, 700), comments(), fmt(true, 7), ctx); + toml11_test_parse_success("01:23:45.123456789", toml::local_time(1, 23, 45, 123, 456, 789), comments(), fmt(true, 9), ctx); + } } diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp deleted file mode 100644 index 92d8028..0000000 --- a/tests/test_parse_file.cpp +++ /dev/null @@ -1,1009 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include -#include -#include - -BOOST_AUTO_TEST_CASE(test_example) -{ - const auto data = toml::parse(testinput("example.toml")); - - BOOST_TEST(toml::find(data, "title") == "TOML Example"); - const auto owner = toml::find(data, "owner"); - { - BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); - BOOST_TEST(toml::find(owner, "organization") == "GitHub"); - BOOST_TEST(toml::find(owner, "bio") == - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_TEST(toml::find(owner, "dob") == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - } - - const auto database = toml::find(data, "database"); - { - BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_TEST(toml::find(database, "connection_max") == 5000); - BOOST_TEST(toml::find(database, "enabled") == true); - } - - const auto servers = toml::find(data, "servers"); - { - toml::table alpha = toml::find(servers, "alpha"); - BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); - BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); - - toml::table beta = toml::find(servers, "beta"); - BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); - BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); - BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); - } - - const auto clients = toml::find(data, "clients"); - { - toml::array clients_data = toml::find(clients, "data"); - - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); - - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); - - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); - BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); - - BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); - BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); - BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); - } -} - -BOOST_AUTO_TEST_CASE(test_example_stream) -{ - std::ifstream ifs(testinput("example.toml"), std::ios::binary); - const auto data = toml::parse(ifs); - - BOOST_TEST(toml::find(data, "title") == "TOML Example"); - const auto owner = toml::find(data, "owner"); - { - BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); - BOOST_TEST(toml::find(owner, "organization") == "GitHub"); - BOOST_TEST(toml::find(owner, "bio") == - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_TEST(toml::find(owner, "dob") == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - } - - const auto database = toml::find(data, "database"); - { - BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_TEST(toml::find(database, "connection_max") == 5000); - BOOST_TEST(toml::find(database, "enabled") == true); - } - - const auto servers = toml::find(data, "servers"); - { - toml::table alpha = toml::find(servers, "alpha"); - BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); - BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); - - toml::table beta = toml::find(servers, "beta"); - BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); - BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); - BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); - } - - const auto clients = toml::find(data, "clients"); - { - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); - - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); - - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_TEST(toml::get(products.at(0).at("name")) == - "Hammer"); - BOOST_TEST(toml::get(products.at(0).at("sku")) == - 738594937); - - BOOST_TEST(toml::get(products.at(1).at("name")) == - "Nail"); - BOOST_TEST(toml::get(products.at(1).at("sku")) == - 284758393); - BOOST_TEST(toml::get(products.at(1).at("color")) == - "gray"); - } -} - -BOOST_AUTO_TEST_CASE(test_example_file_pointer) -{ - FILE * file = fopen(testinput("example.toml").c_str(), "rb"); - const auto data = toml::parse(file, "toml/tests/example.toml"); - fclose(file); - - BOOST_TEST(toml::find(data, "title") == "TOML Example"); - const auto owner = toml::find(data, "owner"); - { - BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); - BOOST_TEST(toml::find(owner, "organization") == "GitHub"); - BOOST_TEST(toml::find(owner, "bio") == - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_TEST(toml::find(owner, "dob") == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - } - - const auto database = toml::find(data, "database"); - { - BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_TEST(toml::find(database, "connection_max") == 5000); - BOOST_TEST(toml::find(database, "enabled") == true); - } - - const auto servers = toml::find(data, "servers"); - { - toml::table alpha = toml::find(servers, "alpha"); - BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); - BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); - - toml::table beta = toml::find(servers, "beta"); - BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); - BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); - BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); - } - - const auto clients = toml::find(data, "clients"); - { - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); - - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); - - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_TEST(toml::get(products.at(0).at("name")) == - "Hammer"); - BOOST_TEST(toml::get(products.at(0).at("sku")) == - 738594937); - - BOOST_TEST(toml::get(products.at(1).at("name")) == - "Nail"); - BOOST_TEST(toml::get(products.at(1).at("sku")) == - 284758393); - BOOST_TEST(toml::get(products.at(1).at("color")) == - "gray"); - } -} - -BOOST_AUTO_TEST_CASE(test_fruit) -{ - 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"); - { - const auto physical = toml::find(blah.at(0), "physical"); - BOOST_TEST(toml::find(physical, "color") == "red"); - BOOST_TEST(toml::find(physical, "shape") == "round"); - } - { - const auto physical = toml::find(blah.at(1), "physical"); - BOOST_TEST(toml::find(physical, "color") == "yellow"); - BOOST_TEST(toml::find(physical, "shape") == "bent"); - } -} - -BOOST_AUTO_TEST_CASE(test_hard_example) -{ - 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 - #"); - - const auto hard = toml::find(the, "hard"); - const std::vector expected_the_hard_test_array{"] ", " # "}; - BOOST_CHECK(toml::find>(hard, "test_array") == - expected_the_hard_test_array); - const std::vector expected_the_hard_test_array2{ - "Test #11 ]proved that", "Experiment #9 was a success"}; - BOOST_CHECK(toml::find>(hard, "test_array2") == - expected_the_hard_test_array2); - BOOST_TEST(toml::find(hard, "another_test_string") == - " Same thing, but with a string #"); - BOOST_TEST(toml::find(hard, "harder_test_string") == - " And when \"'s are in the string, along with # \""); - - const auto bit = toml::find(hard, "bit#"); - BOOST_TEST(toml::find(bit, "what?") == - "You don't think some user won't do that?"); - const std::vector expected_multi_line_array{"]"}; - BOOST_CHECK(toml::find>(bit, "multi_line_array") == - expected_multi_line_array); -} -BOOST_AUTO_TEST_CASE(test_hard_example_comment) -{ - 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 - #"); - - const auto hard = toml::find(the, "hard"); - const std::vector expected_the_hard_test_array{"] ", " # "}; - BOOST_CHECK(toml::find>(hard, "test_array") == - expected_the_hard_test_array); - const std::vector expected_the_hard_test_array2{ - "Test #11 ]proved that", "Experiment #9 was a success"}; - BOOST_CHECK(toml::find>(hard, "test_array2") == - expected_the_hard_test_array2); - BOOST_TEST(toml::find(hard, "another_test_string") == - " Same thing, but with a string #"); - BOOST_TEST(toml::find(hard, "harder_test_string") == - " And when \"'s are in the string, along with # \""); - - const auto bit = toml::find(hard, "bit#"); - BOOST_TEST(toml::find(bit, "what?") == - "You don't think some user won't do that?"); - const std::vector expected_multi_line_array{"]"}; - BOOST_CHECK(toml::find>(bit, "multi_line_array") == - expected_multi_line_array); -} - - -BOOST_AUTO_TEST_CASE(test_example_preserve_comment) -{ - const auto data = toml::parse(testinput("example.toml")); - - BOOST_TEST(toml::find(data, "title") == "TOML Example"); - const auto owner = toml::find(data, "owner"); - { - BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); - BOOST_TEST(toml::find(owner, "organization") == "GitHub"); - BOOST_TEST(toml::find(owner, "bio") == - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_TEST(toml::find(owner, "dob") == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - BOOST_TEST(toml::find(owner, "dob").comments().at(0) == - " First class dates? Why not?"); - } - - const auto database = toml::find(data, "database"); - { - BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_TEST(toml::find(database, "connection_max") == 5000); - BOOST_TEST(toml::find(database, "enabled") == true); - } - - const auto servers = toml::find(data, "servers"); - { - const auto alpha = toml::find(servers, "alpha"); - BOOST_TEST(alpha.comments().at(0) == - " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); - BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); - - const auto beta = toml::find(servers, "beta"); - BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); - BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); - BOOST_TEST(toml::find(beta, "country") == - "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_TEST(toml::find(beta, "country").comments().at(0) == - " This should be parsed as UTF-8"); - } - - const auto clients = toml::find(data, "clients"); - { - BOOST_TEST(toml::find(clients, "data").comments().at(0) == - " just an update to make sure parsers support it"); - - - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); - - BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == - " Line breaks are OK when inside arrays"); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_TEST(toml::get(products.at(0).at("name")) == - "Hammer"); - BOOST_TEST(toml::get(products.at(0).at("sku")) == - 738594937); - - BOOST_TEST(toml::get(products.at(1).at("name")) == - "Nail"); - BOOST_TEST(toml::get(products.at(1).at("sku")) == - 284758393); - BOOST_TEST(toml::get(products.at(1).at("color")) == - "gray"); - } -} - -BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) -{ - const auto data = toml::parse( - testinput("example.toml")); - - static_assert(std::is_same::type> - >::value, ""); - static_assert(std::is_same::type> - >::value, ""); - - BOOST_TEST(toml::find(data, "title") == "TOML Example"); - const auto owner = toml::find(data, "owner"); - { - BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); - BOOST_TEST(toml::find(owner, "organization") == "GitHub"); - BOOST_TEST(toml::find(owner, "bio") == - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_TEST(toml::find(owner, "dob") == - toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), - toml::local_time(7, 32, 0), toml::time_offset(0, 0))); - BOOST_TEST(toml::find(owner, "dob").comments().at(0) == - " First class dates? Why not?"); - } - - const auto database = toml::find(data, "database"); - { - BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_TEST(toml::find(database, "connection_max") == 5000); - BOOST_TEST(toml::find(database, "enabled") == true); - } - - const auto servers = toml::find(data, "servers"); - { - const auto alpha = toml::find(servers, "alpha"); - BOOST_TEST(alpha.comments().at(0) == - " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); - BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); - - const auto beta = toml::find(servers, "beta"); - BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); - BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); - BOOST_TEST(toml::find(beta, "country") == - "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_TEST(toml::find(beta, "country").comments().at(0) == - " This should be parsed as UTF-8"); - } - - const auto clients = toml::find(data, "clients"); - { - BOOST_TEST(toml::find(clients, "data").comments().at(0) == - " just an update to make sure parsers support it"); - - - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); - - BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == - " Line breaks are OK when inside arrays"); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_TEST(toml::get(products.at(0).at("name")) == - "Hammer"); - BOOST_TEST(toml::get(products.at(0).at("sku")) == - 738594937); - - BOOST_TEST(toml::get(products.at(1).at("name")) == - "Nail"); - BOOST_TEST(toml::get(products.at(1).at("sku")) == - 284758393); - BOOST_TEST(toml::get(products.at(1).at("color")) == - "gray"); - } -} - -// --------------------------------------------------------------------------- -// after here, the test codes generate the content of a file. - -BOOST_AUTO_TEST_CASE(test_file_with_BOM) -{ - { - const std::string table( - "\xEF\xBB\xBF" // BOM - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, "test_file_with_BOM.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "\xEF\xBB\xBF" // BOM - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - ); - { - std::ofstream ofs("tmp.toml"); - ofs << table; - } - const auto data = toml::parse("tmp.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "\xEF\xBB\xBF" // BOM - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, "test_file_with_BOM_CRLF.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "\xEF\xBB\xBF" // BOM - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - ); - { - // with text-mode, "\n" is converted to "\r\n" and the resulting - // value will be "\r\r\n". To avoid the additional "\r", use binary - // mode. - std::ofstream ofs("tmp.toml", std::ios_base::binary); - ofs.write(table.data(), static_cast(table.size())); - } - const auto data = toml::parse("tmp.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } -} - -BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) -{ - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file_CRLF.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\" # comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\" # comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\" \t" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file_ws.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\" \t" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_file_without_newline_at_the_end_of_file_ws.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } -} - - -BOOST_AUTO_TEST_CASE(test_files_end_with_comment) -{ - // comment w/o newline - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "# comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "# comment\n" - "# one more comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // comment w/ newline - - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "# comment\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "# comment\n" - "# one more comment\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // CRLF version - - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "# comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "# comment\r\n" - "# one more comment" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "# comment\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "# comment\r\n" - "# one more comment\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_comment.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } -} - - -BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) -{ - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "\n" - "\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // with whitespaces - - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - " \n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - " \n" - " \n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "\n" - " \n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - " \n" - "\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // with whitespaces but no newline - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - " " - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // without newline - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"\n" - "a = 0" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - - // CRLF - - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "\r\n" - "\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - - // with whitespaces - - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - " \r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - "\r\n" - " \r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - " \r\n" - "\r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - " \r\n" - " \r\n" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } - { - const std::string table( - "key = \"value\"\r\n" - "[table]\r\n" - "key = \"value\"\r\n" - " " - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_with_newline.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } -} - -BOOST_AUTO_TEST_CASE(test_file_ends_without_lf) -{ - { - const std::string table( - "key = \"value\"\n" - "[table]\n" - "key = \"value\"" - ); - std::istringstream iss(table); - const auto data = toml::parse(iss, - "test_files_end_without_lf.toml"); - - BOOST_TEST(toml::find(data, "key") == "value"); - BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); - } -} - -BOOST_AUTO_TEST_CASE(test_parse_function_compiles) -{ - 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 - (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) -{ - BOOST_CHECK_THROW(toml::parse("nonexistent.toml"), std::ios_base::failure); -} diff --git a/tests/test_parse_floating.cpp b/tests/test_parse_floating.cpp index 5c05bab..f406a3c 100644 --- a/tests/test_parse_floating.cpp +++ b/tests/test_parse_floating.cpp @@ -1,181 +1,167 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include "utility.hpp" -#include +#include +#include -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_fractional) +TEST_CASE("testing fractional float") { - TOML11_TEST_PARSE_EQUAL(parse_floating, "1.0", 1.0); - TOML11_TEST_PARSE_EQUAL(parse_floating, "0.1", 0.1); - TOML11_TEST_PARSE_EQUAL(parse_floating, "0.001", 0.001); - TOML11_TEST_PARSE_EQUAL(parse_floating, "0.100", 0.1); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+3.14", 3.14); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-3.14", -3.14); - TOML11_TEST_PARSE_EQUAL(parse_floating, "3.1415_9265_3589", 3.141592653589); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+3.1415_9265_3589", 3.141592653589); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-3.1415_9265_3589", -3.141592653589); - TOML11_TEST_PARSE_EQUAL(parse_floating, "123_456.789", 123456.789); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+123_456.789", 123456.789); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-123_456.789", -123456.789); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+0.0", 0.0); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-0.0", -0.0); + toml::detail::context ctx(toml::spec::v(1,0,0)); + + auto fmt = [](std::size_t prec) { + toml::floating_format_info f; + f.fmt = toml::floating_format::fixed; + f.prec = prec; + return f; + }; + + toml11_test_parse_success("1.0", 1.0 , comments(), fmt( 1), ctx); + toml11_test_parse_success("0.1", 0.1 , comments(), fmt( 1), ctx); + toml11_test_parse_success("0.001", 0.001 , comments(), fmt( 3), ctx); + toml11_test_parse_success("0.100", 0.1 , comments(), fmt( 3), ctx); + toml11_test_parse_success("+3.14", 3.14 , comments(), fmt( 2), ctx); + toml11_test_parse_success("-3.14", -3.14 , comments(), fmt( 2), ctx); + toml11_test_parse_success("3.1415_9265_3589", 3.141592653589, comments(), fmt(12), ctx); + toml11_test_parse_success("+3.1415_9265_3589", 3.141592653589, comments(), fmt(12), ctx); + toml11_test_parse_success("-3.1415_9265_3589", -3.141592653589, comments(), fmt(12), ctx); + toml11_test_parse_success("123_456.789", 123456.789 , comments(), fmt( 3), ctx); + toml11_test_parse_success("+123_456.789", 123456.789 , comments(), fmt( 3), ctx); + toml11_test_parse_success("-123_456.789", -123456.789 , comments(), fmt( 3), ctx); + toml11_test_parse_success("+0.0", 0.0 , comments(), fmt( 1), ctx); + toml11_test_parse_success("-0.0", -0.0 , comments(), fmt( 1), ctx); } -BOOST_AUTO_TEST_CASE(test_fractional_value) +TEST_CASE("testing exponents") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1.0", value( 1.0)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.1", value( 0.1)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.001", value( 0.001)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.100", value( 0.1)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.14", value( 3.14)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.14", value(-3.14)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "3.1415_9265_3589", value( 3.141592653589)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.1415_9265_3589", value( 3.141592653589)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.1415_9265_3589", value(-3.141592653589)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456.789", value( 123456.789)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+123_456.789", value( 123456.789)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-123_456.789", value(-123456.789)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+0.0", value( 0.0)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0.0", value(-0.0)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + + auto fmt = [](std::size_t prec) { + toml::floating_format_info f; + f.fmt = toml::floating_format::scientific; + f.prec = prec; + return f; + }; + + toml11_test_parse_success("1e10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("1e+10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("1e-10", 1e-10 , comments(), fmt(1), ctx); + toml11_test_parse_success("+1e10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("+1e+10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("+1e-10", 1e-10 , comments(), fmt(1), ctx); + toml11_test_parse_success("-1e10", -1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("-1e+10", -1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("-1e-10", -1e-10 , comments(), fmt(1), ctx); + toml11_test_parse_success("123e-10", 123e-10, comments(), fmt(3), ctx); + toml11_test_parse_success("1E10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("1E+10", 1e10 , comments(), fmt(1), ctx); + toml11_test_parse_success("1E-10", 1e-10 , comments(), fmt(1), ctx); + toml11_test_parse_success("123E-10", 123e-10, comments(), fmt(3), ctx); + toml11_test_parse_success("1_2_3E-10", 123e-10, comments(), fmt(3), ctx); + toml11_test_parse_success("1_2_3E-1_0", 123e-10, comments(), fmt(3), ctx); + toml11_test_parse_success("+0e0", 0.0 , comments(), fmt(1), ctx); + toml11_test_parse_success("-0e0", -0.0 , comments(), fmt(1), ctx); } -BOOST_AUTO_TEST_CASE(test_exponential) +TEST_CASE("testing fraction + exponents") { - TOML11_TEST_PARSE_EQUAL(parse_floating, "1e10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1e+10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1e-10", 1e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e+10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+1e-10", 1e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e10", -1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e+10", -1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-1e-10", -1e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "123e-10", 123e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1E10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1E+10", 1e10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1E-10", 1e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "123E-10", 123e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-10", 123e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-1_0", 123e-10); - TOML11_TEST_PARSE_EQUAL(parse_floating, "+0e0", 0.0); - TOML11_TEST_PARSE_EQUAL(parse_floating, "-0e0", -0.0); + toml::detail::context ctx(toml::spec::v(1,0,0)); -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-01", 123e-1); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-0_1", 123e-1); -#endif + auto fmt = [](std::size_t prec) { + toml::floating_format_info f; + f.fmt = toml::floating_format::scientific; + f.prec = prec; + return f; + }; + + toml11_test_parse_success("6.02e23", 6.02e23, comments(), fmt(3), ctx); + toml11_test_parse_success("6.02e+23", 6.02e23, comments(), fmt(3), ctx); + toml11_test_parse_success("1.112_650_06e-17", 1.11265006e-17, comments(), fmt(9), ctx); } -BOOST_AUTO_TEST_CASE(test_exponential_value) +TEST_CASE("testing +/-inf") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e-10", value(1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e-10", value(1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e10", value(-1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e+10", value(-1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e-10", value(-1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123e-10", value(123e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E-10", value(1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123E-10", value(123e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-10", value(123e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-1_0", value(123e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+0e0", value( 0.0)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0e0", value(-0.0)); + toml::detail::context ctx(toml::spec::v(1,0,0)); -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-01", value(123e-1)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-0_1", value(123e-1)); -#endif -} -BOOST_AUTO_TEST_CASE(test_fe) -{ - TOML11_TEST_PARSE_EQUAL(parse_floating, "6.02e23", 6.02e23); - TOML11_TEST_PARSE_EQUAL(parse_floating, "6.02e+23", 6.02e23); - TOML11_TEST_PARSE_EQUAL(parse_floating, "1.112_650_06e-17", 1.11265006e-17); -} -BOOST_AUTO_TEST_CASE(test_fe_vaule) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "6.02e23", value(6.02e23)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "6.02e+23", value(6.02e23)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1.112_650_06e-17", value(1.11265006e-17)); - -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part"); - // toml-lang/toml master permits leading 0s in exp part (unreleased) - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "3.141_5e-01", value(3.1415e-1)); -#endif -} - -BOOST_AUTO_TEST_CASE(test_inf) -{ { - const std::string token("inf"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isinf(r.unwrap().first)); - BOOST_CHECK(r.unwrap().first > 0.0); + auto loc = toml::detail::make_temporary_location("inf"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isinf(val.as_floating())); + CHECK_UNARY(val.as_floating() > 0); // + } { - const std::string token("+inf"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isinf(r.unwrap().first)); - BOOST_CHECK(r.unwrap().first > 0.0); + auto loc = toml::detail::make_temporary_location("+inf"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isinf(val.as_floating())); + CHECK_UNARY(val.as_floating() > 0); // + } { - const std::string token("-inf"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isinf(r.unwrap().first)); - BOOST_CHECK(r.unwrap().first < 0.0); + auto loc = toml::detail::make_temporary_location("-inf"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isinf(val.as_floating())); + CHECK_UNARY(val.as_floating() < 0); // - } } -BOOST_AUTO_TEST_CASE(test_nan) +TEST_CASE("testing +/-nan") { + toml::detail::context ctx(toml::spec::v(1,0,0)); + { - const std::string token("nan"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isnan(r.unwrap().first)); + auto loc = toml::detail::make_temporary_location("nan"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isnan(val.as_floating())); } { - const std::string token("+nan"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isnan(r.unwrap().first)); + auto loc = toml::detail::make_temporary_location("+nan"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isnan(val.as_floating())); } { - const std::string token("-nan"); - toml::detail::location loc("test", token); - const auto r = parse_floating(loc); - BOOST_CHECK(r.is_ok()); - BOOST_CHECK(std::isnan(r.unwrap().first)); + auto loc = toml::detail::make_temporary_location("-nan"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_UNARY(std::isnan(val.as_floating())); } } -BOOST_AUTO_TEST_CASE(test_overflow) +TEST_CASE("testing hexfloat") { - std::istringstream float_overflow (std::string("float-overflow = 1.0e+1024")); - BOOST_CHECK_THROW(toml::parse(float_overflow ), toml::syntax_error); - // istringstream >> float does not set failbit in case of underflow. + toml::spec s = toml::spec::v(1,0,0); + s.ext_hex_float = true; + toml::detail::context ctx(s); + + { + auto loc = toml::detail::make_temporary_location("0xABCp-3"); + const auto res = toml::detail::parse_floating(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + REQUIRE_UNARY(val.is_floating()); + + CHECK_EQ(val.as_floating(), 343.5); + } } diff --git a/tests/test_parse_inline_table.cpp b/tests/test_parse_inline_table.cpp index a11767c..2378be0 100644 --- a/tests/test_parse_inline_table.cpp +++ b/tests/test_parse_inline_table.cpp @@ -1,59 +1,142 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include +#include "utility.hpp" +#include +#include -using namespace toml; -using namespace detail; +#include "doctest.h" -BOOST_AUTO_TEST_CASE(test_inline_table) +TEST_CASE("testing an inline table v1.0") { - TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{}", table()); { - table t; - t["foo"] = toml::value(42); - t["bar"] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{foo = 42, bar = \"baz\"}", t); + // no multiline, no trailing comma + toml::detail::context ctx(toml::spec::v(1,0,0)); + + const auto make_format = [](toml::table_format ty) { + toml::table_format_info fmt; + fmt.fmt = ty; + fmt.indent_type = toml::indent_char::none; + return fmt; + }; + + toml11_test_parse_success("{}", (toml::table{}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a = 1}", (toml::table{{"a", 1}}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a = 1, b = 2}", (toml::table{{"a", 1}, {"b", 2}}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a.b = 1}", (toml::table{{ "a", toml::table{{"b", 1}} }}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a.b = 1, a.c = 2}", (toml::table{{ "a", toml::table{{"b", 1}, {"c", 2}} }}), comments(), make_format(toml::table_format::oneline), ctx); } + + // invalids { - table t; - table t_sub; - t_sub["name"] = toml::value("pug"); - t["type"] = toml::value(t_sub); - TOML11_TEST_PARSE_EQUAL_VAT(parse_inline_table, "{type.name = \"pug\"}", t); + using toml::detail::parse_inline_table; + toml::detail::context ctx(toml::spec::v(1,0,0)); + toml11_test_parse_failure(parse_inline_table, "{ 1, 2 }", ctx); // no key + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2, }", ctx); // trailing comma + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2\n a = b", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{ a.b = 1, a.b.c = 2}", ctx); // a.b is not a table + toml11_test_parse_failure(parse_inline_table, "{ a = 1 # comment\n}", ctx); // newline not allowed } } -BOOST_AUTO_TEST_CASE(test_inline_table_value) +TEST_CASE("testing an inline table v1.0 + trailing comma") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{}", value(table())); { - table t; - t["foo"] = toml::value(42); - t["bar"] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{foo = 42, bar = \"baz\"}", value(t)); + // no multiline, no trailing comma + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_allow_trailing_comma_in_inline_tables = true; + toml::detail::context ctx(spec); + + const auto make_format = [](toml::table_format ty) { + toml::table_format_info fmt; + fmt.fmt = ty; + fmt.indent_type = toml::indent_char::none; + return fmt; + }; + + toml11_test_parse_success("{}", (toml::table{}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a = 1}", (toml::table{{"a", 1}}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a = 1,}", (toml::table{{"a", 1}}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a = 1, b = 2,}", (toml::table{{"a", 1}, {"b", 2}}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a.b = 1}", (toml::table{{ "a", toml::table{{"b", 1}} }}), comments(), make_format(toml::table_format::oneline), ctx); + toml11_test_parse_success("{a.b = 1, a.c = 2}", (toml::table{{ "a", toml::table{{"b", 1}, {"c", 2}} }}), comments(), make_format(toml::table_format::oneline), ctx); } + + // invalids { - table t; - table t_sub; - t_sub["name"] = toml::value("pug"); - t["type"] = toml::value(t_sub); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{type.name = \"pug\"}", value(t)); + using toml::detail::parse_inline_table; + + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_allow_trailing_comma_in_inline_tables = true; + toml::detail::context ctx(spec); + + toml11_test_parse_failure(parse_inline_table, "{ 1, 2 }", ctx); + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2", ctx); + toml11_test_parse_failure(parse_inline_table, "{", ctx); + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2\n a = b", ctx); + toml11_test_parse_failure(parse_inline_table, "{ a.b = 1, a.b.c = 2}", ctx); + toml11_test_parse_failure(parse_inline_table, "{ a = 1 # comment\n}", ctx); } } -BOOST_AUTO_TEST_CASE(test_inline_table_immutability) +TEST_CASE("testing an inline table v1.1") { { - std::istringstream stream(std::string( - "a = {b = 1}\n" - "a.c = 2\n")); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); + // w/ multiline, w/ trailing comma + toml::detail::context ctx(toml::spec::v(1,1,0)); + + const auto make_format = [](toml::table_format ty, + const toml::indent_char ic, + const std::int32_t n, + const std::int32_t b, + const std::int32_t c + ) { + toml::table_format_info fmt; + fmt.fmt = ty; + fmt.indent_type = ic; + fmt.name_indent = n; + fmt.body_indent = b; + fmt.closing_indent = c; + return fmt; + }; + + toml11_test_parse_success("{}", (toml::table{}), comments(), make_format(toml::table_format::oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{a = 1}", (toml::table{{"a", 1}}), comments(), make_format(toml::table_format::oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{a = 1, b = 2}", (toml::table{{"a", 1}, {"b", 2}}), comments(), make_format(toml::table_format::oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{a.b = 1}", (toml::table{{ "a", toml::table{{"b", 1}} }}), comments(), make_format(toml::table_format::oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{a.b = 1, a.c = 2}", (toml::table{{ "a", toml::table{{"b", 1}, {"c", 2}} }}), comments(), make_format(toml::table_format::oneline, toml::indent_char::none,0,0,0), ctx); + + toml11_test_parse_success("{\n}", (toml::table{}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{\na = 1\n}", (toml::table{{"a", 1}}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::none,0,0,0), ctx); + + toml11_test_parse_success("{\n a = 1, \n b = 2\n}", (toml::table{{"a", 1}, {"b", 2}}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 0), ctx); + + toml11_test_parse_success("{\n a.b = 1\n }", (toml::table{{ "a", toml::table{{"b", 1}} }}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 2), ctx); + + toml11_test_parse_success("{a.b = 1,\n a.c = 2}", (toml::table{{ "a", toml::table{{"b", 1}, {"c", 2}} }}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 0), ctx); + + toml11_test_parse_success("{# this table is empty.\n}", (toml::table{}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::none,0,0,0), ctx); + toml11_test_parse_success("{\na = 1 # com\n}", (toml::table{{"a", toml::value(1, {"# com"}) }}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::none,0,0,0), ctx); + + toml11_test_parse_success("{\n a = 1, # com-a\n b = 2 # com-b\n}", (toml::table{{"a", toml::value(1, {"# com-a"}) }, {"b", toml::value(2, {"# com-b"})}}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 0), ctx); + toml11_test_parse_success("{# com-a-b\n a.b = 1\n }", (toml::table{{"a", toml::table{{"b", toml::value(1, {"# com-a-b"})}} }}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 2), ctx); + toml11_test_parse_success("{a.b = 1,\n a.c = 2 # com-a-c\n}", (toml::table{{"a", toml::table{{"b", 1}, {"c", toml::value(2, {"# com-a-c"})}} }}), comments(), make_format(toml::table_format::multiline_oneline, toml::indent_char::space, 0, 2, 0), ctx); } + + // invalids { - std::istringstream stream(std::string( - "a = {b = {c = 1}}\n" - "a.b.d = 2\n")); - BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); + using toml::detail::parse_inline_table; + + auto spec = toml::spec::v(1,1,0); + toml::detail::context ctx(spec); + + toml11_test_parse_failure(parse_inline_table, "{ 1, 2 }", ctx); // no key + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{ a = 1, b = 2\n a = b", ctx); // no closing bracket + toml11_test_parse_failure(parse_inline_table, "{ a.b = 1, a.b.c = 2}", ctx); // a.b is not a table } } + diff --git a/tests/test_parse_integer.cpp b/tests/test_parse_integer.cpp index 4a86226..da510da 100644 --- a/tests/test_parse_integer.cpp +++ b/tests/test_parse_integer.cpp @@ -1,116 +1,147 @@ -#include -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -using namespace toml; -using namespace detail; +#include "utility.hpp" -BOOST_AUTO_TEST_CASE(test_decimal) +#include +#include + +TEST_CASE("testing decimal_value") { - TOML11_TEST_PARSE_EQUAL(parse_integer, "1234", 1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "+1234", 1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "-1234", -1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0", 0); - TOML11_TEST_PARSE_EQUAL(parse_integer, "1_2_3_4", 1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "+1_2_3_4", +1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "-1_2_3_4", -1234); - TOML11_TEST_PARSE_EQUAL(parse_integer, "123_456_789", 123456789); + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto decimal_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::dec; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + toml11_test_parse_success( "0", 0, comments(), decimal_fmt(1, 0), ctx); + toml11_test_parse_success( "+0", 0, comments(), decimal_fmt(2, 0), ctx); + toml11_test_parse_success( "-0", 0, comments(), decimal_fmt(2, 0), ctx); + toml11_test_parse_success( "1234", 1234, comments(), decimal_fmt(4, 0), ctx); + toml11_test_parse_success( "+1234", 1234, comments(), decimal_fmt(5, 0), ctx); + toml11_test_parse_success( "-1234", -1234, comments(), decimal_fmt(5, 0), ctx); + toml11_test_parse_success( "0", 0, comments(), decimal_fmt(1, 0), ctx); + toml11_test_parse_success( "1_2_3_4", 1234, comments(), decimal_fmt(4, 1), ctx); + toml11_test_parse_success( "+1_2_3_4", +1234, comments(), decimal_fmt(5, 1), ctx); + toml11_test_parse_success( "-1_2_3_4", -1234, comments(), decimal_fmt(5, 1), ctx); + toml11_test_parse_success("123_456_789", 123456789, comments(), decimal_fmt(9, 3), ctx); } -BOOST_AUTO_TEST_CASE(test_decimal_value) +TEST_CASE("testing hex_value") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1234", toml::value( 1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1234", toml::value( 1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1234", toml::value( -1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0", toml::value( 0)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3_4", toml::value( 1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1_2_3_4", toml::value( +1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1_2_3_4", toml::value( -1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456_789", toml::value(123456789)); + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto hex_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::hex; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + toml11_test_parse_success("0xDEADBEEF", 0xDEADBEEF, comments(), hex_fmt(8, 0), ctx); + toml11_test_parse_success("0xdeadbeef", 0xDEADBEEF, comments(), hex_fmt(8, 0), ctx); + toml11_test_parse_success("0xDEADbeef", 0xDEADBEEF, comments(), hex_fmt(8, 0), ctx); + toml11_test_parse_success("0xDEAD_BEEF", 0xDEADBEEF, comments(), hex_fmt(8, 4), ctx); + toml11_test_parse_success("0xdead_beef", 0xDEADBEEF, comments(), hex_fmt(8, 4), ctx); + toml11_test_parse_success("0xdead_BEEF", 0xDEADBEEF, comments(), hex_fmt(8, 4), ctx); + toml11_test_parse_success("0xFF", 0xFF, comments(), hex_fmt(2, 0), ctx); + toml11_test_parse_success("0x00FF", 0xFF, comments(), hex_fmt(4, 0), ctx); + toml11_test_parse_success("0x0000FF", 0xFF, comments(), hex_fmt(6, 0), ctx); } -BOOST_AUTO_TEST_CASE(test_hex) +TEST_CASE("testing oct_value") { - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEADBEEF", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdeadbeef", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEADbeef", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xDEAD_BEEF", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdead_beef", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xdead_BEEF", 0xDEADBEEF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0xFF", 0xFF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0x00FF", 0xFF); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0x0000FF", 0xFF); + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto oct_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::oct; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; + + toml11_test_parse_success("0o777", 64*7+8*7+7, comments(), oct_fmt(3, 0), ctx); + toml11_test_parse_success("0o7_7_7", 64*7+8*7+7, comments(), oct_fmt(3, 1), ctx); + toml11_test_parse_success("0o007", 7, comments(), oct_fmt(3, 0), ctx); } -BOOST_AUTO_TEST_CASE(test_hex_value) +TEST_CASE("testing bin_value") { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADBEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdeadbeef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADbeef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEAD_BEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_beef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_BEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xFF", value(0xFF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x00FF", value(0xFF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x0000FF", value(0xFF)); -} + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto bin_fmt = [](std::size_t w, std::size_t s) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::bin; + fmt.width = w; + fmt.spacer = s; + return fmt; + }; -BOOST_AUTO_TEST_CASE(test_oct) -{ - TOML11_TEST_PARSE_EQUAL(parse_integer, "0o777", 64*7+8*7+7); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0o7_7_7", 64*7+8*7+7); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0o007", 7); -} + toml11_test_parse_success("0b10000", 16, comments(), bin_fmt(5, 0), ctx); + toml11_test_parse_success("0b010000", 16, comments(), bin_fmt(6, 0), ctx); + toml11_test_parse_success("0b01_00_00", 16, comments(), bin_fmt(6, 2), ctx); + toml11_test_parse_success("0b111111", 63, comments(), bin_fmt(6, 0), ctx); -BOOST_AUTO_TEST_CASE(test_oct_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o777", value(64*7+8*7+7)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o7_7_7", value(64*7+8*7+7)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o007", value(7)); -} - -BOOST_AUTO_TEST_CASE(test_bin) -{ - TOML11_TEST_PARSE_EQUAL(parse_integer, "0b10000", 16); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0b010000", 16); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0b01_00_00", 16); - TOML11_TEST_PARSE_EQUAL(parse_integer, "0b111111", 63); -} - -BOOST_AUTO_TEST_CASE(test_bin_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b10000", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b010000", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b01_00_00", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b111111", value(63)); - - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + toml11_test_parse_success( "0b1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000_1000", - // 1 0 0 0 - // 0 C 8 4 - value(0x0888888888888888)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + 0x0888888888888888, comments(), bin_fmt(60, 4), ctx); + toml11_test_parse_success( "0b01111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111", - // 1 0 0 0 - // 0 C 8 4 - value(0x7FFFFFFFFFFFFFFF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + 0x7FFFFFFFFFFFFFFF, comments(), bin_fmt(64, 8), ctx); + toml11_test_parse_success( "0b00000000_01111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111", - // 1 0 0 0 - // 0 C 8 4 - value(0x7FFFFFFFFFFFFFFF)); + 0x7FFFFFFFFFFFFFFF, comments(), bin_fmt(72, 8), ctx); } -BOOST_AUTO_TEST_CASE(test_integer_overflow) +TEST_CASE("testing integer_overflow") { - std::istringstream dec_overflow(std::string("dec-overflow = 9223372036854775808")); - std::istringstream hex_overflow(std::string("hex-overflow = 0x1_00000000_00000000")); - std::istringstream oct_overflow(std::string("oct-overflow = 0o1_000_000_000_000_000_000_000")); - // 64 56 48 40 32 24 16 8 - std::istringstream bin_overflow(std::string("bin-overflow = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")); - BOOST_CHECK_THROW(toml::parse(dec_overflow), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(hex_overflow), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(oct_overflow), toml::syntax_error); - BOOST_CHECK_THROW(toml::parse(bin_overflow), toml::syntax_error); + toml::detail::context ctx(toml::spec::v(1,0,0)); + { + auto loc = toml::detail::make_temporary_location("9223372036854775808"); + const auto res = toml::detail::parse_dec_integer(loc, ctx); + CHECK_UNARY(res.is_err()); + } + { + auto loc = toml::detail::make_temporary_location("0x1_00000000_00000000"); + const auto res = toml::detail::parse_hex_integer(loc, ctx); + CHECK_UNARY(res.is_err()); + } + { + auto loc = toml::detail::make_temporary_location("0o1_000_000_000_000_000_000_000"); + const auto res = toml::detail::parse_oct_integer(loc, ctx); + CHECK_UNARY(res.is_err()); + } + { + // 64 56 48 40 32 24 16 8 + auto loc = toml::detail::make_temporary_location("0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000"); + const auto res = toml::detail::parse_oct_integer(loc, ctx); + CHECK_UNARY(res.is_err()); + } +} + +TEST_CASE("testing decimal_value with suffix extension") +{ + auto spec = toml::spec::v(1, 0, 0); + spec.ext_num_suffix = true; + + toml::detail::context ctx(spec); + const auto decimal_fmt = [](std::size_t w, std::size_t s, std::string x) { + toml::integer_format_info fmt; + fmt.fmt = toml::integer_format::dec; + fmt.width = w; + fmt.spacer = s; + fmt.suffix = std::move(x); + return fmt; + }; + toml11_test_parse_success( "1234_μm", 1234, comments(), decimal_fmt(4, 0, "μm"), ctx); + toml11_test_parse_success( "+1234_μm", 1234, comments(), decimal_fmt(5, 0, "μm"), ctx); + toml11_test_parse_success( "-1234_μm", -1234, comments(), decimal_fmt(5, 0, "μm"), ctx); + toml11_test_parse_success( "0_μm", 0, comments(), decimal_fmt(1, 0, "μm"), ctx); + toml11_test_parse_success( "1_2_3_4_μm", 1234, comments(), decimal_fmt(4, 1, "μm"), ctx); + toml11_test_parse_success( "+1_2_3_4_μm", +1234, comments(), decimal_fmt(5, 1, "μm"), ctx); + toml11_test_parse_success( "-1_2_3_4_μm", -1234, comments(), decimal_fmt(5, 1, "μm"), ctx); + toml11_test_parse_success("123_456_789_μm", 123456789, comments(), decimal_fmt(9, 3, "μm"), ctx); } diff --git a/tests/test_parse_key.cpp b/tests/test_parse_key.cpp deleted file mode 100644 index 3af0eaa..0000000 --- a/tests/test_parse_key.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_parse_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_bare_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_key, "barekey", std::vector(1, "barekey")); - TOML11_TEST_PARSE_EQUAL(parse_key, "bare-key", std::vector(1, "bare-key")); - TOML11_TEST_PARSE_EQUAL(parse_key, "bare_key", std::vector(1, "bare_key")); - TOML11_TEST_PARSE_EQUAL(parse_key, "1234", std::vector(1, "1234")); -} - -BOOST_AUTO_TEST_CASE(test_quoted_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_key, "\"127.0.0.1\"", std::vector(1, "127.0.0.1" )); - TOML11_TEST_PARSE_EQUAL(parse_key, "\"character encoding\"", std::vector(1, "character encoding")); -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) - TOML11_TEST_PARSE_EQUAL(parse_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", std::vector(1, "\xCA\x8E\xC7\x9D\xCA\x9E")); -#else - TOML11_TEST_PARSE_EQUAL(parse_key, "\"ʎǝʞ\"", std::vector(1, "ʎǝʞ" )); -#endif - TOML11_TEST_PARSE_EQUAL(parse_key, "'key2'", std::vector(1, "key2" )); - TOML11_TEST_PARSE_EQUAL(parse_key, "'quoted \"value\"'", std::vector(1, "quoted \"value\"" )); -} - -BOOST_AUTO_TEST_CASE(test_dotted_key) -{ - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "color"; - TOML11_TEST_PARSE_EQUAL(parse_key, "physical.color", keys); - } - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "shape"; - TOML11_TEST_PARSE_EQUAL(parse_key, "physical.shape", keys); - } - { - std::vector keys(4); - keys[0] = "x"; - keys[1] = "y"; - keys[2] = "z"; - keys[3] = "w"; - TOML11_TEST_PARSE_EQUAL(parse_key, "x.y.z.w", keys); - } - { - std::vector keys(2); - keys[0] = "site"; - keys[1] = "google.com"; - TOML11_TEST_PARSE_EQUAL(parse_key, "site.\"google.com\"", keys); - } -} diff --git a/tests/test_parse_null.cpp b/tests/test_parse_null.cpp new file mode 100644 index 0000000..d9f12de --- /dev/null +++ b/tests/test_parse_null.cpp @@ -0,0 +1,90 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include +#include + +TEST_CASE("testing null value extension") +{ + toml::spec spec = toml::spec::v(1,0,0); + spec.ext_null_value = true; + toml::detail::context ctx(spec); + + auto loc = toml::detail::make_temporary_location("null"); + + const auto res = toml::detail::parse_value(loc, ctx); + if(res.is_err()) + { + std::cerr << format_error(res.unwrap_err()) << std::endl; + } + REQUIRE_UNARY(res.is_ok()); + const auto val = res.unwrap(); + + REQUIRE_UNARY(val.is_empty()); +} + +TEST_CASE("testing null value extension OFF") +{ + toml::spec spec = toml::spec::v(1,0,0); + toml::detail::context ctx(spec); + + auto loc = toml::detail::make_temporary_location("null"); + + const auto res = toml::detail::parse_value(loc, ctx); + CHECK_UNARY(res.is_err()); +} + +TEST_CASE("testing null value extension, w/ comments") +{ + toml::spec spec = toml::spec::v(1,0,0); + spec.ext_null_value = true; + toml::detail::context ctx(spec); + + auto loc = toml::detail::make_temporary_location(R"(a = null # comment)"); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + if(res.is_err()) + { + std::cerr << format_error(res.unwrap_err()) << std::endl; + } + REQUIRE_UNARY(res.is_ok()); + + CHECK_UNARY(table.contains("a")); + const auto null = table.at("a"); + + CHECK_UNARY(null.is_empty()); + CHECK_EQ(null.comments().size(), 1); + CHECK_EQ(null.comments().at(0), "# comment"); +} + +TEST_CASE("testing null value extension, in an array") +{ + toml::spec spec = toml::spec::v(1,0,0); + spec.ext_null_value = true; + toml::detail::context ctx(spec); + + auto loc = toml::detail::make_temporary_location(R"(a = [1, null, 3, 4, 5])"); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + if(res.is_err()) + { + std::cerr << format_error(res.unwrap_err()) << std::endl; + } + REQUIRE_UNARY(res.is_ok()); + + CHECK_UNARY(table.contains("a")); + const auto a = table.at("a"); + + CHECK_UNARY(a.is_array()); + CHECK_EQ(a.as_array().size(), 5); + + CHECK_UNARY(a.as_array().at(0).is_integer()); + CHECK_UNARY(a.as_array().at(1).is_empty()); + CHECK_UNARY(a.as_array().at(2).is_integer()); + CHECK_UNARY(a.as_array().at(3).is_integer()); + CHECK_UNARY(a.as_array().at(4).is_integer()); +} diff --git a/tests/test_parse_string.cpp b/tests/test_parse_string.cpp index bf381e3..9dac305 100644 --- a/tests/test_parse_string.cpp +++ b/tests/test_parse_string.cpp @@ -1,245 +1,272 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include "utility.hpp" +#include -using namespace toml; -using namespace detail; +#include +#include -BOOST_AUTO_TEST_CASE(test_string) +TEST_CASE("testing basic string") { - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"The quick brown fox jumps over the lazy dog\"", - string("The quick brown fox jumps over the lazy dog", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\'The quick brown fox jumps over the lazy dog\'", - string("The quick brown fox jumps over the lazy dog", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", - string("The quick brown fox jumps over the lazy dog", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "'''The quick brown fox \njumps over the lazy dog'''", - string("The quick brown fox \njumps over the lazy dog", string_t::literal)); -} + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto string_fmt = []() { + // inline basic_string does not use format settings + toml::string_format_info fmt; + fmt.fmt = toml::string_format::basic; + return fmt; + }; -BOOST_AUTO_TEST_CASE(test_string_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\"The quick brown fox jumps over the lazy dog\"", - toml::value("The quick brown fox jumps over the lazy dog", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\'The quick brown fox jumps over the lazy dog\'", - toml::value("The quick brown fox jumps over the lazy dog", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", - toml::value("The quick brown fox jumps over the lazy dog", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "'''The quick brown fox \njumps over the lazy dog'''", - toml::value("The quick brown fox \njumps over the lazy dog", string_t::literal)); -} - - -BOOST_AUTO_TEST_CASE(test_basic_string) -{ - TOML11_TEST_PARSE_EQUAL(parse_string, + toml11_test_parse_success( "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", - string("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, + "GitHub Cofounder & CEO\nLikes tater tots and beer.", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "\"192.168.1.1\"", - string("192.168.1.1", string_t::basic)); + "192.168.1.1", comments(), + string_fmt(), ctx); -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) - TOML11_TEST_PARSE_EQUAL(parse_string, + toml11_test_parse_success( "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", - string("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic)); -#else - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"中国\"", - string("中国", string_t::basic)); -#endif + "\xE4\xB8\xAD\xE5\x9B\xBD", comments(), + string_fmt(), ctx); - TOML11_TEST_PARSE_EQUAL(parse_string, + toml11_test_parse_success( "\"You'll hate me after this - #\"", - string("You'll hate me after this - #", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\" And when \\\"'s are in the along with # \\\"\"", - string(" And when \"'s are in the along with # \"", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"Here are fifteen apostrophes: '''''''''''''''\"", - string("Here are fifteen apostrophes: '''''''''''''''", string_t::basic)); -} + "You'll hate me after this - #", comments(), + string_fmt(), ctx); + toml11_test_parse_success( + "\" And when \\\"'s are in the parse_ml_basic_string, along with # \\\"\"", + " And when \"'s are in the parse_ml_basic_string, along with # \"", comments(), + string_fmt(), ctx); -BOOST_AUTO_TEST_CASE(test_basic_string_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + // ------------------------------------------------------------------------- + // the same test cases, but with parse_string. + + toml11_test_parse_success( "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", - value("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "GitHub Cofounder & CEO\nLikes tater tots and beer.", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "\"192.168.1.1\"", - value("192.168.1.1", string_t::basic)); -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "192.168.1.1", comments(), + string_fmt(), ctx); + + toml11_test_parse_success( "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", - value("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic)); -#else - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\"中国\"", - value("中国", string_t::basic)); -#endif - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\xE4\xB8\xAD\xE5\x9B\xBD", comments(), + string_fmt(), ctx); + + toml11_test_parse_success( "\"You'll hate me after this - #\"", - value("You'll hate me after this - #", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\" And when \\\"'s are in the along with # \\\"\"", - value(" And when \"'s are in the along with # \"", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, - "\"Here are fifteen apostrophes: '''''''''''''''\"", - value("Here are fifteen apostrophes: '''''''''''''''", string_t::basic)); + "You'll hate me after this - #", comments(), + string_fmt(), ctx); + toml11_test_parse_success( + "\" And when \\\"'s are in the parse_ml_basic_string, along with # \\\"\"", + " And when \"'s are in the parse_ml_basic_string, along with # \"", comments(), + string_fmt(), ctx); } -BOOST_AUTO_TEST_CASE(test_ml_basic_string) +TEST_CASE("testing multiline basic string") { - TOML11_TEST_PARSE_EQUAL(parse_string, + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto string_fmt = [](bool nl) { + toml::string_format_info fmt; + fmt.fmt = toml::string_format::multiline_basic; + fmt.start_with_newline = nl; + return fmt; + }; + + toml11_test_parse_success( + // 0 1 + // 01234567890123456 "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", - string("The quick brown fox jumps over the lazy dog.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", - string("The quick brown fox jumps over the lazy dog.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", - string("Here are two quotation marks: \"\". Simple enough.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", - string("Here are three quotation marks: \"\"\".", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", - string("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", - string("\"This,\" she said, \"is just a pointless statement.\"", string_t::basic)); -} + "The quick brown fox jumps over the lazy dog.", comments(), + string_fmt(true), ctx + ); -BOOST_AUTO_TEST_CASE(test_ml_basic_string_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + toml11_test_parse_success( + // 0 1 + // 012345678901234567 + "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", + "The quick brown fox jumps over the lazy dog.", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( + "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", + "Here are two quotation marks: \"\". Simple enough.", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( + "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", + "Here are three quotation marks: \"\"\".", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( + "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", + "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( + "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", + "\"This,\" she said, \"is just a pointless statement.\"", comments(), + string_fmt(false), ctx + ); + + // ------------------------------------------------------------------------- + // the same test cases, but with parse_string. + + toml11_test_parse_success( + // 0 1 + // 01234567890123456 "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", - value("The quick brown fox jumps over the lazy dog.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "The quick brown fox jumps over the lazy dog.", comments(), + string_fmt(true), ctx + ); + + toml11_test_parse_success( + // 0 1 + // 012345678901234567 "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", - value("The quick brown fox jumps over the lazy dog.", string_t::basic)); + "The quick brown fox jumps over the lazy dog.", comments(), + string_fmt(false), ctx + ); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + toml11_test_parse_success( "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", - value("Here are two quotation marks: \"\". Simple enough.", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "Here are two quotation marks: \"\". Simple enough.", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", - value("Here are three quotation marks: \"\"\".", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "Here are three quotation marks: \"\"\".", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", - value("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", comments(), + string_fmt(false), ctx + ); + + toml11_test_parse_success( "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", - value("\"This,\" she said, \"is just a pointless statement.\"", string_t::basic)); + "\"This,\" she said, \"is just a pointless statement.\"", comments(), + string_fmt(false), ctx + ); } -BOOST_AUTO_TEST_CASE(test_literal_string) +TEST_CASE("testing literal_string") { - TOML11_TEST_PARSE_EQUAL(parse_string, + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto string_fmt = []() { + // inline basic_string does not use format settings + toml::string_format_info fmt; + fmt.fmt = toml::string_format::literal; + return fmt; + }; + + toml11_test_parse_success( "'C:\\Users\\nodejs\\templates'", - string("C:\\Users\\nodejs\\templates", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, + "C:\\Users\\nodejs\\templates", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'\\\\ServerX\\admin$\\system32\\'", - string("\\\\ServerX\\admin$\\system32\\", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, + "\\\\ServerX\\admin$\\system32\\", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'Tom \"Dubs\" Preston-Werner'", - string("Tom \"Dubs\" Preston-Werner", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, + "Tom \"Dubs\" Preston-Werner", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'<\\i\\c*\\s*>'", - string("<\\i\\c*\\s*>", string_t::literal)); -} + "<\\i\\c*\\s*>", comments(), + string_fmt(), ctx); -BOOST_AUTO_TEST_CASE(test_literal_string_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + // ------------------------------------------------------------------------- + // the same test cases, but with parse_string. + + toml11_test_parse_success( "'C:\\Users\\nodejs\\templates'", - value("C:\\Users\\nodejs\\templates", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "C:\\Users\\nodejs\\templates", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'\\\\ServerX\\admin$\\system32\\'", - value("\\\\ServerX\\admin$\\system32\\", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "\\\\ServerX\\admin$\\system32\\", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'Tom \"Dubs\" Preston-Werner'", - value("Tom \"Dubs\" Preston-Werner", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "Tom \"Dubs\" Preston-Werner", comments(), + string_fmt(), ctx); + toml11_test_parse_success( "'<\\i\\c*\\s*>'", - value("<\\i\\c*\\s*>", string_t::literal)); + "<\\i\\c*\\s*>", comments(), + string_fmt(), ctx); } -BOOST_AUTO_TEST_CASE(test_ml_literal_string) +TEST_CASE("testing ml_literal_string") { - TOML11_TEST_PARSE_EQUAL(parse_string, + toml::detail::context ctx(toml::spec::v(1,0,0)); + const auto string_fmt = [](bool nl) { + toml::string_format_info fmt; + fmt.fmt = toml::string_format::multiline_literal; + fmt.start_with_newline = nl; + return fmt; + }; + + toml11_test_parse_success( "'''I [dw]on't need \\d{2} apples'''", - string("I [dw]on't need \\d{2} apples", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, + "I [dw]on't need \\d{2} apples", comments(), + string_fmt(false), ctx); + toml11_test_parse_success( "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", - string("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "''''That's still pointless', she said.'''", - string("'That's still pointless', she said.", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", - string("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::literal)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "''''This,' she said, 'is just a pointless statement.''''", - string("'This,' she said, 'is just a pointless statement.'", string_t::literal)); -} + "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", comments(), + string_fmt(true), ctx); -BOOST_AUTO_TEST_CASE(test_ml_literal_string_value) -{ - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + toml11_test_parse_success( + "''''That's still pointless', she said.'''", + "'That's still pointless', she said.", comments(), + string_fmt(false), ctx); + + toml11_test_parse_success( + "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", + "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", comments(), + string_fmt(false), ctx); + + toml11_test_parse_success( + "''''This,' she said, 'is just a pointless statement.''''", + "'This,' she said, 'is just a pointless statement.'", comments(), + string_fmt(false), ctx); + + // ------------------------------------------------------------------------- + // the same test cases, but with parse_string. + + toml11_test_parse_success( "'''I [dw]on't need \\d{2} apples'''", - value("I [dw]on't need \\d{2} apples", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "I [dw]on't need \\d{2} apples", comments(), + string_fmt(false), ctx); + toml11_test_parse_success( "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", - value("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", comments(), + string_fmt(true), ctx); + + toml11_test_parse_success( "''''That's still pointless', she said.'''", - value("'That's still pointless', she said.", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "'That's still pointless', she said.", comments(), + string_fmt(false), ctx); + + toml11_test_parse_success( "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", - value("Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".", comments(), + string_fmt(false), ctx); + + toml11_test_parse_success( "''''This,' she said, 'is just a pointless statement.''''", - value("'This,' she said, 'is just a pointless statement.'", string_t::literal)); -} - -BOOST_AUTO_TEST_CASE(test_simple_excape_sequences) -{ - TOML11_TEST_PARSE_EQUAL(parse_string, - R"("\"\\\b\f\n\r\t")", - string("\"\\\b\f\n\r\t", string_t::basic)); -#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES - TOML11_TEST_PARSE_EQUAL(parse_string, - R"("\e")", - string("\x1b", string_t::basic)); -#endif -} - - -BOOST_AUTO_TEST_CASE(test_unicode_escape_sequence) -{ -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\\u03B1\\u03B2\\u03B3\"", - string("\xCE\xB1\xCE\xB2\xCE\xB3", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\\U0001D7AA\"", - string("\xF0\x9D\x9E\xAA", string_t::basic)); -#else - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\\u03B1\\u03B2\\u03B3\"", - string("αβγ", string_t::basic)); - TOML11_TEST_PARSE_EQUAL(parse_string, - "\"\\U0001D7AA\"", - string("𝞪", string_t::basic)); -#endif + "'This,' she said, 'is just a pointless statement.'", comments(), + string_fmt(false), ctx); } diff --git a/tests/test_parse_table.cpp b/tests/test_parse_table.cpp index 0fd54c7..112f32c 100644 --- a/tests/test_parse_table.cpp +++ b/tests/test_parse_table.cpp @@ -1,45 +1,165 @@ -#include -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "unit_test.hpp" -#include "test_parse_aux.hpp" +#include +#include "utility.hpp" +#include +#include -using namespace toml; -using namespace detail; +#include "doctest.h" -BOOST_AUTO_TEST_CASE(test_normal_table) +TEST_CASE("testing a table") { - std::string table( - "key1 = \"value\"\n" - "key2 = 42\n" - "key3 = 3.14\n" - ); - location loc("test", table); + auto spec = toml::spec::v(1,0,0); + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location(R"(a = "foo")"); - const auto result = toml::detail::parse_ml_table(loc); - BOOST_TEST(result.is_ok()); - const auto data = result.unwrap(); + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + REQUIRE_UNARY(res.is_ok()); - BOOST_TEST(toml::get(data.at("key1")) == "value"); - BOOST_TEST(toml::get(data.at("key2")) == 42); - BOOST_TEST(toml::get(data.at("key3")) == 3.14); -} - -BOOST_AUTO_TEST_CASE(test_nested_table) -{ - std::string table( - "a.b = \"value\"\n" - "a.c.d = 42\n" - ); - location loc("test", table); - - const auto result = toml::detail::parse_ml_table(loc); - BOOST_TEST(result.is_ok()); - const auto data = result.unwrap(); - - const auto a = toml::get(data.at("a")); - const auto c = toml::get(a.at("c")); - - BOOST_TEST(toml::get(a.at("b")) == "value"); - BOOST_TEST(toml::get(c.at("d")) == 42); + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.as_table().at("a").is_string()); + CHECK_EQ (table.as_table().at("a").as_string(), "foo"); + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::none); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 0); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + } + + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location(" a = \"foo\""); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + + REQUIRE_UNARY(res.is_ok()); + + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.as_table().at("a").is_string()); + CHECK_EQ (table.as_table().at("a").as_string(), "foo"); + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::space); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 2); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + } + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location("\ta = \"foo\""); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + REQUIRE_UNARY(res.is_ok()); + + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.as_table().at("a").is_string()); + CHECK_EQ (table.as_table().at("a").as_string(), "foo"); + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::tab); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 1); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + } + + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location(R"(a = "foo" +b = "bar" +c.c1 = "baz" +c.c2 = "qux" +)"); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + REQUIRE_UNARY(res.is_ok()); + + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + CHECK_UNARY(table.at("b").is_string()); + CHECK_EQ (table.at("b").as_string(), "bar"); + CHECK_UNARY(table.at("c").at("c1").is_string()); + CHECK_EQ (table.at("c").at("c1").as_string(), "baz"); + CHECK_UNARY(table.at("c").at("c2").is_string()); + CHECK_EQ (table.at("c").at("c2").as_string(), "qux"); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::none); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 0); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + } + + + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location(R"(a = "foo" +b = "bar" +c.c1 = "baz" +[next.table] +c.c2 = "qux" +)"); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + REQUIRE_UNARY(res.is_ok()); + + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + CHECK_UNARY(table.at("b").is_string()); + CHECK_EQ (table.at("b").as_string(), "bar"); + CHECK_UNARY(table.at("c").at("c1").is_string()); + CHECK_EQ (table.at("c").at("c1").as_string(), "baz"); + CHECK_UNARY( ! table.at("c").contains("c2")); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::none); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 0); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + } + + { + toml::detail::context ctx(spec); + auto loc = toml::detail::make_temporary_location(R"( + a = "foo" + b = "bar" + c.c1 = "baz" + [next.table] + c.c2 = "qux" +)"); + + toml::value table{toml::table()}; + const auto res = toml::detail::parse_table(loc, ctx, table); + REQUIRE_UNARY(res.is_ok()); + + REQUIRE_UNARY(table.is_table()); + + CHECK_UNARY(table.at("a").is_string()); + CHECK_EQ (table.at("a").as_string(), "foo"); + CHECK_UNARY(table.at("b").is_string()); + CHECK_EQ (table.at("b").as_string(), "bar"); + CHECK_UNARY(table.at("c").at("c1").is_string()); + CHECK_EQ (table.at("c").at("c1").as_string(), "baz"); + CHECK_UNARY( ! table.at("c").contains("c2")); + + CHECK_EQ(table.as_table_fmt().indent_type, toml::indent_char::space); + CHECK_EQ(table.as_table_fmt().name_indent, 0); + CHECK_EQ(table.as_table_fmt().body_indent, 4); + CHECK_EQ(table.as_table_fmt().closing_indent, 0); + + } } diff --git a/tests/test_parse_table_key.cpp b/tests/test_parse_table_key.cpp deleted file mode 100644 index a921c96..0000000 --- a/tests/test_parse_table_key.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include - -#include "unit_test.hpp" -#include "test_parse_aux.hpp" - -using namespace toml; -using namespace detail; - -BOOST_AUTO_TEST_CASE(test_table_bare_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[barekey]", std::vector(1, "barekey")); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[bare-key]", std::vector(1, "bare-key")); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[bare_key]", std::vector(1, "bare_key")); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[1234]", std::vector(1, "1234")); -} - -BOOST_AUTO_TEST_CASE(test_table_quoted_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"127.0.0.1\"]", std::vector(1, "127.0.0.1" )); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"character encoding\"]", std::vector(1, "character encoding")); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[\"ʎǝʞ\"]", std::vector(1, "ʎǝʞ" )); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "['key2']", std::vector(1, "key2" )); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "['quoted \"value\"']", std::vector(1, "quoted \"value\"" )); -} - -BOOST_AUTO_TEST_CASE(test_table_dotted_key) -{ - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "color"; - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[physical.color]", keys); - } - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "shape"; - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[physical.shape]", keys); - } - { - std::vector keys(4); - keys[0] = "x"; - keys[1] = "y"; - keys[2] = "z"; - keys[3] = "w"; - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x.y.z.w]", keys); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x . y . z . w]", keys); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x. y .z. w]", keys); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[x .y. z .w]", keys); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[ x. y .z . w ]", keys); - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[ x . y . z . w ]", keys); - } - { - std::vector keys(2); - keys[0] = "site"; - keys[1] = "google.com"; - TOML11_TEST_PARSE_EQUAL(parse_table_key, "[site.\"google.com\"]", keys); - } -} - -BOOST_AUTO_TEST_CASE(test_array_of_table_bare_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[barekey]]", std::vector(1, "barekey")); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[bare-key]]", std::vector(1, "bare-key")); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[bare_key]]", std::vector(1, "bare_key")); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[1234]]", std::vector(1, "1234")); -} - -BOOST_AUTO_TEST_CASE(test_array_of_table_quoted_key) -{ - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"127.0.0.1\"]]", std::vector(1, "127.0.0.1" )); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"character encoding\"]]", std::vector(1, "character encoding")); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[\"ʎǝʞ\"]]", std::vector(1, "ʎǝʞ" )); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[['key2']]", std::vector(1, "key2" )); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[['quoted \"value\"']]", std::vector(1, "quoted \"value\"" )); -} - -BOOST_AUTO_TEST_CASE(test_array_of_table_dotted_key) -{ - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "color"; - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[physical.color]]", keys); - } - { - std::vector keys(2); - keys[0] = "physical"; - keys[1] = "shape"; - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[physical.shape]]", keys); - } - { - std::vector keys(4); - keys[0] = "x"; - keys[1] = "y"; - keys[2] = "z"; - keys[3] = "w"; - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x.y.z.w]]", keys); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x . y . z . w]]", keys); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x. y .z. w]]", keys); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[x .y. z .w]]", keys); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[ x. y .z . w ]]", keys); - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[ x . y . z . w ]]", keys); - - } - { - std::vector keys(2); - keys[0] = "site"; - keys[1] = "google.com"; - TOML11_TEST_PARSE_EQUAL(parse_array_table_key, "[[site.\"google.com\"]]", keys); - } -} diff --git a/tests/test_parse_table_keys.cpp b/tests/test_parse_table_keys.cpp new file mode 100644 index 0000000..d94a3c0 --- /dev/null +++ b/tests/test_parse_table_keys.cpp @@ -0,0 +1,105 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +#include +#include "utility.hpp" +#include +#include + +#include "doctest.h" + +TEST_CASE("testing table keys") +{ + toml::detail::context ctx(toml::spec::v(1,0,0)); + { + auto loc = toml::detail::make_temporary_location("[one-key]"); + const auto res = toml::detail::parse_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 1); + REQUIRE_UNARY(val.at(0) == "one-key"); + } + + { + auto loc = toml::detail::make_temporary_location("[many.keys]"); + const auto res = toml::detail::parse_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 2); + REQUIRE_UNARY(val.at(0) == "many"); + REQUIRE_UNARY(val.at(1) == "keys"); + } + + { + auto loc = toml::detail::make_temporary_location("[ many . keys . with . spaces ]"); + const auto res = toml::detail::parse_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 4); + REQUIRE_UNARY(val.at(0) == "many"); + REQUIRE_UNARY(val.at(1) == "keys"); + REQUIRE_UNARY(val.at(2) == "with"); + REQUIRE_UNARY(val.at(3) == "spaces"); + } + + { + auto loc = toml::detail::make_temporary_location("[ \"one.long.key\" ]"); + const auto res = toml::detail::parse_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 1); + REQUIRE_UNARY(val.at(0) == "one.long.key"); + } +} + +TEST_CASE("testing array table keys") +{ + toml::detail::context ctx(toml::spec::v(1,0,0)); + { + auto loc = toml::detail::make_temporary_location("[[one-key]]"); + const auto res = toml::detail::parse_array_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 1); + REQUIRE_UNARY(val.at(0) == "one-key"); + } + + { + auto loc = toml::detail::make_temporary_location("[[many.keys]]"); + const auto res = toml::detail::parse_array_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 2); + REQUIRE_UNARY(val.at(0) == "many"); + REQUIRE_UNARY(val.at(1) == "keys"); + } + + { + auto loc = toml::detail::make_temporary_location("[[ many . keys . with . spaces ]]"); + const auto res = toml::detail::parse_array_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 4); + REQUIRE_UNARY(val.at(0) == "many"); + REQUIRE_UNARY(val.at(1) == "keys"); + REQUIRE_UNARY(val.at(2) == "with"); + REQUIRE_UNARY(val.at(3) == "spaces"); + } + + { + auto loc = toml::detail::make_temporary_location("[[ \"one.long.key\" ]]"); + const auto res = toml::detail::parse_array_table_key(loc, ctx); + REQUIRE_UNARY(res.is_ok()); + + const auto val = std::get<0>(res.unwrap()); + REQUIRE_UNARY(val.size() == 1); + REQUIRE_UNARY(val.at(0) == "one.long.key"); + } +} + diff --git a/tests/test_parse_unicode.cpp b/tests/test_parse_unicode.cpp deleted file mode 100644 index 8bc4253..0000000 --- a/tests/test_parse_unicode.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include - -BOOST_AUTO_TEST_CASE(test_hard_example_unicode) -{ - 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")) == - std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x27\xE2\x84\x93\xE2\x84\x93\x20\xCE\xBB\xC3\xA1\xC6\xAD\xC3\xA8\x20\xE2\x82\xA5\xC3\xA8\x20\xC3\xA1\xC6\x92\xC6\xAD\xC3\xA8\xC5\x99\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC6\xA8\x20\x2D\x20\x23")); - - const auto hard = toml::get(the.at("hard")); - const std::vector expected_the_hard_test_array{"] ", " # "}; - BOOST_CHECK(toml::get>(hard.at("test_array")) == - expected_the_hard_test_array); - const std::vector expected_the_hard_test_array2{ - std::string("\x54\xC3\xA8\xC6\xA8\xC6\xAD\x20\x23\x31\x31\x20\x5D\xC6\xA5\xC5\x99\xC3\xB4\xC6\xB2\xC3\xA8\xCE\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD"), - std::string("\xC3\x89\xD0\xB6\xC6\xA5\xC3\xA8\xC5\x99\xC3\xAF\xE2\x82\xA5\xC3\xA8\xC3\xB1\xC6\xAD\x20\x23\x39\x20\xCF\x89\xC3\xA1\xC6\xA8\x20\xC3\xA1\x20\xC6\xA8\xC3\xBA\xC3\xA7\xC3\xA7\xC3\xA8\xC6\xA8\xC6\xA8") - }; - BOOST_CHECK(toml::get>(hard.at("test_array2")) == - expected_the_hard_test_array2); - BOOST_TEST(toml::get(hard.at("another_test_string")) == - std::string("\xC2\xA7\xC3\xA1\xE2\x82\xA5\xC3\xA8\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xCE\xB2\xC3\xBA\xC6\xAD\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\xC3\xA1\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x20\x23")); - BOOST_TEST(toml::get(hard.at("harder_test_string")) == - std::string("\x20\xC3\x82\xC3\xB1\xCE\xB4\x20\xCF\x89\xCE\xBB\xC3\xA8\xC3\xB1\x20\x22\x27\xC6\xA8\x20\xC3\xA1\xC5\x99\xC3\xA8\x20\xC3\xAF\xC3\xB1\x20\xC6\xAD\xCE\xBB\xC3\xA8\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xC3\xA1\xE2\x84\x93\xC3\xB4\xC3\xB1\xCF\xB1\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\x23\x20\x22")); -// - const auto bit = toml::get(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23"))); - BOOST_TEST(toml::get(bit.at(std::string("\xCF\x89\xCE\xBB\xC3\xA1\xC6\xAD\x3F"))) == - std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x20\xCE\xB4\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xC6\x99\x20\xC6\xA8\xC3\xB4\xE2\x82\xA5\xC3\xA8\x20\xC3\xBA\xC6\xA8\xC3\xA8\xC5\x99\x20\xCF\x89\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xCE\xB4\xC3\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD\x3F")); - const std::vector expected_multi_line_array{"]"}; - BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == - expected_multi_line_array); -} diff --git a/tests/test_result.cpp b/tests/test_result.cpp index ad5084c..7737971 100644 --- a/tests/test_result.cpp +++ b/tests/test_result.cpp @@ -1,440 +1,148 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include -#include - -BOOST_AUTO_TEST_CASE(test_construct) +TEST_CASE("testing constructor") { { auto s = toml::ok(42); toml::result result(s); - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { const auto s = toml::ok(42); toml::result result(s); - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { toml::result result(toml::ok(42)); - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { - auto f = toml::err("foobar"); + auto f = toml::err("foobar"); toml::result result(f); - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "foobar"); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "foobar"); } { - const auto f = toml::err("foobar"); + const auto f = toml::err("foobar"); toml::result result(f); - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "foobar"); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "foobar"); } { - toml::result result(toml::err("foobar")); - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "foobar"); + toml::result result(toml::err("foobar")); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "foobar"); } } -BOOST_AUTO_TEST_CASE(test_assignment) +TEST_CASE("testing assignment op") { { - toml::result result(toml::err("foobar")); + toml::result result(toml::err("foobar")); result = toml::ok(42); - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { - toml::result result(toml::err("foobar")); + toml::result result(toml::err("foobar")); auto s = toml::ok(42); result = s; - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { - toml::result result(toml::err("foobar")); + toml::result result(toml::err("foobar")); const auto s = toml::ok(42); result = s; - BOOST_TEST(!!result); - BOOST_TEST(result.is_ok()); - BOOST_TEST(!result.is_err()); - BOOST_TEST(result.unwrap() == 42); + CHECK(!!result); + CHECK(result.is_ok()); + CHECK(!result.is_err()); + CHECK(result.unwrap() == 42); } { - toml::result result(toml::err("foobar")); - result = toml::err("hoge"); - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "hoge"); + toml::result result(toml::err("foobar")); + result = toml::err("hoge"); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "hoge"); } { - toml::result result(toml::err("foobar")); - auto f = toml::err("hoge"); + toml::result result(toml::err("foobar")); + auto f = toml::err("hoge"); result = f; - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "hoge"); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "hoge"); } { - toml::result result(toml::err("foobar")); - const auto f = toml::err("hoge"); + toml::result result(toml::err("foobar")); + const auto f = toml::err("hoge"); result = f; - BOOST_TEST(!result); - BOOST_TEST(!result.is_ok()); - BOOST_TEST(result.is_err()); - BOOST_TEST(result.unwrap_err() == "hoge"); + CHECK(!result); + CHECK(!result.is_ok()); + CHECK(result.is_err()); + CHECK(result.unwrap_err() == "hoge"); } } -BOOST_AUTO_TEST_CASE(test_map) +TEST_CASE("testing result") { { - const toml::result result(toml::ok(42)); - const auto mapped = result.map( - [](const int i) -> int { - return i * 2; - }); + int a = 42; - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42 * 2); + toml::result, std::string> result(toml::ok(std::ref(a))); + CHECK_UNARY(result); + CHECK_UNARY(result.is_ok()); + CHECK_UNARY_FALSE(result.is_err()); + + CHECK_EQ(result.unwrap(), 42); + CHECK_EQ(a, 42); + + result.unwrap() = 6 * 9; + + CHECK_EQ(result.unwrap(), 6*9); + CHECK_EQ(a, 6*9); } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).map( - [](std::unique_ptr i) -> int { - return *i; - }); - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42); - } { - const toml::result result(toml::err("hoge")); - const auto mapped = result.map( - [](const int i) -> int { - return i * 2; - }); + std::string b = "foo"; - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hoge"); - } - { - toml::result, std::string> - result(toml::err("hoge")); - const auto mapped = std::move(result).map( - [](std::unique_ptr i) -> int { - return *i; - }); + toml::result> result(toml::err(std::ref(b))); + CHECK_UNARY_FALSE(result); + CHECK_UNARY_FALSE(result.is_ok()); + CHECK_UNARY(result.is_err()); - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hoge"); - } -} - -BOOST_AUTO_TEST_CASE(test_map_err) -{ - { - const toml::result result(toml::ok(42)); - const auto mapped = result.map_err( - [](const std::string s) -> std::string { - return s + s; - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42); - } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).map_err( - [](const std::string s) -> std::string { - return s + s; - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(*(mapped.unwrap()) == 42); - } - { - const toml::result result(toml::err("hoge")); - const auto mapped = result.map_err( - [](const std::string s) -> std::string { - return s + s; - }); - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hogehoge"); - } - { - toml::result> - result(toml::err(std::unique_ptr(new std::string("hoge")))); - const auto mapped = std::move(result).map_err( - [](std::unique_ptr p) -> std::string { - return *p; - }); - - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hoge"); - } -} - -BOOST_AUTO_TEST_CASE(test_map_or_else) -{ - { - const toml::result result(toml::ok(42)); - const auto mapped = result.map_or_else( - [](const int i) -> int { - return i * 2; - }, 54); - - BOOST_TEST(mapped == 42 * 2); - } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).map_or_else( - [](std::unique_ptr i) -> int { - return *i; - }, 54); - - BOOST_TEST(mapped == 42); - } - { - const toml::result result(toml::err("hoge")); - const auto mapped = result.map_or_else( - [](const int i) -> int { - return i * 2; - }, 54); - - BOOST_TEST(mapped == 54); - } - { - toml::result, std::string> - result(toml::err("hoge")); - const auto mapped = std::move(result).map_or_else( - [](std::unique_ptr i) -> int { - return *i; - }, 54); - - BOOST_TEST(mapped == 54); - } -} - -BOOST_AUTO_TEST_CASE(test_map_err_or_else) -{ - { - const toml::result result(toml::ok(42)); - const auto mapped = result.map_err_or_else( - [](const std::string i) -> std::string { - return i + i; - }, "foobar"); - - BOOST_TEST(mapped == "foobar"); - } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).map_err_or_else( - [](const std::string i) -> std::string { - return i + i; - }, "foobar"); - - BOOST_TEST(mapped == "foobar"); - } - { - const toml::result result(toml::err("hoge")); - const auto mapped = result.map_err_or_else( - [](const std::string i) -> std::string { - return i + i; - }, "foobar"); - - BOOST_TEST(mapped == "hogehoge"); - } - { - toml::result, std::string> - result(toml::err("hoge")); - const auto mapped = result.map_err_or_else( - [](const std::string i) -> std::string { - return i + i; - }, "foobar"); - - BOOST_TEST(mapped == "hogehoge"); - } -} - - -BOOST_AUTO_TEST_CASE(test_and_then) -{ - { - const toml::result result(toml::ok(42)); - const auto mapped = result.and_then( - [](const int i) -> toml::result { - return toml::ok(i * 2); - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42 * 2); - } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).and_then( - [](std::unique_ptr i) -> toml::result { - return toml::ok(*i); - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42); - } - { - const toml::result result(toml::err("hoge")); - const auto mapped = result.and_then( - [](const int i) -> toml::result { - return toml::ok(i * 2); - }); - - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hoge"); - } - { - toml::result, std::string> - result(toml::err("hoge")); - const auto mapped = std::move(result).and_then( - [](std::unique_ptr i) -> toml::result { - return toml::ok(*i); - }); - - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hoge"); - } -} - -BOOST_AUTO_TEST_CASE(test_or_else) -{ - { - const toml::result result(toml::ok(42)); - const auto mapped = result.or_else( - [](const std::string& s) -> toml::result { - return toml::err(s + s); - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(mapped.unwrap() == 42); - } - { - toml::result, std::string> - result(toml::ok(std::unique_ptr(new int(42)))); - const auto mapped = std::move(result).or_else( - [](const std::string& s) -> toml::result, std::string> { - return toml::err(s + s); - }); - - BOOST_TEST(!!mapped); - BOOST_TEST(mapped.is_ok()); - BOOST_TEST(!mapped.is_err()); - BOOST_TEST(*mapped.unwrap() == 42); - } - { - const toml::result result(toml::err("hoge")); - const auto mapped = result.or_else( - [](const std::string& s) -> toml::result { - return toml::err(s + s); - }); - - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hogehoge"); - } - { - toml::result, std::string> - result(toml::err("hoge")); - const auto mapped = std::move(result).or_else( - [](const std::string& s) -> toml::result, std::string> { - return toml::err(s + s); - }); - - BOOST_TEST(!mapped); - BOOST_TEST(!mapped.is_ok()); - BOOST_TEST(mapped.is_err()); - BOOST_TEST(mapped.unwrap_err() == "hogehoge"); - } -} - -BOOST_AUTO_TEST_CASE(test_and_or_other) -{ - { - const toml::result r1(toml::ok(42)); - const toml::result r2(toml::err("foo")); - - BOOST_TEST(r1 == r1.or_other(r2)); - BOOST_TEST(r2 == r1.and_other(r2)); - BOOST_TEST(42 == r1.or_other(r2).unwrap()); - BOOST_TEST("foo" == r1.and_other(r2).unwrap_err()); - } - { - auto r1_gen = []() -> toml::result { - return toml::ok(42); - }; - auto r2_gen = []() -> toml::result { - return toml::err("foo"); - }; - const auto r3 = r1_gen(); - const auto r4 = r2_gen(); - - BOOST_TEST(r3 == r1_gen().or_other (r2_gen())); - BOOST_TEST(r4 == r1_gen().and_other(r2_gen())); - BOOST_TEST(42 == r1_gen().or_other (r2_gen()).unwrap()); - BOOST_TEST("foo" == r1_gen().and_other(r2_gen()).unwrap_err()); + CHECK_EQ(result.unwrap_err(), "foo"); + CHECK_EQ(b, "foo"); + + result.unwrap_err() = "foobar"; + + CHECK_EQ(result.unwrap_err(), "foobar"); + CHECK_EQ(b, "foobar"); } } diff --git a/tests/test_scanner.cpp b/tests/test_scanner.cpp new file mode 100644 index 0000000..c0ef738 --- /dev/null +++ b/tests/test_scanner.cpp @@ -0,0 +1,170 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing scanner: character") +{ + auto loc = toml::detail::make_temporary_location("\t \tA"); + + toml::detail::character tab('\t'); + toml::detail::character space(' '); + + CHECK_UNARY( tab .scan(loc).is_ok()); // loc += 1 + CHECK_UNARY(!tab .scan(loc).is_ok()); + CHECK_UNARY( space.scan(loc).is_ok()); + CHECK_UNARY( tab .scan(loc).is_ok()); + CHECK_UNARY(!tab .scan(loc).is_ok()); + CHECK_UNARY(!space.scan(loc).is_ok()); +} + +TEST_CASE("testing scanner: character_either") +{ + auto loc = toml::detail::make_temporary_location("\t \t01\0"); + + toml::detail::character_either wschar{'\t', ' '}; + toml::detail::character_either digit01("01"); + + CHECK_UNARY( wschar .scan(loc).is_ok()); + CHECK_UNARY( wschar .scan(loc).is_ok()); + CHECK_UNARY( wschar .scan(loc).is_ok()); + CHECK_UNARY(!wschar .scan(loc).is_ok()); + CHECK_UNARY( digit01.scan(loc).is_ok()); + CHECK_UNARY( digit01.scan(loc).is_ok()); + CHECK_UNARY(!digit01.scan(loc).is_ok()); + CHECK_UNARY(!wschar .scan(loc).is_ok()); +} + +TEST_CASE("testing scanner: character_in_range") +{ + auto loc = toml::detail::make_temporary_location("abcdz12349"); + + toml::detail::character_in_range alpha('a', 'z'); + toml::detail::character_in_range digit('0', '9'); + + CHECK_UNARY( alpha.scan(loc).is_ok()); + CHECK_UNARY( alpha.scan(loc).is_ok()); + CHECK_UNARY( alpha.scan(loc).is_ok()); + CHECK_UNARY( alpha.scan(loc).is_ok()); + CHECK_UNARY( alpha.scan(loc).is_ok()); + CHECK_UNARY(!alpha.scan(loc).is_ok()); + CHECK_UNARY( digit.scan(loc).is_ok()); + CHECK_UNARY( digit.scan(loc).is_ok()); + CHECK_UNARY( digit.scan(loc).is_ok()); + CHECK_UNARY( digit.scan(loc).is_ok()); + CHECK_UNARY( digit.scan(loc).is_ok()); + CHECK_UNARY(!digit.scan(loc).is_ok()); +} + +TEST_CASE("testing scanner: literal") +{ + auto loc = toml::detail::make_temporary_location("abcdz12349"); + + toml::detail::literal abcd("abcd"); + toml::detail::literal z123("z123"); + + CHECK_UNARY( abcd.scan(loc).is_ok()); + CHECK_UNARY(!abcd.scan(loc).is_ok()); + CHECK_UNARY( z123.scan(loc).is_ok()); + CHECK_UNARY(!z123.scan(loc).is_ok()); + CHECK_UNARY(!abcd.scan(loc).is_ok()); +} + +TEST_CASE("testing scanner: sequence") +{ + auto loc = toml::detail::make_temporary_location("abcdz12349"); + + toml::detail::literal abcd("abcd"); + toml::detail::literal z123("z123"); + + toml::detail::sequence seq(abcd, z123); + + CHECK_UNARY( seq.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('4')); + + auto loc2 = toml::detail::make_temporary_location("abcde12349"); + + CHECK_UNARY(!seq.scan(loc2).is_ok()); +} + +TEST_CASE("testing scanner: either") +{ + auto loc = toml::detail::make_temporary_location("abcdz123"); + + toml::detail::literal abcd("abcd"); + toml::detail::literal z123("z123"); + + toml::detail::either e(abcd, z123); + + CHECK_UNARY( e.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('z')); + + CHECK_UNARY( e.scan(loc).is_ok()); + CHECK_UNARY( loc.eof() ); +} + +TEST_CASE("testing scanner: repeat_exact") +{ + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + toml::detail::repeat_exact r(2, toml::detail::literal("foo")); + + CHECK_UNARY( r.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('b')); + } + + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + + toml::detail::repeat_exact r(3, toml::detail::literal("foo")); + + CHECK_UNARY( ! r.scan(loc).is_ok()); + } +} + +TEST_CASE("testing scanner: repeat_at_least") +{ + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + toml::detail::repeat_at_least r(1, toml::detail::literal("foo")); + + CHECK_UNARY( r.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('b')); + } + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + toml::detail::repeat_at_least r(2, toml::detail::literal("foo")); + + CHECK_UNARY( r.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('b')); + } + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + + toml::detail::repeat_at_least r(3, toml::detail::literal("foo")); + + CHECK_UNARY( ! r.scan(loc).is_ok()); + } +} + +TEST_CASE("testing scanner: maybe") +{ + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + toml::detail::maybe r(toml::detail::literal("foo")); + + CHECK_UNARY( r.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('f')); + CHECK_EQ( loc.get_location(), 3); + } + { + auto loc = toml::detail::make_temporary_location("foofoobar"); + toml::detail::maybe r(toml::detail::literal("bar")); + + CHECK_UNARY( r.scan(loc).is_ok()); + CHECK_EQ( loc.current(), toml::detail::location::char_type('f')); + CHECK_EQ( loc.get_location(), 0); + } +} diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp deleted file mode 100644 index 40cb484..0000000 --- a/tests/test_serialize_file.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include - -#include "unit_test.hpp" - -#include -#include -#include -#include -#include - -#include - -template class Table, - template class Array> -bool has_comment_inside(const toml::basic_value& v) -{ - if(!v.comments().empty()) - { - return false; - } - // v itself does not have a comment. - if(v.is_array()) - { - for(const auto& x : v.as_array()) - { - if(has_comment_inside(x)) - { - return false; - } - } - } - if(v.is_table()) - { - for(const auto& x : v.as_table()) - { - if(has_comment_inside(x.second)) - { - return false; - } - } - } - return true; -} - -BOOST_AUTO_TEST_CASE(test_example) -{ - const auto data = toml::parse(testinput("example.toml")); - { - std::ofstream ofs("tmp1.toml"); - ofs << std::setw(80) << data; - } - - auto serialized = toml::parse("tmp1.toml"); - { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_example_map_dq) -{ - const auto data = toml::parse( - testinput("example.toml")); - { - std::ofstream ofs("tmp1_map_dq.toml"); - ofs << std::setw(80) << data; - } - - auto serialized = toml::parse( - "tmp1_map_dq.toml"); - { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_example_with_comment) -{ - const auto data = toml::parse(testinput("example.toml")); - { - std::ofstream ofs("tmp1_com.toml"); - ofs << std::setw(80) << data; - } - - auto serialized = toml::parse("tmp1_com.toml"); - { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - BOOST_TEST(data == serialized); - { - std::ofstream ofs("tmp1_com1.toml"); - ofs << std::setw(80) << serialized; - } -} - -BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) -{ - { - const auto data = toml::parse(testinput("example.toml")); - { - std::ofstream ofs("tmp1_com_nocomment.toml"); - ofs << std::setw(80) << toml::nocomment << data; - } - const auto serialized = toml::parse("tmp1_com_nocomment.toml"); - // check no comment exist - BOOST_TEST(!has_comment_inside(serialized)); - } - { - const auto data_nocomment = toml::parse(testinput("example.toml")); - auto serialized = toml::parse("tmp1_com_nocomment.toml"); - { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - // check collectly serialized - BOOST_TEST(data_nocomment == serialized); - } -} - -BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) -{ - const auto data = toml::parse( - testinput("example.toml")); - { - std::ofstream ofs("tmp1_com_map_dq.toml"); - ofs << std::setw(80) << data; - } - - auto serialized = toml::parse( - "tmp1_com_map_dq.toml"); - { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - BOOST_TEST(data == serialized); - { - std::ofstream ofs("tmp1_com1_map_dq.toml"); - ofs << std::setw(80) << serialized; - } -} - -BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) -{ - { - const auto data = toml::parse(testinput("example.toml")); - { - std::ofstream ofs("tmp1_com_map_dq_nocomment.toml"); - ofs << std::setw(80) << toml::nocomment << data; - } - const auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); - BOOST_TEST(!has_comment_inside(serialized)); - } - { - 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"); - auto& bio = toml::find(owner, "bio"); - const auto CR = std::find(bio.begin(), bio.end(), '\r'); - if(CR != bio.end()) - { - bio.erase(CR); - } - } - BOOST_TEST(data_nocomment == serialized); - } -} - -BOOST_AUTO_TEST_CASE(test_fruit) -{ - const auto data = toml::parse(testinput("fruit.toml")); - { - std::ofstream ofs("tmp2.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp2.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_fruit_map_dq) -{ - const auto data = toml::parse( - testinput("fruit.toml")); - { - std::ofstream ofs("tmp2.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse( - "tmp2.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_fruit_with_comments) -{ - const auto data = toml::parse(testinput("fruit.toml")); - { - std::ofstream ofs("tmp2_com.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp2_com.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq) -{ - const auto data = toml::parse( - testinput("fruit.toml")); - { - std::ofstream ofs("tmp2_com.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp2_com.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_hard_example) -{ - const auto data = toml::parse(testinput("hard_example.toml")); - { - std::ofstream ofs("tmp3.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse("tmp3.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_hard_example_map_dq) -{ - const auto data = toml::parse( - testinput("hard_example.toml")); - { - std::ofstream ofs("tmp3.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse( - "tmp3.toml"); - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_hard_example_with_comment) -{ - const auto data = toml::parse( - testinput("hard_example.toml")); - { - std::ofstream ofs("tmp3_com.toml"); - ofs << std::setw(80) << data; - } - const auto serialized = toml::parse( - "tmp3_com.toml"); - { - std::ofstream ofs("tmp3_com1.toml"); - ofs << std::setw(80) << serialized; - } - BOOST_TEST(data == serialized); -} - -BOOST_AUTO_TEST_CASE(test_format_key) -{ - { - const toml::key key("normal_bare-key"); - BOOST_TEST("normal_bare-key" == toml::format_key(key)); - } - { - const toml::key key("key.include.dots"); - BOOST_TEST("\"key.include.dots\"" == toml::format_key(key)); - } - { - const toml::key key("key-include-unicode-\xE3\x81\x82"); - BOOST_TEST("\"key-include-unicode-\xE3\x81\x82\"" == toml::format_key(key)); - } - { - const toml::key key("special-chars-\\-\"-\b-\f-\r-\n-\t"); - BOOST_TEST("\"special-chars-\\\\-\\\"-\\b-\\f-\\r-\\n-\\t\"" == toml::format_key(key)); - } -} - -// In toml11, an implicitly-defined value does not have any comments. -// So, in the following file, -// ```toml -// # comment -// [[array-of-tables]] -// foo = "bar" -// ``` -// The array named "array-of-tables" does not have the comment, but the first -// element of the array has. That means that, the above file is equivalent to -// the following. -// ```toml -// array-of-tables = [ -// # comment -// {foo = "bar"}, -// ] -// ``` -// If the array itself has a comment (value_has_comment_ == true), we should try -// to make it inline. -// ```toml -// # comment about array -// array-of-tables = [ -// # comment about table element -// {foo = "bar"} -// ] -// ``` -// If it is formatted as a multiline table, the two comments becomes -// indistinguishable. -// ```toml -// # comment about array -// # comment about table element -// [[array-of-tables]] -// foo = "bar" -// ``` -// So we need to try to make it inline, and it force-inlines regardless -// of the line width limit. -// It may fail if the element of a table has comment. In that case, -// the array-of-tables will be formatted as a multiline table. -BOOST_AUTO_TEST_CASE(test_distinguish_comment) -{ - const std::string str = R"(# comment about array itself -array_of_table = [ - # comment about the first element (table) - {key = "value"}, -])"; - std::istringstream iss(str); - const auto data = toml::parse(iss); - const auto serialized = toml::format(data, /*width = */ 0); - - std::istringstream reparse(serialized); - const auto parsed = toml::parse(reparse); - - BOOST_TEST(parsed.at("array_of_table").comments().size() == 1u); - BOOST_TEST(parsed.at("array_of_table").comments().front() == " comment about array itself"); - BOOST_TEST(parsed.at("array_of_table").at(0).comments().size() == 1u); - BOOST_TEST(parsed.at("array_of_table").at(0).comments().front() == " comment about the first element (table)"); -} - - -BOOST_AUTO_TEST_CASE(test_serialize_under_locale) -{ - // avoid null init (setlocale returns null when it failed) - std::string setloc(std::setlocale(LC_ALL, nullptr)); - - // fr_FR is a one of locales that uses `,` as a decimal separator. - if(const char* try_hyphen = std::setlocale(LC_ALL, "fr_FR.UTF-8")) - { - setloc = std::string(try_hyphen); - } - else if(const char* try_nohyphen = std::setlocale(LC_ALL, "fr_FR.utf8")) - { - setloc = std::string(try_nohyphen); - } - // In some envs, fr_FR locale has not been installed. Tests must work even in such a case. -// else -// { -// BOOST_TEST(false); -// } - BOOST_TEST_MESSAGE("current locale at the beginning of the test = " << setloc); - - const std::string str = R"( -pi = 3.14159 -large_int = 1234567890 -)"; - std::istringstream iss(str); - const auto ref = toml::parse(iss); - const auto serialized_str = toml::format(ref, /*width = */ 80); - - BOOST_TEST_MESSAGE("serialized = " << serialized_str); - - std::istringstream serialized_iss(serialized_str); - const auto serialized_ref = toml::parse(serialized_iss); - - BOOST_TEST(serialized_ref.at("pi").as_floating() == ref.at("pi").as_floating()); - BOOST_TEST(serialized_ref.at("large_int").as_integer() == ref.at("large_int").as_integer()); - - const std::string endloc(std::setlocale(LC_ALL, nullptr)); - BOOST_TEST_MESSAGE("current locale at the end of the test = " << endloc); - // check if serializer change global locale - BOOST_TEST(setloc == endloc); -} diff --git a/tests/test_spec.cpp b/tests/test_spec.cpp new file mode 100644 index 0000000..00debdf --- /dev/null +++ b/tests/test_spec.cpp @@ -0,0 +1,58 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +TEST_CASE("testing constructor of semantic_version") +{ + constexpr auto v123 = toml::semantic_version(1, 2, 3); + + CHECK(v123.major == 1); + CHECK(v123.minor == 2); + CHECK(v123.patch == 3); +} + +TEST_CASE("testing the ordering of semantic_version") +{ + constexpr auto v100 = toml::semantic_version(1, 0, 0); + constexpr auto v101 = toml::semantic_version(1, 0, 1); + constexpr auto v110 = toml::semantic_version(1, 1, 0); + constexpr auto v112 = toml::semantic_version(1, 1, 2); + constexpr auto v121 = toml::semantic_version(1, 2, 1); + + CHECK(v100 == v100); + CHECK(v100 >= v100); + CHECK(v100 <= v100); + CHECK_FALSE(v100 != v100); + CHECK_FALSE(v100 > v100); + CHECK_FALSE(v100 < v100); + + CHECK(v100 != v101); + CHECK(v100 <= v101); + CHECK(v100 < v101); + CHECK_FALSE(v100 == v101); + CHECK_FALSE(v100 >= v101); + CHECK_FALSE(v100 > v101); + + CHECK(v101 != v110); + CHECK(v101 < v110); + CHECK(v101 <= v110); + CHECK_FALSE(v101 == v110); + CHECK_FALSE(v101 > v110); + CHECK_FALSE(v101 >= v110); + + CHECK(v110 != v101); + CHECK(v110 > v101); + CHECK(v110 >= v101); + CHECK_FALSE(v110 == v101); + CHECK_FALSE(v110 < v101); + CHECK_FALSE(v110 <= v101); + + CHECK(v112 != v121); + CHECK(v112 < v121); + CHECK(v112 <= v121); + + CHECK(v121 != v112); + CHECK(v121 > v112); + CHECK(v121 >= v112); +} diff --git a/tests/test_storage.cpp b/tests/test_storage.cpp new file mode 100644 index 0000000..3305e1d --- /dev/null +++ b/tests/test_storage.cpp @@ -0,0 +1,78 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +TEST_CASE("testing storage construct") +{ + toml::detail::storage x(42); + + REQUIRE_UNARY(x.is_ok()); + + CHECK_EQ(x.get(), 42); + CHECK_NE(x.get(), 6*9); + + x.get() = 6 * 9; + + CHECK_EQ(x.get(), 6*9); + CHECK_NE(x.get(), 42); +} + +TEST_CASE("testing storage copy") +{ + toml::detail::storage x(42); + toml::detail::storage y(x); + + REQUIRE_UNARY(x.is_ok()); + REQUIRE_UNARY(y.is_ok()); + + CHECK_EQ(x.get(), 42); + CHECK_NE(x.get(), 6*9); + + CHECK_EQ(y.get(), 42); + CHECK_NE(y.get(), 6*9); + + x.get() = 6 * 9; + + CHECK_EQ(x.get(), 6*9); + CHECK_NE(x.get(), 42); + + CHECK_EQ(y.get(), 42); + CHECK_NE(y.get(), 6*9); + + x = y; + + CHECK_EQ(x.get(), 42); + CHECK_NE(x.get(), 6*9); + + CHECK_EQ(y.get(), 42); + CHECK_NE(y.get(), 6*9); +} + +TEST_CASE("testing storage move") +{ + toml::detail::storage x(42); + toml::detail::storage y(x); + + REQUIRE_UNARY(x.is_ok()); + REQUIRE_UNARY(y.is_ok()); + + CHECK_EQ(x.get(), 42); + CHECK_NE(x.get(), 6*9); + + CHECK_EQ(y.get(), 42); + CHECK_NE(y.get(), 6*9); + + x.get() = 6 * 9; + + CHECK_EQ(x.get(), 6*9); + CHECK_NE(x.get(), 42); + + CHECK_EQ(y.get(), 42); + CHECK_NE(y.get(), 6*9); + + x = std::move(y); + + CHECK_EQ(x.get(), 42); + CHECK_NE(x.get(), 6*9); +} diff --git a/tests/test_string.cpp b/tests/test_string.cpp deleted file mode 100644 index e3f093a..0000000 --- a/tests/test_string.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#include "unit_test.hpp" - -BOOST_AUTO_TEST_CASE(test_basic_string) -{ - { - const toml::string str("basic string"); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "\"basic string\""); - } - { - const std::string s1 ("basic string"); - const toml::string str(s1); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "\"basic string\""); - } - { - const toml::string str("basic string", toml::string_t::basic); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "\"basic string\""); - } - { - const std::string s1 ("basic string"); - const toml::string str(s1, toml::string_t::basic); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "\"basic string\""); - } -} - -BOOST_AUTO_TEST_CASE(test_basic_ml_string) -{ - { - const toml::string str("basic\nstring"); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; - BOOST_TEST(oss1.str() == oss2.str()); - } - { - const std::string s1 ("basic\nstring"); - const toml::string str(s1); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; - BOOST_TEST(oss1.str() == oss2.str()); - } - { - const toml::string str("basic\nstring", toml::string_t::basic); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; - BOOST_TEST(oss1.str() == oss2.str()); - - } - { - const std::string s1 ("basic\nstring"); - const toml::string str(s1, toml::string_t::basic); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; - BOOST_TEST(oss1.str() == oss2.str()); - } -} - - -BOOST_AUTO_TEST_CASE(test_literal_string) -{ - { - const toml::string str("literal string", toml::string_t::literal); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "'literal string'"); - } - { - const std::string s1 ("literal string"); - const toml::string str(s1, toml::string_t::literal); - std::ostringstream oss; - oss << str; - BOOST_TEST(oss.str() == "'literal string'"); - } -} - -BOOST_AUTO_TEST_CASE(test_literal_ml_string) -{ - { - const toml::string str("literal\nstring", toml::string_t::literal); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "'''\nliteral\nstring'''"; - BOOST_TEST(oss1.str() == oss2.str()); - - } - { - const std::string s1 ("literal\nstring"); - const toml::string str(s1, toml::string_t::literal); - std::ostringstream oss1; - oss1 << str; - std::ostringstream oss2; - oss2 << "'''\nliteral\nstring'''"; - BOOST_TEST(oss1.str() == oss2.str()); - } -} - -BOOST_AUTO_TEST_CASE(test_string_add_assign) -{ - // string literal - { - toml::string str("foo"); - str += "bar"; - BOOST_TEST(str.str == "foobar"); - } - // std::string - { - toml::string str("foo"); - std::string str2("bar"); - str += str2; - BOOST_TEST(str.str == "foobar"); - } - // toml::string - { - toml::string str("foo"); - toml::string str2("bar"); - str += str2; - BOOST_TEST(str.str == "foobar"); - } -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L - // std::string_view - { - toml::string str("foo"); - str += std::string_view("bar"); - BOOST_TEST(str == "foobar"); - } -#endif - // std::string += toml::string - { - std::string str("foo"); - toml::string str2("bar"); - str += str2; - BOOST_TEST(str == "foobar"); - } - - -} diff --git a/tests/test_syntax_boolean.cpp b/tests/test_syntax_boolean.cpp new file mode 100644 index 0000000..42743b1 --- /dev/null +++ b/tests/test_syntax_boolean.cpp @@ -0,0 +1,28 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing boolean should success") +{ + const auto scanner = toml::detail::syntax::boolean(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "true", "true"); + test_scan_success(scanner, "false", "false"); + test_scan_success(scanner, "true # comment", "true"); + test_scan_success(scanner, "false # comment", "false"); +} + +TEST_CASE("testing boolean should fail") +{ + const auto scanner = toml::detail::syntax::boolean(toml::spec::v(1,0,0)); + + test_scan_failure(scanner, "TRUE"); + test_scan_failure(scanner, "FALSE"); + test_scan_failure(scanner, "True"); + test_scan_failure(scanner, "False"); + test_scan_failure(scanner, "T"); + test_scan_failure(scanner, "F"); +} diff --git a/tests/test_syntax_comment.cpp b/tests/test_syntax_comment.cpp new file mode 100644 index 0000000..449f32f --- /dev/null +++ b/tests/test_syntax_comment.cpp @@ -0,0 +1,16 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing comment") +{ + const auto scanner = toml::detail::syntax::comment(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "# hoge", "# hoge"); + test_scan_success(scanner, "# \n", "# "); + test_scan_success(scanner, "# \r\n", "# "); + test_scan_success(scanner, "# # \n", "# # "); +} diff --git a/tests/test_syntax_datetime.cpp b/tests/test_syntax_datetime.cpp new file mode 100644 index 0000000..ad07d42 --- /dev/null +++ b/tests/test_syntax_datetime.cpp @@ -0,0 +1,136 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing offset_datetime") +{ + { + const auto scanner = toml::detail::syntax::offset_datetime(toml::spec::v(1,0,0)); + + test_scan_success(scanner, + "1979-05-27T07:32:00Z", + "1979-05-27T07:32:00Z"); + test_scan_success(scanner, + "1979-05-27T07:32:00-07:00", + "1979-05-27T07:32:00-07:00"); + test_scan_success(scanner, + "1979-05-27T07:32:00.999999-07:00", + "1979-05-27T07:32:00.999999-07:00"); + + test_scan_success(scanner, + "1979-05-27 07:32:00Z", + "1979-05-27 07:32:00Z"); + test_scan_success(scanner, + "1979-05-27 07:32:00-07:00", + "1979-05-27 07:32:00-07:00"); + test_scan_success(scanner, + "1979-05-27 07:32:00.999999-07:00", + "1979-05-27 07:32:00.999999-07:00"); + } + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + const auto scanner = toml::detail::syntax::offset_datetime(spec); + + test_scan_success(scanner, + "1979-05-27T07:32Z", + "1979-05-27T07:32Z"); + + test_scan_success(scanner, + "1979-05-27T07:32:00Z", + "1979-05-27T07:32:00Z"); + test_scan_success(scanner, + "1979-05-27T07:32:00-07:00", + "1979-05-27T07:32:00-07:00"); + test_scan_success(scanner, + "1979-05-27T07:32:00.999999-07:00", + "1979-05-27T07:32:00.999999-07:00"); + + test_scan_success(scanner, + "1979-05-27 07:32Z", + "1979-05-27 07:32Z"); + test_scan_success(scanner, + "1979-05-27 07:32:00Z", + "1979-05-27 07:32:00Z"); + test_scan_success(scanner, + "1979-05-27 07:32:00-07:00", + "1979-05-27 07:32:00-07:00"); + test_scan_success(scanner, + "1979-05-27 07:32:00.999999-07:00", + "1979-05-27 07:32:00.999999-07:00"); + } + +} + +TEST_CASE("testing local_datetime") +{ + { + const auto scanner = toml::detail::syntax::local_datetime(toml::spec::v(1,0,0)); + + test_scan_success(scanner, + "1979-05-27T07:32:00", + "1979-05-27T07:32:00"); + test_scan_success(scanner, + "1979-05-27T07:32:00.999999", + "1979-05-27T07:32:00.999999"); + + test_scan_success(scanner, + "1979-05-27 07:32:00", + "1979-05-27 07:32:00"); + test_scan_success(scanner, + "1979-05-27 07:32:00.999999", + "1979-05-27 07:32:00.999999"); + } + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + const auto scanner = toml::detail::syntax::local_datetime(spec); + + test_scan_success(scanner, + "1979-05-27T07:32", + "1979-05-27T07:32"); + test_scan_success(scanner, + "1979-05-27T07:32:00", + "1979-05-27T07:32:00"); + test_scan_success(scanner, + "1979-05-27T07:32:00.999999", + "1979-05-27T07:32:00.999999"); + + test_scan_success(scanner, + "1979-05-27 07:32:00", + "1979-05-27 07:32:00"); + test_scan_success(scanner, + "1979-05-27 07:32:00.999999", + "1979-05-27 07:32:00.999999"); + } +} + +TEST_CASE("testing local_date") +{ + const auto scanner = toml::detail::syntax::local_date(toml::spec::v(1,0,0)); + test_scan_success(scanner, "1979-05-27", "1979-05-27"); +} +TEST_CASE("testing local_time") +{ + { + const auto scanner = toml::detail::syntax::local_time(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "07:32:00", "07:32:00"); + test_scan_success(scanner, "07:32:00.999999", "07:32:00.999999"); + } + + { + auto spec = toml::spec::v(1,0,0); + spec.v1_1_0_make_seconds_optional = true; + + const auto scanner = toml::detail::syntax::local_time(spec); + + test_scan_success(scanner, "07:32", "07:32"); + test_scan_success(scanner, "07:32:00", "07:32:00"); + test_scan_success(scanner, "07:32:00.999999", "07:32:00.999999"); + } + +} diff --git a/tests/test_syntax_floating.cpp b/tests/test_syntax_floating.cpp new file mode 100644 index 0000000..e73ea3a --- /dev/null +++ b/tests/test_syntax_floating.cpp @@ -0,0 +1,99 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing fractional_valid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_success(floating, "1.0", "1.0" ); + test_scan_success(floating, "0.1", "0.1" ); + test_scan_success(floating, "0.001", "0.001" ); + test_scan_success(floating, "0.100", "0.100" ); + test_scan_success(floating, "+3.14", "+3.14" ); + test_scan_success(floating, "-3.14", "-3.14" ); + test_scan_success(floating, "3.1415_9265_3589", "3.1415_9265_3589" ); + test_scan_success(floating, "+3.1415_9265_3589", "+3.1415_9265_3589"); + test_scan_success(floating, "-3.1415_9265_3589", "-3.1415_9265_3589"); + test_scan_success(floating, "123_456.789", "123_456.789" ); + test_scan_success(floating, "+123_456.789", "+123_456.789" ); + test_scan_success(floating, "-123_456.789", "-123_456.789" ); +} + +TEST_CASE("testing fractional_invalid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_failure(floating, "0."); + test_scan_failure(floating, ".0"); + test_scan_failure(floating, "01.0"); + test_scan_failure(floating, "3,14"); + test_scan_failure(floating, "+-1.0"); + test_scan_failure(floating, "1._0"); +} + +TEST_CASE("testing exponential_valid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_success(floating, "1e10", "1e10"); + test_scan_success(floating, "1e+10", "1e+10"); + test_scan_success(floating, "1e-10", "1e-10"); + test_scan_success(floating, "+1e10", "+1e10"); + test_scan_success(floating, "+1e+10", "+1e+10"); + test_scan_success(floating, "+1e-10", "+1e-10"); + test_scan_success(floating, "-1e10", "-1e10"); + test_scan_success(floating, "-1e+10", "-1e+10"); + test_scan_success(floating, "-1e-10", "-1e-10"); + test_scan_success(floating, "123e-10", "123e-10"); + test_scan_success(floating, "1E10", "1E10"); + test_scan_success(floating, "1E+10", "1E+10"); + test_scan_success(floating, "1E-10", "1E-10"); + test_scan_success(floating, "123E-10", "123E-10"); + test_scan_success(floating, "1_2_3E-10", "1_2_3E-10"); + test_scan_success(floating, "1_2_3E-1_0", "1_2_3E-1_0"); + + test_scan_success(floating, "1_2_3E-01", "1_2_3E-01"); + test_scan_success(floating, "1_2_3E-0_1", "1_2_3E-0_1"); +} + +TEST_CASE("testing exponential_invalid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + // accept partially + test_scan_success(floating, "1e1E0", "1e1"); + test_scan_success(floating, "1E1e0", "1E1"); +} + +TEST_CASE("testing both_valid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_success(floating, "6.02e23", "6.02e23"); + test_scan_success(floating, "6.02e+23", "6.02e+23"); + test_scan_success(floating, "1.112_650_06e-17", "1.112_650_06e-17"); + + test_scan_success(floating, "1.0e-07", "1.0e-07"); +} + +TEST_CASE("testing both_invalid") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_failure(floating, "01e1.0"); + // accept partially + test_scan_success(floating, "1e1.0", "1e1"); + + test_scan_success(floating, "1.0e_01", "1.0"); + test_scan_success(floating, "1.0e0__1", "1.0e0"); +} + +TEST_CASE("testing special_floating_point") +{ + const auto floating = toml::detail::syntax::floating(toml::spec::v(1,0,0)); + test_scan_success(floating, "inf", "inf"); + test_scan_success(floating, "+inf", "+inf"); + test_scan_success(floating, "-inf", "-inf"); + + test_scan_success(floating, "nan", "nan"); + test_scan_success(floating, "+nan", "+nan"); + test_scan_success(floating, "-nan", "-nan"); +} diff --git a/tests/test_syntax_integer.cpp b/tests/test_syntax_integer.cpp new file mode 100644 index 0000000..9202b4d --- /dev/null +++ b/tests/test_syntax_integer.cpp @@ -0,0 +1,117 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing decimal_correct") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + + test_scan_success(integer, "1234", "1234" ); + test_scan_success(integer, "+1234", "+1234" ); + test_scan_success(integer, "-1234", "-1234" ); + test_scan_success(integer, "0", "0" ); + test_scan_success(integer, "1_2_3_4", "1_2_3_4" ); + test_scan_success(integer, "+1_2_3_4", "+1_2_3_4" ); + test_scan_success(integer, "-1_2_3_4", "-1_2_3_4" ); + test_scan_success(integer, "123_456_789", "123_456_789"); +} + +TEST_CASE("testing decimal_invalid") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + + test_scan_success(integer, "123+45", "123"); + test_scan_success(integer, "123-45", "123"); + test_scan_success(integer, "01234", "0"); + test_scan_success(integer, "123__45", "123"); + + test_scan_failure(integer, "_1234"); +} + +TEST_CASE("testing hex_correct") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + + test_scan_success(integer, "0xDEADBEEF", "0xDEADBEEF" ); + test_scan_success(integer, "0xdeadbeef", "0xdeadbeef" ); + test_scan_success(integer, "0xDEADbeef", "0xDEADbeef" ); + test_scan_success(integer, "0xDEAD_BEEF", "0xDEAD_BEEF"); + test_scan_success(integer, "0xdead_beef", "0xdead_beef"); + test_scan_success(integer, "0xdead_BEEF", "0xdead_BEEF"); + + test_scan_success(integer, "0xFF", "0xFF" ); + test_scan_success(integer, "0x00FF", "0x00FF" ); + test_scan_success(integer, "0x0000FF", "0x0000FF"); +} + +TEST_CASE("testing hex_invalid") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + const auto hex_int = toml::detail::syntax::hex_int(toml::spec::v(1,0,0)); + + test_scan_success(integer, "0xAPPLE", "0xA"); + test_scan_success(integer, "0xDEAD+BEEF", "0xDEAD"); + test_scan_success(integer, "0xDEAD__BEEF", "0xDEAD"); + + test_scan_failure(hex_int, "0x_DEADBEEF"); + test_scan_failure(hex_int, "0x+DEADBEEF"); + test_scan_failure(hex_int, "-0xFF" ); + test_scan_failure(hex_int, "-0x00FF" ); + + test_scan_success(integer, "0x_DEADBEEF", "0" ); + test_scan_success(integer, "0x+DEADBEEF", "0" ); + test_scan_success(integer, "-0xFF" , "-0" ); + test_scan_success(integer, "-0x00FF" , "-0" ); +} + +TEST_CASE("testing oct_correct") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + + test_scan_success(integer, "0o777", "0o777" ); + test_scan_success(integer, "0o7_7_7", "0o7_7_7"); + test_scan_success(integer, "0o007", "0o007" ); +} + +TEST_CASE("testing oct_invalid") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + const auto oct_int = toml::detail::syntax::hex_int(toml::spec::v(1,0,0)); + + test_scan_success(integer, "0o77+7", "0o77"); + test_scan_success(integer, "0o1__0", "0o1"); + + test_scan_failure(oct_int, "0o800" ); + test_scan_failure(oct_int, "-0o777"); + test_scan_failure(oct_int, "0o+777"); + test_scan_failure(oct_int, "0o_10" ); + + test_scan_success(integer, "0o800", "0"); + test_scan_success(integer, "-0o777", "-0"); + test_scan_success(integer, "0o+777", "0"); + test_scan_success(integer, "0o_10", "0"); +} + +TEST_CASE("testing bin_correct") +{ + const auto integer = toml::detail::syntax::integer(toml::spec::v(1,0,0)); + + test_scan_success(integer, "0b10000", "0b10000" ); + test_scan_success(integer, "0b010000", "0b010000" ); + test_scan_success(integer, "0b01_00_00", "0b01_00_00"); + test_scan_success(integer, "0b111111", "0b111111" ); +} + +TEST_CASE("testing bin_invalid") +{ + const auto bin_int = toml::detail::syntax::bin_int(toml::spec::v(1,0,0)); + + test_scan_success(bin_int, "0b11__11", "0b11"); + test_scan_success(bin_int, "0b11+11" , "0b11"); + + test_scan_failure(bin_int, "-0b10000"); + test_scan_failure(bin_int, "0b_1111" ); +} diff --git a/tests/test_syntax_key.cpp b/tests/test_syntax_key.cpp new file mode 100644 index 0000000..15bc8f9 --- /dev/null +++ b/tests/test_syntax_key.cpp @@ -0,0 +1,49 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include "utility.hpp" + +#include + +TEST_CASE("testing bare_key") +{ + const auto scanner = toml::detail::syntax::key(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "barekey", "barekey"); + test_scan_success(scanner, "bare-key", "bare-key"); + test_scan_success(scanner, "bare_key", "bare_key"); + test_scan_success(scanner, "1234", "1234"); +} + +TEST_CASE("testing quoted_key") +{ + const auto scanner = toml::detail::syntax::key(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "\"127.0.0.1\"", "\"127.0.0.1\""); + test_scan_success(scanner, "\"character encoding\"", "\"character encoding\""); + + // UTF-8 codepoint of characters that looks like "key" written upside down + test_scan_success(scanner, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", + "\"\xCA\x8E\xC7\x9D\xCA\x9E\""); + + test_scan_success(scanner, "'key2'", "'key2'"); + test_scan_success(scanner, "'quoted \"value\"'", "'quoted \"value\"'"); +} + +TEST_CASE("testing dotted_key") +{ + const auto scanner = toml::detail::syntax::key(toml::spec::v(1,0,0)); + + test_scan_success(scanner, "physical.color", "physical.color"); + test_scan_success(scanner, "physical.shape", "physical.shape"); + test_scan_success(scanner, "x.y", "x.y"); + test_scan_success(scanner, "x . y", "x . y"); + test_scan_success(scanner, "x.y.z", "x.y.z"); + test_scan_success(scanner, "x. y .z", "x. y .z"); + test_scan_success(scanner, "x .y. z", "x .y. z"); + test_scan_success(scanner, "x . y . z", "x . y . z"); + test_scan_success(scanner, "x.y.z.w", "x.y.z.w"); + test_scan_success(scanner, "x. y .z. w", "x. y .z. w"); + test_scan_success(scanner, "x . y . z . w", "x . y . z . w"); + test_scan_success(scanner, "site.\"google.com\"", "site.\"google.com\""); +} diff --git a/tests/test_lex_string.cpp b/tests/test_syntax_string.cpp similarity index 61% rename from tests/test_lex_string.cpp rename to tests/test_syntax_string.cpp index f8f2424..8e41eed 100644 --- a/tests/test_lex_string.cpp +++ b/tests/test_syntax_string.cpp @@ -1,108 +1,125 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" -#include "test_lex_aux.hpp" +#include "utility.hpp" -using namespace toml; -using namespace detail; +#include -BOOST_AUTO_TEST_CASE(test_string) +TEST_CASE("testing string") { - TOML11_TEST_LEX_ACCEPT(lex_string, + const auto string = toml::detail::syntax::string(toml::spec::v(1,0,0)); + const auto ml_basic_string = toml::detail::syntax::ml_basic_string(toml::spec::v(1,0,0)); + const auto ml_literal_string = toml::detail::syntax::ml_literal_string(toml::spec::v(1,0,0)); + + test_scan_success(string, "\"The quick brown fox jumps over the lazy dog\"", "\"The quick brown fox jumps over the lazy dog\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\'The quick brown fox jumps over the lazy dog\'", "\'The quick brown fox jumps over the lazy dog\'"); - TOML11_TEST_LEX_ACCEPT(lex_ml_basic_string, + test_scan_success(ml_basic_string, + "\"\"\"The quick brown fox jumps over the lazy dog\"\"\"", + "\"\"\"The quick brown fox jumps over the lazy dog\"\"\""); + test_scan_success(ml_basic_string, "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_ml_literal_string, + test_scan_success(ml_literal_string, + "'''The quick brown fox jumps over the lazy dog'''", + "'''The quick brown fox jumps over the lazy dog'''"); + test_scan_success(ml_literal_string, "'''The quick brown fox \njumps over the lazy dog'''", "'''The quick brown fox \njumps over the lazy dog'''"); } -BOOST_AUTO_TEST_CASE(test_basic_string) +TEST_CASE("testing basic_string") { - TOML11_TEST_LEX_ACCEPT(lex_string, + const auto string = toml::detail::syntax::string(toml::spec::v(1,0,0)); + + test_scan_success(string, "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"192.168.1.1\"", "\"192.168.1.1\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", // UTF-8 string (means "China" in "\"\xE4\xB8\xAD\xE5\x9B\xBD\""); // Chinese characters) - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"You'll hate me after this - #\"", "\"You'll hate me after this - #\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\" And when \\\"'s are in the string, along with # \\\"\"", "\" And when \\\"'s are in the string, along with # \\\"\""); } -BOOST_AUTO_TEST_CASE(test_ml_basic_string) +TEST_CASE("testing ml_basic_string") { - TOML11_TEST_LEX_ACCEPT(lex_string, + const auto string = toml::detail::syntax::string(toml::spec::v(1,0,0)); + + test_scan_success(string, "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"", "\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"", "\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"", "\"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\"", "\"\"\"Here are three quotation marks: \"\"\\\".\"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"", "\"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\""); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\"", "\"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\""); } -BOOST_AUTO_TEST_CASE(test_literal_string) +TEST_CASE("testing literal_string") { - TOML11_TEST_LEX_ACCEPT(lex_string, + const auto string = toml::detail::syntax::string(toml::spec::v(1,0,0)); + + test_scan_success(string, "'C:\\Users\\nodejs\\templates'", "'C:\\Users\\nodejs\\templates'"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "'\\\\ServerX\\admin$\\system32\\'", "'\\\\ServerX\\admin$\\system32\\'"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "'Tom \"Dubs\" Preston-Werner'", "'Tom \"Dubs\" Preston-Werner'"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "'<\\i\\c*\\s*>'", "'<\\i\\c*\\s*>'"); } -BOOST_AUTO_TEST_CASE(test_ml_literal_string) +TEST_CASE("testing ml_literal_string") { - TOML11_TEST_LEX_ACCEPT(lex_string, + const auto string = toml::detail::syntax::string(toml::spec::v(1,0,0)); + + test_scan_success(string, "'''I [dw]on't need \\d{2} apples'''", "'''I [dw]on't need \\d{2} apples'''"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''", "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "''''That's still pointless', she said.'''", "''''That's still pointless', she said.'''"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''", "'''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".'''"); - TOML11_TEST_LEX_ACCEPT(lex_string, + test_scan_success(string, "''''This,' she said, 'is just a pointless statement.''''", "''''This,' she said, 'is just a pointless statement.''''"); } diff --git a/tests/test_traits.cpp b/tests/test_traits.cpp index 4d5e3e2..a4438e0 100644 --- a/tests/test_traits.cpp +++ b/tests/test_traits.cpp @@ -1,6 +1,7 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include #include #include @@ -17,63 +18,72 @@ struct dummy_type{}; template struct dummy_container { - typedef T value_type; - typedef value_type* pointer; - typedef value_type& reference; + typedef T value_type; + typedef value_type* pointer; + typedef value_type& reference; typedef value_type const* const_pointer; typedef value_type const& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; + typedef pointer iterator; + typedef const_pointer const_iterator; }; -typedef std::array std_array_type; -typedef std::map std_map_type; -typedef std::unordered_map std_unordered_map_type; - -BOOST_AUTO_TEST_CASE(test_has_xxx) +TEST_CASE("testing has_xxx traits") { - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_iterator::value); - BOOST_TEST(toml::detail::has_iterator::value); - BOOST_TEST(toml::detail::has_iterator::value); - BOOST_TEST(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); + CHECK_UNARY(toml::detail::has_iterator>::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_value_type::value); - BOOST_TEST(toml::detail::has_value_type::value); - BOOST_TEST(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); + CHECK_UNARY(toml::detail::has_value_type>::value); - BOOST_TEST(toml::detail::has_key_type::value); - BOOST_TEST(toml::detail::has_key_type::value); - BOOST_TEST(toml::detail::has_mapped_type::value); - BOOST_TEST(toml::detail::has_mapped_type::value); + CHECK_UNARY(toml::detail::has_key_type>::value); + CHECK_UNARY(toml::detail::has_key_type>::value); + CHECK_UNARY(toml::detail::has_mapped_type>::value); + CHECK_UNARY(toml::detail::has_mapped_type>::value); } -BOOST_AUTO_TEST_CASE(test_is_xxx) +TEST_CASE("testing is_xxx traits") { - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container::value); - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); + CHECK_UNARY(toml::detail::is_container>::value); - BOOST_TEST(!toml::detail::is_container::value); - BOOST_TEST(!toml::detail::is_container::value); + CHECK_UNARY_FALSE(toml::detail::is_container>::value); + CHECK_UNARY_FALSE(toml::detail::is_container>::value); - BOOST_TEST(toml::detail::is_map::value); - BOOST_TEST(toml::detail::is_map::value); + CHECK_UNARY(toml::detail::is_map>::value); + CHECK_UNARY(toml::detail::is_map>::value); +} + +TEST_CASE("testing make_index_sequence") +{ + static_assert(std::is_same, toml::cxx::index_sequence<>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2,3>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2,3,4>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2,3,4,5>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2,3,4,5,6>>::value, ""); + static_assert(std::is_same, toml::cxx::index_sequence<0,1,2,3,4,5,6,7>>::value, ""); } diff --git a/tests/test_types.cpp b/tests/test_types.cpp new file mode 100644 index 0000000..82fb029 --- /dev/null +++ b/tests/test_types.cpp @@ -0,0 +1,137 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +TEST_CASE("testing value_t to string") +{ + CHECK_EQ(toml::to_string(toml::value_t::boolean ), "boolean"); + CHECK_EQ(toml::to_string(toml::value_t::integer ), "integer"); + CHECK_EQ(toml::to_string(toml::value_t::floating ), "floating"); + CHECK_EQ(toml::to_string(toml::value_t::string ), "string"); + CHECK_EQ(toml::to_string(toml::value_t::offset_datetime), "offset_datetime"); + CHECK_EQ(toml::to_string(toml::value_t::local_datetime ), "local_datetime"); + CHECK_EQ(toml::to_string(toml::value_t::local_date ), "local_date"); + CHECK_EQ(toml::to_string(toml::value_t::local_time ), "local_time"); + CHECK_EQ(toml::to_string(toml::value_t::array ), "array"); + CHECK_EQ(toml::to_string(toml::value_t::table ), "table"); + + + {std::ostringstream oss; oss << toml::value_t::boolean ; CHECK_EQ(oss.str(), "boolean" );} + {std::ostringstream oss; oss << toml::value_t::integer ; CHECK_EQ(oss.str(), "integer" );} + {std::ostringstream oss; oss << toml::value_t::floating ; CHECK_EQ(oss.str(), "floating" );} + {std::ostringstream oss; oss << toml::value_t::string ; CHECK_EQ(oss.str(), "string" );} + {std::ostringstream oss; oss << toml::value_t::offset_datetime; CHECK_EQ(oss.str(), "offset_datetime");} + {std::ostringstream oss; oss << toml::value_t::local_datetime ; CHECK_EQ(oss.str(), "local_datetime" );} + {std::ostringstream oss; oss << toml::value_t::local_date ; CHECK_EQ(oss.str(), "local_date" );} + {std::ostringstream oss; oss << toml::value_t::local_time ; CHECK_EQ(oss.str(), "local_time" );} + {std::ostringstream oss; oss << toml::value_t::array ; CHECK_EQ(oss.str(), "array" );} + {std::ostringstream oss; oss << toml::value_t::table ; CHECK_EQ(oss.str(), "table" );} +} + +#include + +TEST_CASE("testing type_to_enum") +{ + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::boolean ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::integer ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::floating ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::string ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::local_time ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::local_date ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::local_datetime ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::offset_datetime); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::array ); + CHECK_EQ((toml::detail::type_to_enum::value), toml::value_t::table ); +} + +TEST_CASE("testing enum_to_type") +{ + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + CHECK_UNARY(std::is_same::type, boolean_type >::value); + CHECK_UNARY(std::is_same::type, integer_type >::value); + CHECK_UNARY(std::is_same::type, floating_type >::value); + CHECK_UNARY(std::is_same::type, string_type >::value); + CHECK_UNARY(std::is_same::type, local_time_type >::value); + CHECK_UNARY(std::is_same::type, local_date_type >::value); + CHECK_UNARY(std::is_same::type, local_datetime_type >::value); + CHECK_UNARY(std::is_same::type, offset_datetime_type>::value); + CHECK_UNARY(std::is_same::type, array_type >::value); + CHECK_UNARY(std::is_same::type, table_type >::value); +} + +TEST_CASE("testing is_exact_toml_type") +{ + using value_type = toml::value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + CHECK_UNARY(toml::detail::is_exact_toml_type::value); + + CHECK_UNARY_FALSE(toml::detail::is_exact_toml_type::value); + CHECK_UNARY_FALSE(toml::detail::is_exact_toml_type::value); + CHECK_UNARY_FALSE(toml::detail::is_exact_toml_type, value_type>::value); + +} diff --git a/tests/test_user_defined_conversion.cpp b/tests/test_user_defined_conversion.cpp new file mode 100644 index 0000000..e8941ae --- /dev/null +++ b/tests/test_user_defined_conversion.cpp @@ -0,0 +1,623 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include +#include "utility.hpp" + +namespace extlib +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + + void from_toml(const toml::value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + return ; + } + + toml::table into_toml() const + { + return toml::table{{"a", this->a}, {"b", this->b}}; + } +}; + +struct baz +{ + int a; + std::string b; +}; +struct qux +{ + int a; + std::string b; +}; + +struct foobar +{ + // via constructor + explicit foobar(const toml::value& v) + : a(toml::find(v, "a")), b(toml::find(v, "b")) + {} + int a; + std::string b; +}; +} // extlib + +namespace toml +{ +template<> +struct from +{ + static extlib::foo from_toml(const toml::value& v) + { + return extlib::foo{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + template + static toml::basic_value into_toml(const extlib::foo& f) + { + return toml::basic_value(typename toml::basic_value::table_type{{"a", f.a}, {"b", f.b}}); + } +}; + +template<> +struct from +{ + static extlib::baz from_toml(const toml::value& v) + { + return extlib::baz{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + template + static toml::basic_value into_toml(const extlib::qux& f) + { + return toml::basic_value(typename toml::basic_value::table_type{{"a", f.a}, {"b", f.b}}); + } +}; +} // toml + +// --------------------------------------------------------------------------- + +namespace extlib2 +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + + template + void from_toml(const toml::basic_value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + return ; + } + + toml::ordered_table into_toml() const + { + return toml::ordered_table{{"a", this->a}, {"b", this->b}}; + } +}; +struct baz +{ + int a; + std::string b; +}; +struct qux +{ + int a; + std::string b; +}; + +struct foobar +{ + template + explicit foobar(const toml::basic_value& v) + : a(toml::find(v, "a")), b(toml::find(v, "b")) + {} + int a; + std::string b; +}; + +} // extlib2 + +namespace toml +{ +template<> +struct from +{ + template + static extlib2::foo from_toml(const toml::basic_value& v) + { + return extlib2::foo{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + template + static toml::basic_value into_toml(const extlib2::foo& f) + { + return toml::basic_value(typename toml::basic_value::table_type{{"a", f.a}, {"b", f.b}}); + } +}; + +template<> +struct from +{ + template + static extlib2::baz from_toml(const toml::basic_value& v) + { + return extlib2::baz{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + template + static toml::basic_value + into_toml(const extlib2::qux& f) + { + return toml::basic_value{ + {"a", f.a}, {"b", f.b} + }; + } +}; +} // toml + +// --------------------------------------------------------------------------- + +TEST_CASE("test_conversion_by_member_methods") +{ + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto foo = toml::get(v); + CHECK_EQ(foo.a, 42); + CHECK_EQ(foo.b, "baz"); + + const toml::value v2(foo); + + CHECK_EQ(v, v2); + } + + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto foo = toml::get(v); + CHECK(foo.a == 42); + CHECK(foo.b == "baz"); + + const toml::value v2(foo); + CHECK(v == v2); + } + + { + const toml::ordered_value v(toml::ordered_table{{"a", 42}, {"b", "baz"}}); + + const auto foo = toml::get(v); + CHECK(foo.a == 42); + CHECK(foo.b == "baz"); + + const toml::ordered_value v2(foo); + + CHECK(v == v2); + } +} + +TEST_CASE("test_conversion_by_specialization") +{ + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto bar = toml::get(v); + CHECK(bar.a == 42); + CHECK(bar.b == "baz"); + + const toml::value v2(bar); + + CHECK(v == v2); + } + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto bar = toml::get(v); + CHECK(bar.a == 42); + CHECK(bar.b == "baz"); + + const toml::value v2(bar); + + CHECK(v == v2); + } + { + const toml::ordered_value v(toml::ordered_table{{"a", 42}, {"b", "baz"}}); + + const auto bar = toml::get(v); + CHECK(bar.a == 42); + CHECK(bar.b == "baz"); + + const toml::ordered_value v2(bar); + + CHECK(v == v2); + } +} + +TEST_CASE("test_conversion_one_way") +{ + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto baz = toml::get(v); + CHECK(baz.a == 42); + CHECK(baz.b == "baz"); + } + { + const extlib::qux q{42, "qux"}; + const toml::value v(q); + + CHECK(toml::find(v, "a") == 42); + CHECK(toml::find(v, "b") == "qux"); + } + + { + const toml::ordered_value v(toml::ordered_table{ + {"a", 42}, {"b", "baz"} + }); + + const auto baz = toml::get(v); + CHECK(baz.a == 42); + CHECK(baz.b == "baz"); + } + { + const extlib::qux q{42, "qux"}; + const toml::ordered_value v(q); + + CHECK(toml::find(v, "a") == 42); + CHECK(toml::find(v, "b") == "qux"); + } +} + +TEST_CASE("test_conversion_via_constructor") +{ + { + const toml::value v(toml::table{{"a", 42}, {"b", "foobar"}}); + + const auto foobar = toml::get(v); + CHECK(foobar.a == 42); + CHECK(foobar.b == "foobar"); + } + + { + const toml::ordered_value v(toml::ordered_table{ + {"a", 42}, {"b", "foobar"} + }); + + const auto foobar = toml::get(v); + CHECK(foobar.a == 42); + CHECK(foobar.b == "foobar"); + } +} + +TEST_CASE("test_recursive_conversion") +{ + { + const toml::value v(toml::array{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}}, + }); + + const auto foos = toml::get>(v); + CHECK(foos.size() == 4ul); + CHECK(foos.at(0).a == 42); + CHECK(foos.at(1).a == 43); + CHECK(foos.at(2).a == 44); + CHECK(foos.at(3).a == 45); + + CHECK(foos.at(0).b == "baz"); + CHECK(foos.at(1).b == "qux"); + CHECK(foos.at(2).b == "quux"); + CHECK(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + CHECK(bars.size() == 4ul); + CHECK(bars.at(0).a == 42); + CHECK(bars.at(1).a == 43); + CHECK(bars.at(2).a == 44); + CHECK(bars.at(3).a == 45); + + CHECK(bars.at(0).b == "baz"); + CHECK(bars.at(1).b == "qux"); + CHECK(bars.at(2).b == "quux"); + CHECK(bars.at(3).b == "foobar"); + } + { + const toml::value v(toml::array{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}}, + }); + + const auto foos = toml::get>(v); + CHECK(foos.size() == 4ul); + CHECK(foos.at(0).a == 42); + CHECK(foos.at(1).a == 43); + CHECK(foos.at(2).a == 44); + CHECK(foos.at(3).a == 45); + + CHECK(foos.at(0).b == "baz"); + CHECK(foos.at(1).b == "qux"); + CHECK(foos.at(2).b == "quux"); + CHECK(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + CHECK(bars.size() == 4ul); + CHECK(bars.at(0).a == 42); + CHECK(bars.at(1).a == 43); + CHECK(bars.at(2).a == 44); + CHECK(bars.at(3).a == 45); + + CHECK(bars.at(0).b == "baz"); + CHECK(bars.at(1).b == "qux"); + CHECK(bars.at(2).b == "quux"); + CHECK(bars.at(3).b == "foobar"); + } + + { + const toml::ordered_value v(toml::ordered_array{ + toml::ordered_table{{"a", 42}, {"b", "baz"}}, + toml::ordered_table{{"a", 43}, {"b", "qux"}}, + toml::ordered_table{{"a", 44}, {"b", "quux"}}, + toml::ordered_table{{"a", 45}, {"b", "foobar"}} + }); + + const auto foos = toml::get>(v); + CHECK(foos.size() == 4ul); + CHECK(foos.at(0).a == 42); + CHECK(foos.at(1).a == 43); + CHECK(foos.at(2).a == 44); + CHECK(foos.at(3).a == 45); + + CHECK(foos.at(0).b == "baz"); + CHECK(foos.at(1).b == "qux"); + CHECK(foos.at(2).b == "quux"); + CHECK(foos.at(3).b == "foobar"); + + const auto bars = toml::get>(v); + CHECK(bars.size() == 4ul); + CHECK(bars.at(0).a == 42); + CHECK(bars.at(1).a == 43); + CHECK(bars.at(2).a == 44); + CHECK(bars.at(3).a == 45); + + CHECK(bars.at(0).b == "baz"); + CHECK(bars.at(1).b == "qux"); + CHECK(bars.at(2).b == "quux"); + CHECK(bars.at(3).b == "foobar"); + } + + // via constructor + { + const toml::value v(toml::array{ + toml::table{{"a", 42}, {"b", "baz"}}, + toml::table{{"a", 43}, {"b", "qux"}}, + toml::table{{"a", 44}, {"b", "quux"}}, + toml::table{{"a", 45}, {"b", "foobar"}} + }); + + { + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at(0).a == 42); + CHECK(foobars.at(1).a == 43); + CHECK(foobars.at(2).a == 44); + CHECK(foobars.at(3).a == 45); + + CHECK(foobars.at(0).b == "baz"); + CHECK(foobars.at(1).b == "qux"); + CHECK(foobars.at(2).b == "quux"); + CHECK(foobars.at(3).b == "foobar"); + } + { + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at(0).a == 42); + CHECK(foobars.at(1).a == 43); + CHECK(foobars.at(2).a == 44); + CHECK(foobars.at(3).a == 45); + + CHECK(foobars.at(0).b == "baz"); + CHECK(foobars.at(1).b == "qux"); + CHECK(foobars.at(2).b == "quux"); + CHECK(foobars.at(3).b == "foobar"); + } + } + { + const toml::ordered_value v(toml::ordered_array{ + toml::ordered_table{{"a", 42}, {"b", "baz"}}, + toml::ordered_table{{"a", 43}, {"b", "qux"}}, + toml::ordered_table{{"a", 44}, {"b", "quux"}}, + toml::ordered_table{{"a", 45}, {"b", "foobar"}} + }); + + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at(0).a == 42); + CHECK(foobars.at(1).a == 43); + CHECK(foobars.at(2).a == 44); + CHECK(foobars.at(3).a == 45); + + CHECK(foobars.at(0).b == "baz"); + CHECK(foobars.at(1).b == "qux"); + CHECK(foobars.at(2).b == "quux"); + CHECK(foobars.at(3).b == "foobar"); + } + + // via constructor + { + const toml::value v(toml::table{ + {"0", toml::table{{"a", 42}, {"b", "baz"}}}, + {"1", toml::table{{"a", 43}, {"b", "qux"}}}, + {"2", toml::table{{"a", 44}, {"b", "quux"}}}, + {"3", toml::table{{"a", 45}, {"b", "foobar"}}} + }); + + { + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at("0").a == 42); + CHECK(foobars.at("1").a == 43); + CHECK(foobars.at("2").a == 44); + CHECK(foobars.at("3").a == 45); + + CHECK(foobars.at("0").b == "baz"); + CHECK(foobars.at("1").b == "qux"); + CHECK(foobars.at("2").b == "quux"); + CHECK(foobars.at("3").b == "foobar"); + } + { + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at("0").a == 42); + CHECK(foobars.at("1").a == 43); + CHECK(foobars.at("2").a == 44); + CHECK(foobars.at("3").a == 45); + + CHECK(foobars.at("0").b == "baz"); + CHECK(foobars.at("1").b == "qux"); + CHECK(foobars.at("2").b == "quux"); + CHECK(foobars.at("3").b == "foobar"); + } + } + { + const toml::ordered_value v(toml::ordered_table{ + {"0", toml::ordered_table{{"a", 42}, {"b", "baz"}}}, + {"1", toml::ordered_table{{"a", 43}, {"b", "qux"}}}, + {"2", toml::ordered_table{{"a", 44}, {"b", "quux"}}}, + {"3", toml::ordered_table{{"a", 45}, {"b", "foobar"}}} + }); + + const auto foobars = toml::get>(v); + CHECK(foobars.size() == 4ul); + CHECK(foobars.at("0").a == 42); + CHECK(foobars.at("1").a == 43); + CHECK(foobars.at("2").a == 44); + CHECK(foobars.at("3").a == 45); + + CHECK(foobars.at("0").b == "baz"); + CHECK(foobars.at("1").b == "qux"); + CHECK(foobars.at("2").b == "quux"); + CHECK(foobars.at("3").b == "foobar"); + } + +} + +// =========================================================================== + +#ifndef TOML11_WITHOUT_DEFINE_NON_INTRUSIVE + +namespace extlib3 +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + foo f; +}; + +} // extlib3 + +TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::foo, a, b) +TOML11_DEFINE_CONVERSION_NON_INTRUSIVE(extlib3::bar, a, b, f) + +TEST_CASE("test_conversion_via_macro") +{ + { + const toml::value v(toml::table{{"a", 42}, {"b", "baz"}}); + + const auto foo = toml::get(v); + CHECK(foo.a == 42); + CHECK(foo.b == "baz"); + + const toml::value v2(foo); + CHECK(v2 == v); + } + { + const toml::ordered_value v(toml::ordered_table{ + {"a", 42}, {"b", "baz"} + }); + + const auto foo = toml::get(v); + CHECK(foo.a == 42); + CHECK(foo.b == "baz"); + + const toml::ordered_value v2(foo); + CHECK(v2 == v); + } + + // ----------------------------------------------------------------------- + + { + const toml::value v(toml::table{ + {"a", 42}, + {"b", "bar.b"}, + {"f", toml::table{{"a", 42}, {"b", "foo.b"}}} + }); + + const auto bar = toml::get(v); + CHECK(bar.a == 42); + CHECK(bar.b == "bar.b"); + CHECK(bar.f.a == 42); + CHECK(bar.f.b == "foo.b"); + + const toml::value v2(bar); + CHECK(v2 == v); + } + { + const toml::ordered_value v(toml::ordered_table{ + {"a", 42}, + {"b", "bar.b"}, + {"f", toml::ordered_table{{"a", 42}, {"b", "foo.b"}}} + }); + + const auto bar = toml::get(v); + CHECK(bar.a == 42); + CHECK(bar.b == "bar.b"); + CHECK(bar.f.a == 42); + CHECK(bar.f.b == "foo.b"); + + const toml::ordered_value v2(bar); + CHECK(v2 == v); + } +} +#endif // TOML11_WITHOUT_DEFINE_NON_INTRUSIVE diff --git a/tests/test_utility.cpp b/tests/test_utility.cpp index c67e3b8..bf6cfec 100644 --- a/tests/test_utility.cpp +++ b/tests/test_utility.cpp @@ -1,11 +1,17 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include -#include -#include +TEST_CASE("testing make_unique") +{ + const auto v = toml::cxx::make_unique>(std::size_t(2), "foobar"); + CHECK_EQ(v->size(), 2); + CHECK_EQ(v->at(0), "foobar"); + CHECK_EQ(v->at(1), "foobar"); +} -BOOST_AUTO_TEST_CASE(test_try_reserve) +TEST_CASE("testing try_reserve") { { // since BOOST_TEST is a macro, it cannot handle commas correctly. @@ -16,30 +22,149 @@ BOOST_AUTO_TEST_CASE(test_try_reserve) // this problem. using reservable_type = std::vector ; using nonreservable_type = std::array; - BOOST_TEST( toml::detail::has_reserve_method::value); - BOOST_TEST(!toml::detail::has_reserve_method::value); + CHECK_UNARY( toml::detail::has_reserve_method::value); + CHECK_UNARY(!toml::detail::has_reserve_method::value); } { std::vector v; - toml::try_reserve(v, 100); - BOOST_TEST(v.capacity() == 100u); + toml::detail::try_reserve(v, 100); + CHECK_EQ(v.capacity(), 100u); + } + { + std::array v; + toml::detail::try_reserve(v, 100); + CHECK_EQ(v.size(), 1); } } -BOOST_AUTO_TEST_CASE(test_concat_to_string) -{ - const std::string cat = toml::concat_to_string("foo", "bar", 42); - BOOST_TEST(cat == "foobar42"); -} - -BOOST_AUTO_TEST_CASE(test_from_string) +TEST_CASE("testing from_string") { { const std::string str("123"); - BOOST_TEST(toml::from_string(str, 0) == 123); + REQUIRE_UNARY(toml::detail::from_string(str).is_ok()); + CHECK_EQ(toml::detail::from_string(str).unwrap(), 123); } { const std::string str("01"); - BOOST_TEST(toml::from_string(str, 0) == 1); + REQUIRE_UNARY(toml::detail::from_string(str).is_ok()); + CHECK_EQ(toml::detail::from_string(str).unwrap(), 1); } } + +TEST_CASE("testing make_string") +{ + const auto s1 = toml::detail::make_string(3, 'a'); + CHECK_EQ(s1, "aaa"); + + const auto s2 = toml::detail::make_string(0, 'a'); + CHECK_EQ(s2, ""); + + const std::string s("bbb"); + + const auto s3 = toml::detail::make_string(s.begin(), s.end()); + CHECK_EQ(s3, "bbb"); + + const auto s4 = toml::detail::make_string(s.begin(), s.begin()); + CHECK_EQ(s4, ""); +} + +TEST_CASE("testing make_reverse_iterator") +{ + const std::vector v{1, 2, 3, 4, 5}; + + const auto iter = toml::cxx::make_reverse_iterator(v.begin()); + CHECK_EQ(iter, v.rend()); +} + +#if defined(TOML11_HAS_STD_SOURCE_LOCATION) || defined(TOML11_HAS_EXPERIMENTAL_SOURCE_LOCATION) || defined(TOML11_HAS_BUILTIN_FILE_LINE) +TEST_CASE("cxx::source_location") +{ + const std::string file = __FILE__; + const auto line = __LINE__; const auto loc = toml::cxx::source_location::current(); + + CHECK_EQ(file, loc.file_name()); + CHECK_EQ(line, loc.line()); +} +#endif + +TEST_CASE("cxx::optional") +{ + { + toml::cxx::optional v(42); + + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + + CHECK_EQ(v.value(), 42); + CHECK_EQ(v.value_or(6 * 9), 42); + + v.value() = 6 * 9; + CHECK_EQ(v.value(), 54); + } + { + toml::cxx::optional v; + + CHECK_UNARY_FALSE(static_cast(v)); + CHECK_UNARY_FALSE(v.has_value()); + CHECK_THROWS(v.value()); + CHECK_EQ(v.value_or(6 * 9), 54); + + v = 42; + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + CHECK_EQ(v.value(), 42); + } + { + toml::cxx::optional v(toml::cxx::make_nullopt()); + + CHECK_UNARY_FALSE(static_cast(v)); + CHECK_UNARY_FALSE(v.has_value()); + CHECK_THROWS(v.value()); + CHECK_EQ(v.value_or(6 * 9), 54); + + v = 42; + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + CHECK_EQ(v.value(), 42); + } + + { + toml::cxx::optional> v(std::vector{42}); + + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + + CHECK_EQ(v.value(), std::vector{42}); + CHECK_EQ(v.value_or(std::vector{6 * 9}), std::vector{42}); + + v.value() = std::vector{6 * 9}; + CHECK_EQ(v.value(), std::vector{54}); + } + { + toml::cxx::optional> v; + + CHECK_UNARY_FALSE(static_cast(v)); + CHECK_UNARY_FALSE(v.has_value()); + CHECK_THROWS(v.value()); + CHECK_EQ(v.value_or(std::vector{6 * 9}), std::vector{54}); + + v = std::vector{42}; + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + CHECK_EQ(v.value(), std::vector{42}); + } + { + toml::cxx::optional> v(toml::cxx::make_nullopt()); + + CHECK_UNARY_FALSE(static_cast(v)); + CHECK_UNARY_FALSE(v.has_value()); + CHECK_THROWS(v.value()); + CHECK_EQ(v.value_or(std::vector{6 * 9}), std::vector{54}); + + v = std::vector{42}; + CHECK_UNARY(static_cast(v)); + CHECK_UNARY(v.has_value()); + CHECK_EQ(v.value(), std::vector{42}); + } + +} diff --git a/tests/test_value.cpp b/tests/test_value.cpp index 296d343..df3d113 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -1,1015 +1,1199 @@ -#include +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" -#include "unit_test.hpp" +#include "utility.hpp" +#include + +#include #include -#include -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L -#include -#endif - - -BOOST_AUTO_TEST_CASE(test_value_boolean) +template +void test_is_type(const toml::basic_value& v, const toml::value_t t) { - toml::value v1(true); - toml::value v2(false); + CHECK_EQ(v.type(), t); - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v2.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v2.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); + if(t == toml::value_t::boolean ) {CHECK_UNARY(v.is_boolean() );} else {CHECK_UNARY_FALSE(v.is_boolean() );} + if(t == toml::value_t::integer ) {CHECK_UNARY(v.is_integer() );} else {CHECK_UNARY_FALSE(v.is_integer() );} + if(t == toml::value_t::floating ) {CHECK_UNARY(v.is_floating() );} else {CHECK_UNARY_FALSE(v.is_floating() );} + if(t == toml::value_t::string ) {CHECK_UNARY(v.is_string() );} else {CHECK_UNARY_FALSE(v.is_string() );} + if(t == toml::value_t::offset_datetime) {CHECK_UNARY(v.is_offset_datetime());} else {CHECK_UNARY_FALSE(v.is_offset_datetime());} + if(t == toml::value_t::local_datetime ) {CHECK_UNARY(v.is_local_datetime() );} else {CHECK_UNARY_FALSE(v.is_local_datetime() );} + if(t == toml::value_t::local_date ) {CHECK_UNARY(v.is_local_date() );} else {CHECK_UNARY_FALSE(v.is_local_date() );} + if(t == toml::value_t::local_time ) {CHECK_UNARY(v.is_local_time() );} else {CHECK_UNARY_FALSE(v.is_local_time() );} + if(t == toml::value_t::array ) {CHECK_UNARY(v.is_array() );} else {CHECK_UNARY_FALSE(v.is_array() );} + if(t == toml::value_t::table ) {CHECK_UNARY(v.is_table() );} else {CHECK_UNARY_FALSE(v.is_table() );} + if(t == toml::value_t::empty ) {CHECK_UNARY(v.is_empty() );} else {CHECK_UNARY_FALSE(v.is_empty() );} - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v2.cast() == false); - BOOST_TEST(v1.as_boolean() == true); - BOOST_TEST(v2.as_boolean() == false); - BOOST_TEST(v1.as_boolean(std::nothrow) == true); - BOOST_TEST(v2.as_boolean(std::nothrow) == false); + using value_type = toml::basic_value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; - v1 = false; - v2 = true; + if(t == toml::value_t::boolean ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::integer ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::floating ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::string ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::offset_datetime) {CHECK_UNARY(v.template is());} else {CHECK_UNARY_FALSE(v.template is());} + if(t == toml::value_t::local_datetime ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::local_date ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::local_time ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::array ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} + if(t == toml::value_t::table ) {CHECK_UNARY(v.template is() );} else {CHECK_UNARY_FALSE(v.template is() );} +// if(t == toml::value_t::empty ) {CHECK_UNARY(v.template is());} else {CHECK_UNARY_FALSE(v.template is() );} - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v2.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v2.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - - BOOST_TEST(v1.cast() == false); - BOOST_TEST(v2.cast() == true); - BOOST_TEST(v1.as_boolean() == false); - BOOST_TEST(v2.as_boolean() == true); - - toml::value v3(v1); - toml::value v4(v2); - BOOST_TEST(v3 == v1); - BOOST_TEST(v4 == v2); - - BOOST_TEST(v3.type() == toml::value_t::boolean); - BOOST_TEST(v4.type() == toml::value_t::boolean); - BOOST_TEST(v3.is(toml::value_t::boolean)); - BOOST_TEST(v4.is(toml::value_t::boolean)); - BOOST_TEST(v3.is()); - BOOST_TEST(v4.is()); - BOOST_TEST(v3.is_boolean()); - BOOST_TEST(v4.is_boolean()); - - BOOST_TEST(v3.cast() == false); - BOOST_TEST(v4.cast() == true); - BOOST_TEST(v3.as_boolean() == false); - BOOST_TEST(v4.as_boolean() == true); - - toml::value v5(std::move(v1)); - toml::value v6(std::move(v2)); - - BOOST_TEST(v5.type() == toml::value_t::boolean); - BOOST_TEST(v6.type() == toml::value_t::boolean); - BOOST_TEST(v5.is(toml::value_t::boolean)); - BOOST_TEST(v6.is(toml::value_t::boolean)); - BOOST_TEST(v5.is()); - BOOST_TEST(v6.is()); - BOOST_TEST(v3.is_boolean()); - BOOST_TEST(v4.is_boolean()); - - BOOST_TEST(v5.cast() == false); - BOOST_TEST(v6.cast() == true); - BOOST_TEST(v5.as_boolean() == false); - BOOST_TEST(v6.as_boolean() == true); - - v1 = 42; - v2 = 3.14; - - BOOST_TEST(v1.type() == toml::value_t::integer); - BOOST_TEST(v2.type() == toml::value_t::floating); - BOOST_TEST(v1.is(toml::value_t::integer)); - BOOST_TEST(v2.is(toml::value_t::floating)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_integer()); - BOOST_TEST(v2.is_floating()); - - BOOST_TEST(v1.cast() == 42); - BOOST_TEST(v2.cast() == 3.14); - BOOST_TEST(v1.as_integer() == 42); - BOOST_TEST(v2.as_floating() == 3.14); + return; } -BOOST_AUTO_TEST_CASE(test_value_integer) +template +void test_as_type_throws(toml::basic_value& v, const toml::value_t t) { - toml::value v1(-42); - toml::value v2(42u); + if(t != toml::value_t::boolean ) {CHECK_THROWS_AS(v.as_boolean() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::integer ) {CHECK_THROWS_AS(v.as_integer() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::floating ) {CHECK_THROWS_AS(v.as_floating() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::string ) {CHECK_THROWS_AS(v.as_string() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::offset_datetime) {CHECK_THROWS_AS(v.as_offset_datetime(), toml::type_error); CHECK_THROWS_AS(v.template as(), toml::type_error);} + if(t != toml::value_t::local_datetime ) {CHECK_THROWS_AS(v.as_local_datetime() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::local_date ) {CHECK_THROWS_AS(v.as_local_date() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::local_time ) {CHECK_THROWS_AS(v.as_local_time() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::array ) {CHECK_THROWS_AS(v.as_array() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} + if(t != toml::value_t::table ) {CHECK_THROWS_AS(v.as_table() , toml::type_error); CHECK_THROWS_AS(v.template as() , toml::type_error);} - BOOST_TEST(v1.type() == toml::value_t::integer); - BOOST_TEST(v2.type() == toml::value_t::integer); - BOOST_TEST(v1.is(toml::value_t::integer)); - BOOST_TEST(v2.is(toml::value_t::integer)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_integer()); - BOOST_TEST(v2.is_integer()); + if(t != toml::value_t::boolean ) {CHECK_THROWS_AS(as_const(v).as_boolean() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::integer ) {CHECK_THROWS_AS(as_const(v).as_integer() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::floating ) {CHECK_THROWS_AS(as_const(v).as_floating() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::string ) {CHECK_THROWS_AS(as_const(v).as_string() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::offset_datetime) {CHECK_THROWS_AS(as_const(v).as_offset_datetime(), toml::type_error); CHECK_THROWS_AS(as_const(v).template as(), toml::type_error);} + if(t != toml::value_t::local_datetime ) {CHECK_THROWS_AS(as_const(v).as_local_datetime() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::local_date ) {CHECK_THROWS_AS(as_const(v).as_local_date() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::local_time ) {CHECK_THROWS_AS(as_const(v).as_local_time() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::array ) {CHECK_THROWS_AS(as_const(v).as_array() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} + if(t != toml::value_t::table ) {CHECK_THROWS_AS(as_const(v).as_table() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as() , toml::type_error);} - BOOST_TEST(v1.cast() == -42); - BOOST_TEST(v2.cast() == 42u); - BOOST_TEST(v1.as_integer() == -42); - BOOST_TEST(v2.as_integer() == 42u); - BOOST_TEST(v1.as_integer(std::nothrow) == -42); - BOOST_TEST(v2.as_integer(std::nothrow) == 42u); - - v1 = 54; - v2 = -54; - - BOOST_TEST(v1.type() == toml::value_t::integer); - BOOST_TEST(v2.type() == toml::value_t::integer); - BOOST_TEST(v1.is(toml::value_t::integer)); - BOOST_TEST(v2.is(toml::value_t::integer)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_integer()); - BOOST_TEST(v2.is_integer()); - - BOOST_TEST(v1.cast() == 54); - BOOST_TEST(v2.cast() == -54); - BOOST_TEST(v1.as_integer() == 54); - BOOST_TEST(v2.as_integer() == -54); - - toml::value v3(v1); - toml::value v4(v2); - BOOST_TEST(v3 == v1); - BOOST_TEST(v4 == v2); - - BOOST_TEST(v3.type() == toml::value_t::integer); - BOOST_TEST(v4.type() == toml::value_t::integer); - BOOST_TEST(v3.is(toml::value_t::integer)); - BOOST_TEST(v4.is(toml::value_t::integer)); - BOOST_TEST(v3.is()); - BOOST_TEST(v4.is()); - BOOST_TEST(v3.is_integer()); - BOOST_TEST(v4.is_integer()); - - BOOST_TEST(v3.cast() == 54); - BOOST_TEST(v4.cast() == -54); - BOOST_TEST(v3.as_integer() == 54); - BOOST_TEST(v4.as_integer() == -54); - - toml::value v5(std::move(v1)); - toml::value v6(std::move(v2)); - - BOOST_TEST(v5.type() == toml::value_t::integer); - BOOST_TEST(v6.type() == toml::value_t::integer); - BOOST_TEST(v5.is(toml::value_t::integer)); - BOOST_TEST(v6.is(toml::value_t::integer)); - BOOST_TEST(v5.is()); - BOOST_TEST(v6.is()); - BOOST_TEST(v5.is_integer()); - BOOST_TEST(v6.is_integer()); - - BOOST_TEST(v5.cast() == 54); - BOOST_TEST(v6.cast() == -54); - BOOST_TEST(v5.as_integer() == 54); - BOOST_TEST(v6.as_integer() == -54); - - v1 = true; - v2 = false; - - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v2.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v2.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v2.cast() == false); - BOOST_TEST(v1.as_boolean() == true); - BOOST_TEST(v2.as_boolean() == false); + return; } -BOOST_AUTO_TEST_CASE(test_value_float) +template +struct as_type_tester; +#ifndef TOML11_TEST_DEFINE_AS_TYPE_TESTER +#define TOML11_TEST_DEFINE_AS_TYPE_TESTER(ty) \ + template<> \ + struct as_type_tester \ + { \ + template \ + static void test(toml::basic_value& v, const T& eq, const T& ne) \ + { \ + CHECK_EQ(v.as_ ## ty(), eq); \ + CHECK_NE(v.as_ ## ty(), ne); \ + CHECK_EQ(as_const(v).as_ ## ty(), eq); \ + CHECK_NE(as_const(v).as_ ## ty(), ne); \ + if(v.type() == toml::value_t::ty) \ + { \ + CHECK_EQ(v.as_ ## ty(std::nothrow), eq); \ + CHECK_NE(v.as_ ## ty(std::nothrow), ne); \ + CHECK_EQ(as_const(v).as_ ## ty(std::nothrow), eq); \ + CHECK_NE(as_const(v).as_ ## ty(std::nothrow), ne); \ + } \ + } \ + }; /**/ +#endif // TOML11_TEST_DEFINE_AS_TYPE_TESTER +TOML11_TEST_DEFINE_AS_TYPE_TESTER(boolean ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(integer ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(floating ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(string ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(offset_datetime) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(local_datetime ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(local_date ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(local_time ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(array ) +TOML11_TEST_DEFINE_AS_TYPE_TESTER(table ) +#undef TOML11_TEST_DEFINE_AS_TYPE_TESTER + +template +void test_as_type(toml::basic_value& v, const T& eq_, const U& ne_) { - toml::value v1(3.14); - toml::value v2(3.14f); + using elem_type = toml::detail::enum_to_type_t>; + const elem_type eq(eq_); + const elem_type ne(ne_); - BOOST_TEST(v1.type() == toml::value_t::floating); - BOOST_TEST(v2.type() == toml::value_t::floating); - BOOST_TEST(v1.is(toml::value_t::floating)); - BOOST_TEST(v2.is(toml::value_t::floating)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_floating()); - BOOST_TEST(v2.is_floating()); + as_type_tester::test(v, eq, ne); - BOOST_TEST(v1.cast() == 3.14); - BOOST_TEST(v2.cast() == 3.14, - boost::test_tools::tolerance(1e-2)); - BOOST_TEST(v1.as_floating() == 3.14); - BOOST_TEST(v2.as_floating() == 3.14, - boost::test_tools::tolerance(1e-2)); - BOOST_TEST(v1.as_floating(std::nothrow) == 3.14); - BOOST_TEST(v2.as_floating(std::nothrow) == 3.14, - boost::test_tools::tolerance(1e-2)); + // as + CHECK_EQ(v.template as(), eq); + CHECK_NE(v.template as(), ne); - v1 = 2.718f; - v2 = 2.718; + CHECK_EQ(as_const(v).template as(), eq); + CHECK_NE(as_const(v).template as(), ne); - BOOST_TEST(v1.type() == toml::value_t::floating); - BOOST_TEST(v2.type() == toml::value_t::floating); - BOOST_TEST(v1.is(toml::value_t::floating)); - BOOST_TEST(v2.is(toml::value_t::floating)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_floating()); - BOOST_TEST(v2.is_floating()); + if(v.type() == VT) + { + CHECK_EQ(v.template as(std::nothrow), eq); + CHECK_NE(v.template as(std::nothrow), ne); - BOOST_TEST(v1.cast() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v2.cast() == 2.718); - BOOST_TEST(v1.as_floating() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v2.as_floating() == 2.718); - - toml::value v3(v1); - toml::value v4(v2); - BOOST_TEST(v3 == v1); - BOOST_TEST(v4 == v2); - - BOOST_TEST(v3.type() == toml::value_t::floating); - BOOST_TEST(v4.type() == toml::value_t::floating); - BOOST_TEST(v3.is(toml::value_t::floating)); - BOOST_TEST(v4.is(toml::value_t::floating)); - BOOST_TEST(v3.is()); - BOOST_TEST(v4.is()); - BOOST_TEST(v3.is_floating()); - BOOST_TEST(v4.is_floating()); - - BOOST_TEST(v3.cast() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v4.cast() == 2.718); - BOOST_TEST(v3.as_floating() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v4.as_floating() == 2.718); - - toml::value v5(std::move(v1)); - toml::value v6(std::move(v2)); - - BOOST_TEST(v5.type() == toml::value_t::floating); - BOOST_TEST(v6.type() == toml::value_t::floating); - BOOST_TEST(v5.is(toml::value_t::floating)); - BOOST_TEST(v6.is(toml::value_t::floating)); - BOOST_TEST(v5.is()); - BOOST_TEST(v6.is()); - BOOST_TEST(v5.is_floating()); - BOOST_TEST(v6.is_floating()); - - BOOST_TEST(v5.cast() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v6.cast() == 2.718); - BOOST_TEST(v5.as_floating() == 2.718, - boost::test_tools::tolerance(1e-3)); - BOOST_TEST(v6.as_floating() == 2.718); - - v1 = true; - v2 = false; - - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v2.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v2.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v2.cast() == false); - BOOST_TEST(v1.as_boolean() == true); - BOOST_TEST(v2.as_boolean() == false); + CHECK_EQ(as_const(v).template as(std::nothrow), eq); + CHECK_NE(as_const(v).template as(std::nothrow), ne); + } + return; } -BOOST_AUTO_TEST_CASE(test_value_string) +template +void test_as_type_fmt_throws(toml::basic_value& v, const toml::value_t t) { - toml::value v1(std::string("foo")); - toml::value v2(std::string("foo"), toml::string_t::literal); - toml::value v3("foo"); + if(t != toml::value_t::boolean ) {CHECK_THROWS_AS(v.as_boolean_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::integer ) {CHECK_THROWS_AS(v.as_integer_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::floating ) {CHECK_THROWS_AS(v.as_floating_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::string ) {CHECK_THROWS_AS(v.as_string_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::offset_datetime) {CHECK_THROWS_AS(v.as_offset_datetime_fmt(), toml::type_error); CHECK_THROWS_AS(v.template as_fmt(), toml::type_error);} + if(t != toml::value_t::local_datetime ) {CHECK_THROWS_AS(v.as_local_datetime_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::local_date ) {CHECK_THROWS_AS(v.as_local_date_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::local_time ) {CHECK_THROWS_AS(v.as_local_time_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::array ) {CHECK_THROWS_AS(v.as_array_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} + if(t != toml::value_t::table ) {CHECK_THROWS_AS(v.as_table_fmt() , toml::type_error); CHECK_THROWS_AS(v.template as_fmt() , toml::type_error);} - BOOST_TEST(v1.type() == toml::value_t::string); - BOOST_TEST(v2.type() == toml::value_t::string); - BOOST_TEST(v3.type() == toml::value_t::string); - BOOST_TEST(v1.is(toml::value_t::string)); - BOOST_TEST(v2.is(toml::value_t::string)); - BOOST_TEST(v3.is(toml::value_t::string)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v3.is()); - BOOST_TEST(v1.is_string()); - BOOST_TEST(v2.is_string()); - BOOST_TEST(v3.is_string()); + if(t != toml::value_t::boolean ) {CHECK_THROWS_AS(as_const(v).as_boolean_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::integer ) {CHECK_THROWS_AS(as_const(v).as_integer_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::floating ) {CHECK_THROWS_AS(as_const(v).as_floating_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::string ) {CHECK_THROWS_AS(as_const(v).as_string_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::offset_datetime) {CHECK_THROWS_AS(as_const(v).as_offset_datetime_fmt(), toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt(), toml::type_error);} + if(t != toml::value_t::local_datetime ) {CHECK_THROWS_AS(as_const(v).as_local_datetime_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::local_date ) {CHECK_THROWS_AS(as_const(v).as_local_date_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::local_time ) {CHECK_THROWS_AS(as_const(v).as_local_time_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::array ) {CHECK_THROWS_AS(as_const(v).as_array_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} + if(t != toml::value_t::table ) {CHECK_THROWS_AS(as_const(v).as_table_fmt() , toml::type_error); CHECK_THROWS_AS(as_const(v).template as_fmt() , toml::type_error);} - BOOST_TEST(v1.cast() == "foo"); - BOOST_TEST(v2.cast() == "foo"); - BOOST_TEST(v3.cast() == "foo"); - BOOST_TEST(v1.as_string() == "foo"); - BOOST_TEST(v2.as_string() == "foo"); - BOOST_TEST(v3.as_string() == "foo"); - BOOST_TEST(v1.as_string(std::nothrow) == "foo"); - BOOST_TEST(v2.as_string(std::nothrow) == "foo"); - BOOST_TEST(v3.as_string(std::nothrow) == "foo"); - - v1 = "bar"; - v2 = "bar"; - v3 = "bar"; - - BOOST_TEST(v1.type() == toml::value_t::string); - BOOST_TEST(v2.type() == toml::value_t::string); - BOOST_TEST(v3.type() == toml::value_t::string); - BOOST_TEST(v1.is(toml::value_t::string)); - BOOST_TEST(v2.is(toml::value_t::string)); - BOOST_TEST(v3.is(toml::value_t::string)); - BOOST_TEST(v1.is_string()); - BOOST_TEST(v2.is_string()); - BOOST_TEST(v3.is_string()); - - BOOST_TEST(v1.cast() == "bar"); - BOOST_TEST(v2.cast() == "bar"); - BOOST_TEST(v3.cast() == "bar"); - BOOST_TEST(v1.as_string() == "bar"); - BOOST_TEST(v2.as_string() == "bar"); - BOOST_TEST(v3.as_string() == "bar"); - - - toml::value v4(v1); - toml::value v5(v2); - toml::value v6(v3); - BOOST_TEST(v4 == v1); - BOOST_TEST(v5 == v2); - BOOST_TEST(v6 == v3); - - BOOST_TEST(v4.type() == toml::value_t::string); - BOOST_TEST(v5.type() == toml::value_t::string); - BOOST_TEST(v6.type() == toml::value_t::string); - BOOST_TEST(v4.is(toml::value_t::string)); - BOOST_TEST(v5.is(toml::value_t::string)); - BOOST_TEST(v6.is(toml::value_t::string)); - BOOST_TEST(v4.is()); - BOOST_TEST(v5.is()); - BOOST_TEST(v6.is()); - BOOST_TEST(v4.is_string()); - BOOST_TEST(v5.is_string()); - BOOST_TEST(v6.is_string()); - - BOOST_TEST(v4.cast() == "bar"); - BOOST_TEST(v5.cast() == "bar"); - BOOST_TEST(v6.cast() == "bar"); - BOOST_TEST(v4.as_string() == "bar"); - BOOST_TEST(v5.as_string() == "bar"); - BOOST_TEST(v6.as_string() == "bar"); - - - v4.cast().str.at(2) = 'z'; - v5.cast().str.at(2) = 'z'; - v6.cast().str.at(2) = 'z'; - - BOOST_TEST(v4.type() == toml::value_t::string); - BOOST_TEST(v5.type() == toml::value_t::string); - BOOST_TEST(v6.type() == toml::value_t::string); - BOOST_TEST(v4.is(toml::value_t::string)); - BOOST_TEST(v5.is(toml::value_t::string)); - BOOST_TEST(v6.is(toml::value_t::string)); - BOOST_TEST(v4.is()); - BOOST_TEST(v5.is()); - BOOST_TEST(v6.is()); - BOOST_TEST(v4.is_string()); - BOOST_TEST(v5.is_string()); - BOOST_TEST(v6.is_string()); - - BOOST_TEST(v4.as_string() == "baz"); - BOOST_TEST(v5.as_string() == "baz"); - BOOST_TEST(v6.as_string() == "baz"); - - v1 = true; - v2 = true; - v3 = true; - - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v2.type() == toml::value_t::boolean); - BOOST_TEST(v3.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v2.is(toml::value_t::boolean)); - BOOST_TEST(v3.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v3.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v2.is_boolean()); - BOOST_TEST(v3.is_boolean()); - - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v2.cast() == true); - BOOST_TEST(v3.cast() == true); - BOOST_TEST(v1.as_boolean() == true); - BOOST_TEST(v2.as_boolean() == true); - BOOST_TEST(v3.as_boolean() == true); - -#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L - std::string_view sv = "foo"; - - toml::value v7(sv); - toml::value v8(sv, toml::string_t::literal); - - BOOST_TEST(v7.type() == toml::value_t::string); - BOOST_TEST(v8.type() == toml::value_t::string); - BOOST_TEST(v7.is(toml::value_t::string)); - BOOST_TEST(v8.is(toml::value_t::string)); - BOOST_TEST(v7.is()); - BOOST_TEST(v8.is()); - BOOST_TEST(v7.is_string()); - BOOST_TEST(v8.is_string()); - - BOOST_TEST(v7.cast() == "foo"); - BOOST_TEST(v8.cast() == "foo"); -#endif + return; } -BOOST_AUTO_TEST_CASE(test_value_local_date) +template +struct as_type_fmt_tester; +#ifndef TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER +#define TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(ty) \ + template<> \ + struct as_type_fmt_tester \ + { \ + template \ + static void test(toml::basic_value& v, const FMT& fmt) \ + { \ + CHECK_EQ( v .as_ ## ty ## _fmt(), fmt); \ + CHECK_EQ(as_const(v).as_ ## ty ## _fmt(), fmt); \ + if(v.type() == toml::value_t::ty) \ + { \ + CHECK_EQ( v .as_ ## ty ## _fmt(std::nothrow), fmt); \ + CHECK_EQ(as_const(v).as_ ## ty ## _fmt(std::nothrow), fmt); \ + } \ + } \ + }; /**/ +#endif // TOML11_TEST_DEFINE_AS_TYPE_TESTER +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(boolean ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(integer ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(floating ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(string ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(offset_datetime) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(local_datetime ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(local_date ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(local_time ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(array ) +TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER(table ) +#undef TOML11_TEST_DEFINE_AS_TYPE_FMT_TESTER + +template +void test_as_type_fmt(toml::basic_value& v, const FMT& fmt) { - toml::value v1(toml::local_date(2018, toml::month_t::Jan, 31)); + as_type_fmt_tester::test(v, fmt); - BOOST_TEST(v1.type() == toml::value_t::local_date); - BOOST_TEST(v1.is(toml::value_t::local_date)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_local_date()); - - BOOST_TEST(v1.cast() == - toml::local_date(2018, toml::month_t::Jan, 31)); - BOOST_TEST(v1.as_local_date() == - toml::local_date(2018, toml::month_t::Jan, 31)); - BOOST_TEST(v1.as_local_date(std::nothrow) == - toml::local_date(2018, toml::month_t::Jan, 31)); - - v1 = toml::local_date(2018, toml::month_t::Apr, 1); - - BOOST_TEST(v1.type() == toml::value_t::local_date); - BOOST_TEST(v1.is(toml::value_t::local_date)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_local_date()); - - BOOST_TEST(v1.cast() == - toml::local_date(2018, toml::month_t::Apr, 1)); - BOOST_TEST(v1.as_local_date() == - toml::local_date(2018, toml::month_t::Apr, 1)); - - toml::value v2(v1); - BOOST_TEST(v2 == v1); - - BOOST_TEST(v2.type() == toml::value_t::local_date); - BOOST_TEST(v2.is(toml::value_t::local_date)); - BOOST_TEST(v2.is()); - BOOST_TEST(v2.is_local_date()); - - BOOST_TEST(v2.cast() == - toml::local_date(2018, toml::month_t::Apr, 1)); - BOOST_TEST(v2.as_local_date() == - toml::local_date(2018, toml::month_t::Apr, 1)); - - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); + // as + CHECK_EQ(v .template as_fmt(), fmt); + CHECK_EQ(as_const(v).template as_fmt(), fmt); + if(v.type() == VT) + { + CHECK_EQ(v .template as_fmt(std::nothrow), fmt); + CHECK_EQ(as_const(v).template as_fmt(std::nothrow), fmt); + } + return; } -BOOST_AUTO_TEST_CASE(test_value_local_time) +template +void test_ctors(T eq, U ne, FMT fmt) { - toml::value v1(toml::local_time(12, 30, 45)); - toml::value v2(std::chrono::hours(12) + std::chrono::minutes(30) + - std::chrono::seconds(45)); + { + toml::value x(eq); - BOOST_TEST(v1.type() == toml::value_t::local_time); - BOOST_TEST(v2.type() == toml::value_t::local_time); - BOOST_TEST(v1.is(toml::value_t::local_time)); - BOOST_TEST(v2.is(toml::value_t::local_time)); - BOOST_TEST(v1.is()); - BOOST_TEST(v2.is()); - BOOST_TEST(v1.is_local_time()); - BOOST_TEST(v2.is_local_time()); + test_is_type (x, TYPE); + test_as_type_throws (x, TYPE); + test_as_type_fmt_throws(x, TYPE); - BOOST_TEST(v1.cast() == - toml::local_time(12, 30, 45)); - BOOST_TEST(v1.as_local_time() == - toml::local_time(12, 30, 45)); + test_as_type(x, eq, ne); - BOOST_TEST(v2.cast() == - toml::local_time(12, 30, 45)); - BOOST_TEST(v2.as_local_time() == - toml::local_time(12, 30, 45)); + CHECK_EQ(x.comments().size(), 0); + CHECK_EQ(x.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_with_comments(eq, std::vector{"foo", "bar"}); - BOOST_TEST(v1.cast() == - v2.cast()); - BOOST_TEST(v1.as_local_time() == - v2.as_local_time()); - BOOST_TEST(v1.as_local_time(std::nothrow) == - v2.as_local_time(std::nothrow)); + test_is_type (x_with_comments, TYPE); + test_as_type_throws (x_with_comments, TYPE); + test_as_type_fmt_throws(x_with_comments, TYPE); - v1 = toml::local_time(1, 30, 0, /*ms*/ 100, /*us*/ 0); + test_as_type(x_with_comments, eq, ne); - BOOST_TEST(v1.type() == toml::value_t::local_time); - BOOST_TEST(v1.is(toml::value_t::local_time)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_local_time()); - BOOST_TEST(v1.cast() == - toml::local_time(1, 30, 0, 100, 0)); - BOOST_TEST(v1.as_local_time() == - toml::local_time(1, 30, 0, 100, 0)); + CHECK_EQ(x_with_comments.comments().size(), 2); + CHECK_EQ(x_with_comments.comments().at(0), "foo"); + CHECK_EQ(x_with_comments.comments().at(1), "bar"); - toml::value v3(v1); - BOOST_TEST(v3 == v1); + CHECK_EQ(x_with_comments.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_with_format(eq, fmt); - BOOST_TEST(v3.type() == toml::value_t::local_time); - BOOST_TEST(v3.is(toml::value_t::local_time)); - BOOST_TEST(v3.is()); - BOOST_TEST(v3.is_local_time()); + test_is_type (x_with_format, TYPE); + test_as_type_throws (x_with_format, TYPE); + test_as_type_fmt_throws(x_with_format, TYPE); - BOOST_TEST(v3.cast() == - toml::local_time(1, 30, 0, 100, 0)); - BOOST_TEST(v3.as_local_time() == - toml::local_time(1, 30, 0, 100, 0)); + test_as_type (x_with_format, eq, ne); + test_as_type_fmt(x_with_format, fmt); - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); + CHECK_EQ(x_with_format.comments().size(), 0); + CHECK_EQ(x_with_format.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_with_com_fmt(eq, fmt, + std::vector{"foo", "bar"}); + + test_is_type (x_with_com_fmt, TYPE); + test_as_type_throws (x_with_com_fmt, TYPE); + test_as_type_fmt_throws(x_with_com_fmt, TYPE); + + test_as_type (x_with_com_fmt, eq, ne); + test_as_type_fmt(x_with_com_fmt, fmt); + + CHECK_EQ(x_with_com_fmt.comments().size(), 2); + CHECK_EQ(x_with_com_fmt.comments().at(0), "foo"); + CHECK_EQ(x_with_com_fmt.comments().at(1), "bar"); + + CHECK_EQ(x_with_com_fmt.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_assign(ne, fmt); + x_assign = eq; + + test_is_type (x_assign, TYPE); + test_as_type_throws (x_assign, TYPE); + test_as_type_fmt_throws(x_assign, TYPE); + + test_as_type (x_assign, eq, ne); + test_as_type_fmt(x_assign, fmt); + + CHECK_EQ(x_assign.comments().size(), 0); + CHECK_EQ(x_assign.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_assign_different_type(true); + x_assign_different_type = eq; + + test_is_type (x_assign_different_type, TYPE); + test_as_type_throws (x_assign_different_type, TYPE); + test_as_type_fmt_throws(x_assign_different_type, TYPE); + + test_as_type(x_assign_different_type, eq, ne); + + CHECK_EQ(x_assign_different_type.comments().size(), 0); + CHECK_EQ(x_assign_different_type.location().is_ok(), false); + } +} +template +void test_copy_move_ctors(T eq, U ne, FMT fmt) +{ + { + toml::value x_original(eq, fmt, std::vector{"foo", "bar"}); + toml::value x_copy(x_original); + + test_is_type (x_copy, TYPE); + test_as_type_throws (x_copy, TYPE); + test_as_type_fmt_throws(x_copy, TYPE); + + test_as_type (x_copy, eq, ne); + test_as_type_fmt(x_copy, fmt); + + CHECK_EQ(x_copy.comments().size(), 2); + CHECK_EQ(x_copy.comments().at(0), "foo"); + CHECK_EQ(x_copy.comments().at(1), "bar"); + + CHECK_EQ(x_copy.location().is_ok(), false); + + x_copy = 0; // reset with integer 0 + x_copy = x_original; + + test_is_type (x_copy, TYPE); + test_as_type_throws (x_copy, TYPE); + test_as_type_fmt_throws(x_copy, TYPE); + + test_as_type (x_copy, eq, ne); + test_as_type_fmt(x_copy, fmt); + + CHECK_EQ(x_copy.comments().size(), 2); + CHECK_EQ(x_copy.comments().at(0), "foo"); + CHECK_EQ(x_copy.comments().at(1), "bar"); + + CHECK_EQ(x_copy.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_original(eq, fmt, std::vector{"foo", "bar"}); + toml::value x_move(std::move(x_original)); + + test_is_type (x_move, TYPE); + test_as_type_throws (x_move, TYPE); + test_as_type_fmt_throws(x_move, TYPE); + + test_as_type (x_move, eq, ne); + test_as_type_fmt(x_move, fmt); + + CHECK_EQ(x_move.comments().size(), 2); + CHECK_EQ(x_move.comments().at(0), "foo"); + CHECK_EQ(x_move.comments().at(1), "bar"); + + CHECK_EQ(x_move.location().is_ok(), false); + + x_move = 0; // reset with integer 0 + + toml::value x_original2(eq, fmt, std::vector{"foo", "bar"}); + x_move = std::move(x_original2); + + test_is_type (x_move, TYPE); + test_as_type_throws (x_move, TYPE); + test_as_type_fmt_throws(x_move, TYPE); + + test_as_type (x_move, eq, ne); + test_as_type_fmt(x_move, fmt); + + CHECK_EQ(x_move.comments().size(), 2); + CHECK_EQ(x_move.comments().at(0), "foo"); + CHECK_EQ(x_move.comments().at(1), "bar"); + + CHECK_EQ(x_move.location().is_ok(), false); + } } -BOOST_AUTO_TEST_CASE(test_value_local_datetime) +TEST_CASE("testing default constructor (empty)") { - toml::value v1(toml::local_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45) - )); + toml::value v; - BOOST_TEST(v1.type() == toml::value_t::local_datetime); - BOOST_TEST(v1.is(toml::value_t::local_datetime)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_local_datetime()); + test_is_type(v, toml::value_t::empty); - BOOST_TEST(v1.cast() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45))); - BOOST_TEST(v1.as_local_datetime() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45))); - BOOST_TEST(v1.as_local_datetime(std::nothrow) == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45))); + CHECK_EQ(v.comments().size(), 0); + CHECK_EQ(v.location().is_ok(), false); - - v1 = toml::local_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30)); - - BOOST_TEST(v1.type() == toml::value_t::local_datetime); - BOOST_TEST(v1.is(toml::value_t::local_datetime)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_local_datetime()); - - BOOST_TEST(v1.cast() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30))); - BOOST_TEST(v1.as_local_datetime() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30))); - - toml::value v2(v1); - BOOST_TEST(v2 == v1); - - BOOST_TEST(v2.type() == toml::value_t::local_datetime); - BOOST_TEST(v2.is(toml::value_t::local_datetime)); - BOOST_TEST(v2.is()); - BOOST_TEST(v2.is_local_datetime()); - - BOOST_TEST(v2.cast() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30))); - BOOST_TEST(v2.as_local_datetime() == - toml::local_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30))); - - - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); -} - -BOOST_AUTO_TEST_CASE(test_value_offset_datetime) -{ - toml::value v1(toml::offset_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45), - toml::time_offset(9, 0) - )); - - BOOST_TEST(v1.type() == toml::value_t::offset_datetime); - BOOST_TEST(v1.is(toml::value_t::offset_datetime)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_offset_datetime()); - - BOOST_TEST(v1.cast() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45), - toml::time_offset(9, 0) - )); - BOOST_TEST(v1.as_offset_datetime() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45), - toml::time_offset(9, 0) - )); - BOOST_TEST(v1.as_offset_datetime(std::nothrow) == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Jan, 31), - toml::local_time(12, 30, 45), - toml::time_offset(9, 0) - )); - - - v1 = toml::offset_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30), - toml::time_offset(9, 0)); - - BOOST_TEST(v1.type() == toml::value_t::offset_datetime); - BOOST_TEST(v1.is(toml::value_t::offset_datetime)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_offset_datetime()); - - BOOST_TEST(v1.cast() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30), - toml::time_offset(9, 0))); - BOOST_TEST(v1.as_offset_datetime() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30), - toml::time_offset(9, 0))); - - - toml::value v2(v1); - BOOST_TEST(v2 == v1); - - BOOST_TEST(v2.type() == toml::value_t::offset_datetime); - BOOST_TEST(v2.is(toml::value_t::offset_datetime)); - BOOST_TEST(v2.is()); - BOOST_TEST(v2.is_offset_datetime()); - - BOOST_TEST(v2.cast() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30), - toml::time_offset(9, 0))); - BOOST_TEST(v2.as_offset_datetime() == - toml::offset_datetime( - toml::local_date(2018, toml::month_t::Apr, 1), - toml::local_time(1, 15, 30), - toml::time_offset(9, 0))); - - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); -} - -BOOST_AUTO_TEST_CASE(test_value_array) -{ - std::vector v{1,2,3,4,5}; toml::value v1(v); - toml::value v2{6,7,8,9,0}; - BOOST_TEST(v1.type() == toml::value_t::array); - BOOST_TEST(v1.is(toml::value_t::array)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_array()); + test_is_type(v1, toml::value_t::empty); - BOOST_TEST(v2.type() == toml::value_t::array); - BOOST_TEST(v2.is(toml::value_t::array)); - BOOST_TEST(v2.is()); - BOOST_TEST(v2.is_array()); + CHECK_EQ(v1.comments().size(), 0); + CHECK_EQ(v1.location().is_ok(), false); - BOOST_TEST(v1.cast().at(0).cast() == 1); - BOOST_TEST(v1.cast().at(1).cast() == 2); - BOOST_TEST(v1.cast().at(2).cast() == 3); - BOOST_TEST(v1.cast().at(3).cast() == 4); - BOOST_TEST(v1.cast().at(4).cast() == 5); - BOOST_TEST(v1.as_array().at(0).as_integer() == 1); - BOOST_TEST(v1.as_array().at(1).as_integer() == 2); - BOOST_TEST(v1.as_array().at(2).as_integer() == 3); - BOOST_TEST(v1.as_array().at(3).as_integer() == 4); - BOOST_TEST(v1.as_array().at(4).as_integer() == 5); - BOOST_TEST(v1.as_array(std::nothrow).at(0).as_integer() == 1); - BOOST_TEST(v1.as_array(std::nothrow).at(1).as_integer() == 2); - BOOST_TEST(v1.as_array(std::nothrow).at(2).as_integer() == 3); - BOOST_TEST(v1.as_array(std::nothrow).at(3).as_integer() == 4); - BOOST_TEST(v1.as_array(std::nothrow).at(4).as_integer() == 5); + toml::value v2(std::move(v)); - BOOST_TEST(v2.cast().at(0).cast() == 6); - BOOST_TEST(v2.cast().at(1).cast() == 7); - BOOST_TEST(v2.cast().at(2).cast() == 8); - BOOST_TEST(v2.cast().at(3).cast() == 9); - BOOST_TEST(v2.cast().at(4).cast() == 0); + test_is_type(v2, toml::value_t::empty); - v1 = {6,7,8,9,0}; - v2 = v; + CHECK_EQ(v2.comments().size(), 0); + CHECK_EQ(v2.location().is_ok(), false); - BOOST_TEST(v1.type() == toml::value_t::array); - BOOST_TEST(v1.is(toml::value_t::array)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_array()); + toml::value v3(std::move(v), std::vector{"foo", "bar"}); - BOOST_TEST(v2.type() == toml::value_t::array); - BOOST_TEST(v2.is(toml::value_t::array)); - BOOST_TEST(v2.is()); - BOOST_TEST(v2.is_array()); + test_is_type(v3, toml::value_t::empty); - BOOST_TEST(v1.cast().at(0).cast() == 6); - BOOST_TEST(v1.cast().at(1).cast() == 7); - BOOST_TEST(v1.cast().at(2).cast() == 8); - BOOST_TEST(v1.cast().at(3).cast() == 9); - BOOST_TEST(v1.cast().at(4).cast() == 0); - BOOST_TEST(v1.as_array().at(0).as_integer() == 6); - BOOST_TEST(v1.as_array().at(1).as_integer() == 7); - BOOST_TEST(v1.as_array().at(2).as_integer() == 8); - BOOST_TEST(v1.as_array().at(3).as_integer() == 9); - BOOST_TEST(v1.as_array().at(4).as_integer() == 0); - - - BOOST_TEST(v2.cast().at(0).cast() == 1); - BOOST_TEST(v2.cast().at(1).cast() == 2); - BOOST_TEST(v2.cast().at(2).cast() == 3); - BOOST_TEST(v2.cast().at(3).cast() == 4); - BOOST_TEST(v2.cast().at(4).cast() == 5); - BOOST_TEST(v2.as_array().at(0).as_integer() == 1); - BOOST_TEST(v2.as_array().at(1).as_integer() == 2); - BOOST_TEST(v2.as_array().at(2).as_integer() == 3); - BOOST_TEST(v2.as_array().at(3).as_integer() == 4); - BOOST_TEST(v2.as_array().at(4).as_integer() == 5); - - - toml::value v3(v1); - BOOST_TEST(v3 == v1); - - BOOST_TEST(v3.type() == toml::value_t::array); - BOOST_TEST(v3.is(toml::value_t::array)); - BOOST_TEST(v3.is()); - BOOST_TEST(v3.is_array()); - - BOOST_TEST(v3.cast().at(0).cast() == 6); - BOOST_TEST(v3.cast().at(1).cast() == 7); - BOOST_TEST(v3.cast().at(2).cast() == 8); - BOOST_TEST(v3.cast().at(3).cast() == 9); - BOOST_TEST(v3.cast().at(4).cast() == 0); - BOOST_TEST(v3.as_array().at(0).as_integer() == 6); - BOOST_TEST(v3.as_array().at(1).as_integer() == 7); - BOOST_TEST(v3.as_array().at(2).as_integer() == 8); - BOOST_TEST(v3.as_array().at(3).as_integer() == 9); - BOOST_TEST(v3.as_array().at(4).as_integer() == 0); - - - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); + CHECK_EQ(v3.comments().size(), 2); + CHECK_EQ(v3.comments().at(0), "foo"); + CHECK_EQ(v3.comments().at(1), "bar"); + CHECK_EQ(v3.location().is_ok(), false); } -BOOST_AUTO_TEST_CASE(test_value_table) +TEST_CASE("testing constructor (boolean)") { - toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + toml::boolean_format_info fmt; - BOOST_TEST(v1.type() == toml::value_t::table); - BOOST_TEST(v1.is(toml::value_t::table)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_table()); + const bool eq = true; + const bool ne = false; - BOOST_TEST(v1.cast().at("foo").cast() == 42); - BOOST_TEST(v1.cast().at("bar").cast() == 3.14); - BOOST_TEST(v1.cast().at("baz").cast().str == "qux"); - BOOST_TEST(v1.as_table().at("foo").as_integer() == 42); - BOOST_TEST(v1.as_table().at("bar").as_floating() == 3.14); - BOOST_TEST(v1.as_table().at("baz").as_string().str == "qux"); - BOOST_TEST(v1.as_table(std::nothrow).at("foo").as_integer() == 42); - BOOST_TEST(v1.as_table(std::nothrow).at("bar").as_floating() == 3.14); - BOOST_TEST(v1.as_table(std::nothrow).at("baz").as_string().str == "qux"); - - v1 = {{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; - - BOOST_TEST(v1.type() == toml::value_t::table); - BOOST_TEST(v1.is(toml::value_t::table)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_table()); - - BOOST_TEST(v1.cast().at("foo").cast() == 2.71); - BOOST_TEST(v1.cast().at("bar").cast() == 54); - BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); - BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); - BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); - BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); - - v1 = toml::table{{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; - - BOOST_TEST(v1.type() == toml::value_t::table); - BOOST_TEST(v1.is(toml::value_t::table)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_table()); - - BOOST_TEST(v1.cast().at("foo").cast() == 2.71); - BOOST_TEST(v1.cast().at("bar").cast() == 54); - BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); - BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); - BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); - BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); - - toml::value v3(v1); - BOOST_TEST(v3 == v1); - - BOOST_TEST(v3.type() == toml::value_t::table); - BOOST_TEST(v3.is(toml::value_t::table)); - BOOST_TEST(v3.is()); - BOOST_TEST(v3.is_table()); - - BOOST_TEST(v3.cast().at("foo").cast() == 2.71); - BOOST_TEST(v3.cast().at("bar").cast() == 54); - BOOST_TEST(v3.cast().at("baz").cast().str == "quux"); - BOOST_TEST(v3.as_table().at("foo").as_floating() == 2.71); - BOOST_TEST(v3.as_table().at("bar").as_integer() == 54); - BOOST_TEST(v3.as_table().at("baz").as_string().str == "quux"); - - - v1 = true; - BOOST_TEST(v1.type() == toml::value_t::boolean); - BOOST_TEST(v1.is(toml::value_t::boolean)); - BOOST_TEST(v1.is()); - BOOST_TEST(v1.is_boolean()); - BOOST_TEST(v1.cast() == true); - BOOST_TEST(v1.as_boolean() == true); + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); } -BOOST_AUTO_TEST_CASE(test_value_empty) +TEST_CASE("testing constructor (integer)") { - toml::value v1; - BOOST_TEST(v1.is_uninitialized()); - BOOST_TEST(v1.is(toml::value_t::empty)); + toml::integer_format_info fmt; + fmt.width = 10; - BOOST_CHECK_THROW(v1.as_boolean(), toml::type_error); - BOOST_CHECK_THROW(v1.as_integer(), toml::type_error); - BOOST_CHECK_THROW(v1.as_floating(), toml::type_error); - BOOST_CHECK_THROW(v1.as_string(), toml::type_error); - BOOST_CHECK_THROW(v1.as_offset_datetime(), toml::type_error); - BOOST_CHECK_THROW(v1.as_local_datetime(), toml::type_error); - BOOST_CHECK_THROW(v1.as_local_date(), toml::type_error); - BOOST_CHECK_THROW(v1.as_local_time(), toml::type_error); - BOOST_CHECK_THROW(v1.as_array(), toml::type_error); - BOOST_CHECK_THROW(v1.as_table(), toml::type_error); + const int eq = 42; + const int ne = 6 * 9; + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); } - -BOOST_AUTO_TEST_CASE(test_value_at) +TEST_CASE("testing constructor (floating)") { - { - toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + toml::floating_format_info fmt; + fmt.fmt = toml::floating_format::fixed; + fmt.prec = 6; - BOOST_TEST(v1.at("foo").as_integer() == 42); - BOOST_TEST(v1.at("bar").as_floating() == 3.14); - BOOST_TEST(v1.at("baz").as_string() == "qux"); + const double eq = 3.14; + const double ne = 2.71; - BOOST_CHECK_THROW(v1.at(0), toml::type_error); - BOOST_CHECK_THROW(v1.at("quux"), std::out_of_range); - } - - - { - toml::value v1{1,2,3,4,5}; - - BOOST_TEST(v1.at(0).as_integer() == 1); - BOOST_TEST(v1.at(1).as_integer() == 2); - BOOST_TEST(v1.at(2).as_integer() == 3); - BOOST_TEST(v1.at(3).as_integer() == 4); - BOOST_TEST(v1.at(4).as_integer() == 5); - - BOOST_CHECK_THROW(v1.at("foo"), toml::type_error); - BOOST_CHECK_THROW(v1.at(5), std::out_of_range); - } + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); } -BOOST_AUTO_TEST_CASE(test_value_bracket) +TEST_CASE("testing constructor (string)") { - { - toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + toml::string_format_info fmt; + fmt.fmt = toml::string_format::literal; - BOOST_TEST(v1["foo"].as_integer() == 42); - BOOST_TEST(v1["bar"].as_floating() == 3.14); - BOOST_TEST(v1["baz"].as_string() == "qux"); + const std::string eq("hoge"); + const std::string ne("fuga"); - v1["qux"] = 54; - BOOST_TEST(v1["qux"].as_integer() == 54); - } - { - toml::value v1; - v1["foo"] = 42; - - BOOST_TEST(v1.is_table()); - BOOST_TEST(v1["foo"].as_integer() == 42); - } - { - toml::value v1{1,2,3,4,5}; - - BOOST_TEST(v1[0].as_integer() == 1); - BOOST_TEST(v1[1].as_integer() == 2); - BOOST_TEST(v1[2].as_integer() == 3); - BOOST_TEST(v1[3].as_integer() == 4); - BOOST_TEST(v1[4].as_integer() == 5); - - BOOST_CHECK_THROW(v1["foo"], toml::type_error); - } + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); } -BOOST_AUTO_TEST_CASE(test_value_map_methods) +TEST_CASE("testing constructor (literal string)") { + toml::string_format_info fmt; + fmt.fmt = toml::string_format::literal; + + // to explicitly pass (const char&)[N], we write it here directly + // {{{ + + // ----------------------------------------------------------------------- { - toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; + toml::value x("foo"); - BOOST_TEST(v1.count("foo") == 1u); - BOOST_TEST(v1.count("bar") == 1u); - BOOST_TEST(v1.count("baz") == 1u); - BOOST_TEST(v1.count("qux") == 0u); + test_is_type(x, toml::value_t::string); + test_as_type_throws(x, toml::value_t::string); + test_as_type_fmt_throws(x, toml::value_t::string); - BOOST_TEST( v1.contains("foo")); - BOOST_TEST( v1.contains("bar")); - BOOST_TEST( v1.contains("baz")); - BOOST_TEST(!v1.contains("qux")); + test_as_type(x, "foo", "bar"); - BOOST_TEST(v1.size() == 3); + CHECK_EQ(x.comments().size(), 0); - v1["qux"] = 54; - BOOST_TEST(v1.count("qux") == 1u); - BOOST_TEST(v1.contains("qux")); - BOOST_TEST(v1.size() == 4); + CHECK_EQ(x.location().is_ok(), false); } + // ----------------------------------------------------------------------- { - toml::value v1(42); - BOOST_CHECK_THROW(v1.size() , toml::type_error); - BOOST_CHECK_THROW(v1.count("k") , toml::type_error); - BOOST_CHECK_THROW(v1.contains("k"), toml::type_error); + toml::value x_with_comments("foo", std::vector{"foo", "bar"}); + + test_is_type (x_with_comments, toml::value_t::string); + test_as_type_throws (x_with_comments, toml::value_t::string); + test_as_type_fmt_throws(x_with_comments, toml::value_t::string); + + test_as_type(x_with_comments, "foo", "bar"); + + CHECK_EQ(x_with_comments.comments().size(), 2); + CHECK_EQ(x_with_comments.comments().at(0), "foo"); + CHECK_EQ(x_with_comments.comments().at(1), "bar"); + + CHECK_EQ(x_with_comments.location().is_ok(), false); } + // ----------------------------------------------------------------------- + { + toml::value x_with_format("foo", fmt); + + test_is_type (x_with_format, toml::value_t::string); + test_as_type_throws (x_with_format, toml::value_t::string); + test_as_type_fmt_throws(x_with_format, toml::value_t::string); + + test_as_type (x_with_format, "foo", "bar"); + test_as_type_fmt(x_with_format, fmt); + + CHECK_EQ(x_with_format.comments().size(), 0); + + CHECK_EQ(x_with_format.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_with_com_fmt("foo", fmt, + std::vector{"foo", "bar"}); + + test_is_type (x_with_com_fmt, toml::value_t::string); + test_as_type_throws (x_with_com_fmt, toml::value_t::string); + test_as_type_fmt_throws(x_with_com_fmt, toml::value_t::string); + + test_as_type (x_with_com_fmt, "foo", "bar"); + test_as_type_fmt(x_with_com_fmt, fmt); + + CHECK_EQ(x_with_com_fmt.comments().size(), 2); + CHECK_EQ(x_with_com_fmt.comments().at(0), "foo"); + CHECK_EQ(x_with_com_fmt.comments().at(1), "bar"); + + CHECK_EQ(x_with_com_fmt.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_from_string(std::string("bar"), fmt); + x_from_string = "foo"; + + test_is_type (x_from_string, toml::value_t::string); + test_as_type_throws (x_from_string, toml::value_t::string); + test_as_type_fmt_throws(x_from_string, toml::value_t::string); + + test_as_type (x_from_string, "foo", "bar"); + test_as_type_fmt(x_from_string, fmt); + + CHECK_EQ(x_from_string.comments().size(), 0); + + CHECK_EQ(x_from_string.location().is_ok(), false); + } + // ----------------------------------------------------------------------- + { + toml::value x_from_non_string(true); + x_from_non_string = "foo"; + + test_is_type (x_from_non_string, toml::value_t::string); + test_as_type_throws (x_from_non_string, toml::value_t::string); + test_as_type_fmt_throws(x_from_non_string, toml::value_t::string); + + test_as_type(x_from_non_string, "foo", "bar"); + + CHECK_EQ(x_from_non_string.comments().size(), 0); + + CHECK_EQ(x_from_non_string.location().is_ok(), false); + } + // }}} } -BOOST_AUTO_TEST_CASE(test_value_vector_methods) +#ifdef TOML11_HAS_STRING_VIEW +#include + +TEST_CASE("testing constructor (string_view)") { - { - toml::value v1{1, 2, 3, 4, 5}; + toml::string_format_info fmt; + fmt.fmt = toml::string_format::literal; - BOOST_TEST(v1.size() == 5); + const std::string_view eq("hoge"); + const std::string_view ne("fuga"); - v1.push_back(6); - BOOST_TEST(v1.size() == 6); - - v1.emplace_back(6); - BOOST_TEST(v1.size() == 7); - } - { - toml::value v1(42); - BOOST_CHECK_THROW(v1.size(), toml::type_error); - BOOST_CHECK_THROW(v1.push_back(1), toml::type_error); - BOOST_CHECK_THROW(v1.emplace_back(1), toml::type_error); - } + test_ctors(eq, ne, fmt); +} +#endif + +TEST_CASE("testing constructor (local_date)") +{ + toml::local_date_format_info fmt; + + const toml::local_date eq(2023, toml::month_t::Feb, 2); + const toml::local_date ne(2023, toml::month_t::Jan, 1); + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (local_time)") +{ + toml::local_time_format_info fmt; + fmt.subsecond_precision = 3; + + const toml::local_time eq(12, 30, 45); + const toml::local_time ne( 2, 34, 56); + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (std::chrono::duration)") +{ + toml::local_time_format_info fmt; + fmt.subsecond_precision = 3; + + const auto eq = std::chrono::hours(12) ; + const auto ne = std::chrono::seconds(12); + + test_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (local_datetime)") +{ + toml::local_datetime_format_info fmt; + fmt.subsecond_precision = 3; + + const toml::local_datetime eq(toml::local_date(2023, toml::month_t::Feb, 2), + toml::local_time(12, 30, 45)); + const toml::local_datetime ne(toml::local_date(2023, toml::month_t::Jan, 1), + toml::local_time( 2, 34, 56)); + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (offset_datetime)") +{ + toml::offset_datetime_format_info fmt; + fmt.subsecond_precision = 3; + + const toml::offset_datetime eq(toml::local_date(2023, toml::month_t::Feb, 2), + toml::local_time(12, 30, 45), + toml::time_offset(9, 0)); + const toml::offset_datetime ne(toml::local_date(2023, toml::month_t::Jan, 1), + toml::local_time( 2, 34, 56), + toml::time_offset(-9, 0)); + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (system_clock::time_point)") +{ + toml::offset_datetime_format_info fmt; + fmt.subsecond_precision = 3; + + // we use zero-offset because offset_datetime uses gmtime. + const std::chrono::system_clock::time_point eq = + toml::offset_datetime(toml::local_date(2023, toml::month_t::Feb, 2), + toml::local_time(12, 30, 45), + toml::time_offset(0, 0)); + const std::chrono::system_clock::time_point ne = + toml::offset_datetime(toml::local_date(2023, toml::month_t::Jan, 1), + toml::local_time( 2, 34, 56), + toml::time_offset(-9, 0)); + + test_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (array)") +{ + toml::array_format_info fmt; + fmt.body_indent = 10; + fmt.closing_indent = 5; + + const toml::array eq{true, 42, "hoge"}; + const toml::array ne{false, 3.14, "fuga"}; + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (array-like)") +{ + toml::array_format_info fmt; + fmt.body_indent = 10; + fmt.closing_indent = 5; + + toml::value x(std::deque{true, 42, "hoge"}); + + test_is_type(x, toml::value_t::array); + test_as_type_throws(x, toml::value_t::array); + test_as_type_fmt_throws(x, toml::value_t::array); + + CHECK_UNARY(x.at(0).is_boolean()); + CHECK_UNARY(x.at(1).is_integer()); + CHECK_UNARY(x.at(2).is_string()); + + CHECK_EQ(x.at(0).as_boolean(), true); + CHECK_EQ(x.at(1).as_integer(), 42); + CHECK_EQ(x.at(2).as_string(), std::string("hoge")); + + // ----------------------------------------------------------------------- + + toml::value x_with_comments(std::deque{true, 42, "hoge"}, std::vector{"foo", "bar"}); + + test_is_type (x_with_comments, toml::value_t::array); + test_as_type_throws (x_with_comments, toml::value_t::array); + test_as_type_fmt_throws(x_with_comments, toml::value_t::array); + + CHECK_UNARY(x_with_comments.at(0).is_boolean()); + CHECK_UNARY(x_with_comments.at(1).is_integer()); + CHECK_UNARY(x_with_comments.at(2).is_string()); + + CHECK_EQ(x_with_comments.at(0).as_boolean(), true); + CHECK_EQ(x_with_comments.at(1).as_integer(), 42); + CHECK_EQ(x_with_comments.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(x_with_comments.comments().size(), 2); + CHECK_EQ(x_with_comments.comments().at(0), "foo"); + CHECK_EQ(x_with_comments.comments().at(1), "bar"); + + CHECK_EQ(x_with_comments.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_with_format(std::deque{true, 42, "hoge"}, fmt); + + test_is_type (x_with_format, toml::value_t::array); + test_as_type_throws (x_with_format, toml::value_t::array); + test_as_type_fmt_throws(x_with_format, toml::value_t::array); + + CHECK_UNARY(x_with_format.at(0).is_boolean()); + CHECK_UNARY(x_with_format.at(1).is_integer()); + CHECK_UNARY(x_with_format.at(2).is_string()); + + CHECK_EQ(x_with_format.at(0).as_boolean(), true); + CHECK_EQ(x_with_format.at(1).as_integer(), 42); + CHECK_EQ(x_with_format.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(x_with_format.as_array_fmt(), fmt); + + CHECK_EQ(x_with_format.comments().size(), 0); + + CHECK_EQ(x_with_format.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_with_com_fmt(std::deque{true, 42, "hoge"}, fmt, + std::vector{"foo", "bar"}); + + test_is_type (x_with_com_fmt, toml::value_t::array); + test_as_type_throws (x_with_com_fmt, toml::value_t::array); + test_as_type_fmt_throws(x_with_com_fmt, toml::value_t::array); + + CHECK_UNARY(x_with_com_fmt.at(0).is_boolean()); + CHECK_UNARY(x_with_com_fmt.at(1).is_integer()); + CHECK_UNARY(x_with_com_fmt.at(2).is_string()); + + CHECK_EQ(x_with_com_fmt.at(0).as_boolean(), true); + CHECK_EQ(x_with_com_fmt.at(1).as_integer(), 42); + CHECK_EQ(x_with_com_fmt.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(x_with_com_fmt.as_array_fmt(), fmt); + + CHECK_EQ(x_with_com_fmt.comments().size(), 2); + CHECK_EQ(x_with_com_fmt.comments().at(0), "foo"); + CHECK_EQ(x_with_com_fmt.comments().at(1), "bar"); + + CHECK_EQ(x_with_com_fmt.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_array(std::deque{3.14, 2.71, "foo"}, fmt); + x_from_array = std::deque{true, 42, "hoge"}; + + test_is_type (x_from_array, toml::value_t::array); + test_as_type_throws (x_from_array, toml::value_t::array); + test_as_type_fmt_throws(x_from_array, toml::value_t::array); + + CHECK_UNARY(x_from_array.at(0).is_boolean()); + CHECK_UNARY(x_from_array.at(1).is_integer()); + CHECK_UNARY(x_from_array.at(2).is_string()); + + CHECK_EQ(x_from_array.at(0).as_boolean(), true); + CHECK_EQ(x_from_array.at(1).as_integer(), 42); + CHECK_EQ(x_from_array.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(x_from_array.as_array_fmt(), fmt); + + CHECK_EQ(x_from_array.comments().size(), 0); + + CHECK_EQ(x_from_array.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_non_array(true); + x_from_non_array = std::deque{true, 42, "hoge"}; + + test_is_type (x_from_non_array, toml::value_t::array); + test_as_type_throws (x_from_non_array, toml::value_t::array); + test_as_type_fmt_throws(x_from_non_array, toml::value_t::array); + + CHECK_UNARY(x_from_non_array.at(0).is_boolean()); + CHECK_UNARY(x_from_non_array.at(1).is_integer()); + CHECK_UNARY(x_from_non_array.at(2).is_string()); + + CHECK_EQ(x_from_non_array.at(0).as_boolean(), true); + CHECK_EQ(x_from_non_array.at(1).as_integer(), 42); + CHECK_EQ(x_from_non_array.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(x_from_non_array.comments().size(), 0); + + CHECK_EQ(x_from_non_array.location().is_ok(), false); +} + +TEST_CASE("testing constructor (table)") +{ + toml::table_format_info fmt; + fmt.body_indent = 10; + + const toml::table eq{{"a", true }, {"b", 42}, {"c", "hoge"}}; + const toml::table ne{{"alpha", false}, {"b", 42}, {"c", "fuga"}}; + + test_ctors (eq, ne, fmt); + test_copy_move_ctors(eq, ne, fmt); +} + +TEST_CASE("testing constructor (table-like)") +{ + toml::table_format_info fmt; + fmt.body_indent = 10; + + toml::value x(std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}); + + test_is_type(x, toml::value_t::table); + test_as_type_throws(x, toml::value_t::table); + test_as_type_fmt_throws(x, toml::value_t::table); + + CHECK_UNARY(x.at("a").is_boolean()); + CHECK_UNARY(x.at("b").is_integer()); + CHECK_UNARY(x.at("c").is_string()); + + CHECK_EQ(x.at("a").as_boolean(), true); + CHECK_EQ(x.at("b").as_integer(), 42); + CHECK_EQ(x.at("c").as_string(), std::string("hoge")); + + // ----------------------------------------------------------------------- + + toml::value x_with_comments(std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}, std::vector{"foo", "bar"}); + + test_is_type (x_with_comments, toml::value_t::table); + test_as_type_throws (x_with_comments, toml::value_t::table); + test_as_type_fmt_throws(x_with_comments, toml::value_t::table); + + CHECK_UNARY(x_with_comments.at("a").is_boolean()); + CHECK_UNARY(x_with_comments.at("b").is_integer()); + CHECK_UNARY(x_with_comments.at("c").is_string()); + + CHECK_EQ(x_with_comments.at("a").as_boolean(), true); + CHECK_EQ(x_with_comments.at("b").as_integer(), 42); + CHECK_EQ(x_with_comments.at("c").as_string(), std::string("hoge")); + + CHECK_EQ(x_with_comments.comments().size(), 2); + CHECK_EQ(x_with_comments.comments().at(0), "foo"); + CHECK_EQ(x_with_comments.comments().at(1), "bar"); + + CHECK_EQ(x_with_comments.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_with_format(std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}, fmt); + + test_is_type (x_with_format, toml::value_t::table); + test_as_type_throws (x_with_format, toml::value_t::table); + test_as_type_fmt_throws(x_with_format, toml::value_t::table); + + CHECK_UNARY(x_with_format.at("a").is_boolean()); + CHECK_UNARY(x_with_format.at("b").is_integer()); + CHECK_UNARY(x_with_format.at("c").is_string()); + + CHECK_EQ(x_with_format.at("a").as_boolean(), true); + CHECK_EQ(x_with_format.at("b").as_integer(), 42); + CHECK_EQ(x_with_format.at("c").as_string(), std::string("hoge")); + + CHECK_EQ(x_with_format.as_table_fmt(), fmt); + + CHECK_EQ(x_with_format.comments().size(), 0); + + CHECK_EQ(x_with_format.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_with_com_fmt(std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}, fmt, + std::vector{"foo", "bar"}); + + test_is_type (x_with_com_fmt, toml::value_t::table); + test_as_type_throws (x_with_com_fmt, toml::value_t::table); + test_as_type_fmt_throws(x_with_com_fmt, toml::value_t::table); + + CHECK_UNARY(x_with_com_fmt.at("a").is_boolean()); + CHECK_UNARY(x_with_com_fmt.at("b").is_integer()); + CHECK_UNARY(x_with_com_fmt.at("c").is_string()); + + CHECK_EQ(x_with_com_fmt.at("a").as_boolean(), true); + CHECK_EQ(x_with_com_fmt.at("b").as_integer(), 42); + CHECK_EQ(x_with_com_fmt.at("c").as_string(), std::string("hoge")); + + CHECK_EQ(x_with_com_fmt.as_table_fmt(), fmt); + + CHECK_EQ(x_with_com_fmt.comments().size(), 2); + CHECK_EQ(x_with_com_fmt.comments().at(0), "foo"); + CHECK_EQ(x_with_com_fmt.comments().at(1), "bar"); + + CHECK_EQ(x_with_com_fmt.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_table(toml::table{{"foo", "bar"}}, fmt); + x_from_table = std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}; + + test_is_type (x_from_table, toml::value_t::table); + test_as_type_throws (x_from_table, toml::value_t::table); + test_as_type_fmt_throws(x_from_table, toml::value_t::table); + + CHECK_UNARY(x_from_table.at("a").is_boolean()); + CHECK_UNARY(x_from_table.at("b").is_integer()); + CHECK_UNARY(x_from_table.at("c").is_string()); + + CHECK_EQ(x_from_table.at("a").as_boolean(), true); + CHECK_EQ(x_from_table.at("b").as_integer(), 42); + CHECK_EQ(x_from_table.at("c").as_string(), std::string("hoge")); + + CHECK_EQ(x_from_table.as_table_fmt(), fmt); + + CHECK_EQ(x_from_table.comments().size(), 0); + + CHECK_EQ(x_from_table.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_non_table(true); + x_from_non_table = std::map{{"a", true}, {"b", 42}, {"c", "hoge"}}; + + test_is_type (x_from_non_table, toml::value_t::table); + test_as_type_throws (x_from_non_table, toml::value_t::table); + test_as_type_fmt_throws(x_from_non_table, toml::value_t::table); + + CHECK_UNARY(x_from_non_table.at("a").is_boolean()); + CHECK_UNARY(x_from_non_table.at("b").is_integer()); + CHECK_UNARY(x_from_non_table.at("c").is_string()); + + CHECK_EQ(x_from_non_table.at("a").as_boolean(), true); + CHECK_EQ(x_from_non_table.at("b").as_integer(), 42); + CHECK_EQ(x_from_non_table.at("c").as_string(), std::string("hoge")); + + CHECK_EQ(x_from_non_table.comments().size(), 0); + + CHECK_EQ(x_from_non_table.location().is_ok(), false); +} + +struct X +{ + toml::value into_toml() const + { + return toml::value(this->value); + } + int value; +}; + +inline bool operator==(const X& lhs, const X& rhs) +{ + return lhs.value == rhs.value; +} +inline bool operator!=(const X& lhs, const X& rhs) +{ + return lhs.value != rhs.value; +} + +TEST_CASE("testing constructor (into_toml)") +{ + const X initialized_with{42}; + const X different_from{6*9}; + + // ----------------------------------------------------------------------- + + toml::value x(initialized_with); + + test_is_type(x, toml::value_t::integer); + test_as_type_throws(x, toml::value_t::integer); + test_as_type_fmt_throws(x, toml::value_t::integer); + + CHECK_EQ(x.as_integer(), initialized_with.value); + CHECK_NE(x.as_integer(), different_from.value); + CHECK_EQ(x.as_integer(std::nothrow), initialized_with.value); + CHECK_NE(x.as_integer(std::nothrow), different_from.value); + + CHECK_EQ(x.comments().size(), 0); + + CHECK_EQ(x.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_with_comments(initialized_with, std::vector{"foo", "bar"}); + + test_is_type (x_with_comments, toml::value_t::integer); + test_as_type_throws (x_with_comments, toml::value_t::integer); + test_as_type_fmt_throws(x_with_comments, toml::value_t::integer); + + CHECK_EQ(x_with_comments.as_integer(), initialized_with.value); + CHECK_NE(x_with_comments.as_integer(), different_from.value); + CHECK_EQ(x_with_comments.as_integer(std::nothrow), initialized_with.value); + CHECK_NE(x_with_comments.as_integer(std::nothrow), different_from.value); + + CHECK_EQ(x_with_comments.comments().size(), 2); + CHECK_EQ(x_with_comments.comments().at(0), "foo"); + CHECK_EQ(x_with_comments.comments().at(1), "bar"); + + CHECK_EQ(x_with_comments.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_integer(different_from); + x_from_integer = initialized_with; + + test_is_type (x_from_integer, toml::value_t::integer); + test_as_type_throws (x_from_integer, toml::value_t::integer); + test_as_type_fmt_throws(x_from_integer, toml::value_t::integer); + + CHECK_EQ(x_from_integer.as_integer(), initialized_with.value); + CHECK_NE(x_from_integer.as_integer(), different_from.value); + CHECK_EQ(x_from_integer.as_integer(std::nothrow), initialized_with.value); + CHECK_NE(x_from_integer.as_integer(std::nothrow), different_from.value); + + CHECK_EQ(x_from_integer.comments().size(), 0); + + CHECK_EQ(x_from_integer.location().is_ok(), false); + + // ----------------------------------------------------------------------- + + toml::value x_from_non_integer(true); + x_from_non_integer = initialized_with; + + test_is_type (x_from_non_integer, toml::value_t::integer); + test_as_type_throws (x_from_non_integer, toml::value_t::integer); + test_as_type_fmt_throws(x_from_non_integer, toml::value_t::integer); + + CHECK_EQ(x_from_non_integer.as_integer(), initialized_with.value); + CHECK_NE(x_from_non_integer.as_integer(), different_from.value); + CHECK_EQ(x_from_non_integer.as_integer(std::nothrow), initialized_with.value); + CHECK_NE(x_from_non_integer.as_integer(std::nothrow), different_from.value); + + CHECK_EQ(x_from_non_integer.comments().size(), 0); + + CHECK_EQ(x_from_non_integer.location().is_ok(), false); +} + + +TEST_CASE("testing array-accessors") +{ + toml::value x({true, 42, "hoge"}); + + CHECK_UNARY(x.at(0).is_boolean()); + CHECK_UNARY(x.at(1).is_integer()); + CHECK_UNARY(x.at(2).is_string()); + + CHECK_UNARY(as_const(x).at(0).is_boolean()); + CHECK_UNARY(as_const(x).at(1).is_integer()); + CHECK_UNARY(as_const(x).at(2).is_string()); + + CHECK_EQ(x.at(0).as_boolean(), true); + CHECK_EQ(x.at(1).as_integer(), 42); + CHECK_EQ(x.at(2).as_string(), std::string("hoge")); + + CHECK_EQ(as_const(x).at(0).as_boolean(), true); + CHECK_EQ(as_const(x).at(1).as_integer(), 42); + CHECK_EQ(as_const(x).at(2).as_string(), std::string("hoge")); + + CHECK_UNARY(x[0].is_boolean()); + CHECK_UNARY(x[1].is_integer()); + CHECK_UNARY(x[2].is_string()); + + CHECK_EQ(x[0].as_boolean(), true); + CHECK_EQ(x[1].as_integer(), 42); + CHECK_EQ(x[2].as_string(), std::string("hoge")); + + const toml::value v1(3.14); + toml::value v2(2.71); + + x.push_back(v1); + x.push_back(std::move(v2)); + + CHECK_UNARY(x.at(3).is_floating()); + CHECK_UNARY(x.at(4).is_floating()); + + CHECK_EQ(x.at(3).as_floating(), 3.14); + CHECK_EQ(x.at(4).as_floating(), 2.71); + + x.emplace_back(6.022e23, std::vector{"mol"}); + + CHECK_UNARY(x.at(5).is_floating()); + CHECK_EQ(x.at(5).as_floating(), 6.022e23); + CHECK_EQ(x.at(5).comments().size(), 1); + CHECK_EQ(x.at(5).comments().at(0), "mol"); + + CHECK_EQ(x.size(), 6); + + CHECK_THROWS_AS(x.at(6), std::out_of_range); + CHECK_THROWS_AS(x.at(7), std::out_of_range); + CHECK_THROWS_AS(as_const(x).at(6), std::out_of_range); + CHECK_THROWS_AS(as_const(x).at(7), std::out_of_range); + + // ----------------------------------------- + + toml::value non_array("foobar"); + toml::value v3("foo"); + CHECK_THROWS_AS(non_array.at(0), toml::type_error); + CHECK_THROWS_AS(as_const(non_array).at(0), toml::type_error); + CHECK_THROWS_AS(non_array.push_back(as_const(v3)), toml::type_error); + CHECK_THROWS_AS(non_array.push_back(std::move(v3)), toml::type_error); + CHECK_THROWS_AS(non_array.emplace_back(42), toml::type_error); + + // ----------------------------------------- + toml::value string_has_size("foobar"); + CHECK_EQ(string_has_size.size(), 6); +} + +TEST_CASE("testing table-accessors") +{ + toml::value x({ {"a", true}, {"b", 42}, {"c", "hoge"} }); + + CHECK_UNARY(x.contains("a")); + CHECK_UNARY(x.contains("b")); + CHECK_UNARY(x.contains("c")); + CHECK_UNARY_FALSE(x.contains("d")); + CHECK_UNARY_FALSE(x.contains("e")); + + CHECK_EQ(x.count("a"), 1); + CHECK_EQ(x.count("b"), 1); + CHECK_EQ(x.count("c"), 1); + CHECK_EQ(x.count("d"), 0); + CHECK_EQ(x.count("e"), 0); + + CHECK_UNARY(x.at("a").is_boolean()); + CHECK_UNARY(x.at("b").is_integer()); + CHECK_UNARY(x.at("c").is_string()); + + CHECK_EQ(x.at("a").as_boolean(), true); + CHECK_EQ(x.at("b").as_integer(), 42); + CHECK_EQ(x.at("c").as_string(), std::string("hoge")); + + CHECK_UNARY(x["a"].is_boolean()); + CHECK_UNARY(x["b"].is_integer()); + CHECK_UNARY(x["c"].is_string()); + + CHECK_EQ(x["a"].as_boolean(), true); + CHECK_EQ(x["b"].as_integer(), 42); + CHECK_EQ(x["c"].as_string(), std::string("hoge")); + + const toml::value v1(3.14); + x["d"] = v1; + + CHECK_UNARY(x.at("d").is_floating()); + CHECK_EQ(x.at("d").as_floating(), 3.14); + + CHECK_UNARY(x.contains("d")); + CHECK_EQ(x.count("d"), 1); + + CHECK_EQ(x.size(), 4); + + CHECK_THROWS_AS(x.at("f"), std::out_of_range); + CHECK_THROWS_AS(x.at("g"), std::out_of_range); + CHECK_THROWS_AS(as_const(x).at("f"), std::out_of_range); + CHECK_THROWS_AS(as_const(x).at("g"), std::out_of_range); + + // ----------------------------------------------- + + toml::value non_table("foobar"); + CHECK_THROWS_AS(non_table.at("foo"), toml::type_error); + CHECK_THROWS_AS(as_const(non_table).at("foo"), toml::type_error); + CHECK_THROWS_AS(non_table["foo"], toml::type_error); + CHECK_THROWS_AS(non_table.count("foo"), toml::type_error); + CHECK_THROWS_AS(non_table.contains("foo"), toml::type_error); + + toml::value no_size(42); + CHECK_THROWS_AS(no_size.size(), toml::type_error); + + // ----------------------------------------------- + toml::value empty; + CHECK_UNARY(empty.is_empty()); + + empty["is"] = "table"; + + CHECK_UNARY(empty.is_table()); + CHECK_UNARY(empty.contains("is")); + CHECK_EQ(empty.at("is").as_string(), "table"); } diff --git a/tests/test_visit.cpp b/tests/test_visit.cpp new file mode 100644 index 0000000..fa98293 --- /dev/null +++ b/tests/test_visit.cpp @@ -0,0 +1,161 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include +#include +#include +#include + +template +struct printer +{ + using value_type = Value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + std::string operator()(const boolean_type& x) const + { + if(x) {return "true";} else {return "false";} + } + std::string operator()(const integer_type& x) const + { + return std::to_string(x); + } + std::string operator()(const floating_type& x) const + { + return std::to_string(x); + } + std::string operator()(const string_type& x) const + { + return "\"" + x + "\""; + } + std::string operator()(const local_time_type& x) const + { + std::ostringstream oss; + oss << x; + return oss.str(); + } + std::string operator()(const local_date_type& x) const + { + std::ostringstream oss; + oss << x; + return oss.str(); + } + std::string operator()(const local_datetime_type& x) const + { + std::ostringstream oss; + oss << x; + return oss.str(); + } + std::string operator()(const offset_datetime_type& x) const + { + std::ostringstream oss; + oss << x; + return oss.str(); + } + std::string operator()(const array_type& a) const + { + std::string str; + str += '['; + for(const auto& e : a) + { + str += toml::visit(*this, e); + str += ", "; + } + str += ']'; + return str; + } + + std::string operator()(const table_type& t) const + { + std::string str; + str += '{'; + for(const auto& e : t) + { + str += e.first; + str += " = "; + str += toml::visit(*this, e.second); + str += ", "; + } + if( ! t.empty()) + { + str.pop_back(); + str.pop_back(); + } + str += '}'; + return str; + } +}; + +struct type_config_ordered_map +{ + using comment_type = toml::preserve_comments; + + using boolean_type = bool; + using integer_type = std::int64_t; + using floating_type = double; + using string_type = std::string; + + template + using array_type = std::vector; + template + using table_type = std::map; + + static toml::result + parse_int(const std::string& str, const toml::source_location src, const std::uint8_t base) + { + assert(base == 10 || base == 16 || base == 8 || base == 2); + return toml::read_int(str, src, base); + } + static toml::result + parse_float(const std::string& str, const toml::source_location src, const bool is_hex) + { + return toml::read_float(str, src, is_hex); + } +}; + +TEST_CASE("testing toml::get with toml types") +{ + using value_type = toml::basic_value; + using array_type = typename value_type::array_type; + using table_type = typename value_type::table_type; + + const printer p; + { + value_type v(true); + CHECK_EQ("true", toml::visit(p, v)); + } + { + value_type v(false); + CHECK_EQ("false", toml::visit(p, v)); + } + { + value_type v(42); + CHECK_EQ(std::to_string(42), toml::visit(p, v)); + } + { + value_type v(3.14); + CHECK_EQ(std::to_string(3.14), toml::visit(p, v)); + } + { + value_type v("foo"); + CHECK_EQ("\"foo\"", toml::visit(p, v)); + } + { + value_type v(array_type{true, 42, 3.14, "foo"}); + CHECK_EQ("[true, 42, " + std::to_string(3.14) + ", \"foo\", ]", toml::visit(p, v)); + } + { + value_type v(table_type{{"foo", true}, {"bar", 42}}); + CHECK_EQ("{bar = 42, foo = true}", toml::visit(p, v)); + } +} + diff --git a/tests/test_windows.cpp b/tests/test_windows.cpp deleted file mode 100644 index b178a26..0000000 --- a/tests/test_windows.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include - -int main() -{ - using namespace toml::literals::toml_literals; - const auto data = R"(windows = "defines min and max as a macro")"_toml; - - std::cout << toml::find(data, "windows") << std::endl; - return 0; -} diff --git a/tests/to_json.cpp b/tests/to_json.cpp new file mode 100644 index 0000000..785e851 --- /dev/null +++ b/tests/to_json.cpp @@ -0,0 +1,161 @@ + +#include +#include +#include + +#include +#include + +#include + +#ifdef TOML11_TO_JSON_USE_V1_1_0 +# define TOML11_TO_JSON_SPEC toml::spec::v(1, 1, 0) +#else +# define TOML11_TO_JSON_SPEC toml::spec::v(1, 0, 0) +#endif + +template +struct json_converter +{ + using value_type = Value; + using boolean_type = typename value_type::boolean_type ; + using integer_type = typename value_type::integer_type ; + using floating_type = typename value_type::floating_type ; + using string_type = typename value_type::string_type ; + using local_time_type = typename value_type::local_time_type ; + using local_date_type = typename value_type::local_date_type ; + using local_datetime_type = typename value_type::local_datetime_type ; + using offset_datetime_type = typename value_type::offset_datetime_type; + using array_type = typename value_type::array_type ; + using table_type = typename value_type::table_type ; + + nlohmann::json operator()(boolean_type v) + { + nlohmann::json j; + j["type"] = "bool"; + if(v) + { + j["value"] = "true"; + } + else + { + j["value"] = "false"; + } + return j; + } + nlohmann::json operator()(integer_type v) + { + nlohmann::json j; + j["type"] = "integer"; + j["value"] = std::to_string(v); + return j; + } + nlohmann::json operator()(floating_type v) + { + std::ostringstream oss; + oss << std::setprecision(16); + // if we set the precision as max_digit, 1.1 will be 1.1000000000000001. + // But toml-test does not allow 1.1000000000000001. + if(std::isnan(v) && std::signbit(v)) + { + // toml-test does not allow negative NaN represented in "-nan" because + // there are languages that does not distinguish nan and -nan. + // But toml11 keeps sign from input. To resolve this difference, + // we convert -nan to nan here. + v = std::numeric_limits::quiet_NaN(); + } + oss << v; + + nlohmann::json j; + j["type"] = "float"; + j["value"] = oss.str(); + return j; + } + nlohmann::json operator()(const string_type& v) + { + nlohmann::json j; + j["type"] = "string"; + j["value"] = v; + return j; + } + nlohmann::json operator()(const toml::local_time& v) + { + nlohmann::json j; + j["type"] = "time-local"; + j["value"] = toml::to_string(v); + return j; + } + nlohmann::json operator()(const toml::local_date& v) + { + nlohmann::json j; + j["type"] = "date-local"; + j["value"] = toml::to_string(v); + return j; + } + nlohmann::json operator()(const toml::local_datetime& v) + { + nlohmann::json j; + j["type"] = "datetime-local"; + j["value"] = toml::to_string(v); + return j; + } + nlohmann::json operator()(const toml::offset_datetime& v) + { + nlohmann::json j; + j["type"] = "datetime"; + j["value"] = toml::to_string(v); + return j; + } + nlohmann::json operator()(const toml::array& v) + { + nlohmann::json j = nlohmann::json::array(); + for(const auto& elem : v) + { + j.push_back(toml::visit(*this, elem)); + } + return j; + } + nlohmann::json operator()(const toml::table& v) + { + nlohmann::json j = nlohmann::json::object(); + for(const auto& kv : v) + { + j[kv.first] = toml::visit(*this, kv.second); + } + return j; + } +}; + +int main(int argc, char** argv) +{ + try + { + if(argc == 2) + { + const std::string fname(argv[1]); + const auto data = toml::parse(fname, TOML11_TO_JSON_SPEC); + std::cout << toml::visit(json_converter<>(), data); + return 0; + } + else + { + std::vector buf; + std::cin.peek(); + + while(!std::cin.eof()) + { + buf.push_back(static_cast(std::cin.get())); + std::cin.peek(); + } + + const auto data = toml::parse(buf, "cin", TOML11_TO_JSON_SPEC); + std::cout << toml::visit(json_converter<>(), data); + return 0; + } + } + catch(const std::exception& err) + { + std::cout << "what(): " << err.what() << std::endl; + return 1; + } +} diff --git a/tests/to_toml.cpp b/tests/to_toml.cpp new file mode 100644 index 0000000..a5511bb --- /dev/null +++ b/tests/to_toml.cpp @@ -0,0 +1,113 @@ +#include +#include + +#include +#include + +#include + +toml::value convert_to_toml(const nlohmann::json& j) +{ + if(j.is_array()) + { + toml::value a(toml::array{}); + for(const auto& v : j) + { + a.push_back(convert_to_toml(v)); + } + return a; + } + else if(j.size() == 2 && + j.contains("type") && j.at("type").is_string() && + j.contains("value") && j.at("value").is_string() ) + { + const auto type = j.at("type" ).get(); + const auto value = j.at("value").get(); + if(type == "string") + { + return toml::value(value); + } + else if(type == "int") + { + toml::detail::context ctx(toml::spec::default_version()); + auto loc = toml::detail::make_temporary_location(value); + return toml::detail::parse_integer(loc, ctx).unwrap(); + } + else if(type == "float") + { + toml::detail::context ctx(toml::spec::default_version()); + auto loc = toml::detail::make_temporary_location(value); + if(auto f_r = toml::detail::parse_floating(loc, ctx)) + { + return f_r.unwrap(); + } + else + { + // toml-test converts "inf" into "Inf" + if(value == "Inf" || value == "+Inf") + { + return toml::value(std::numeric_limits::infinity()); + } + else if(value == "-Inf") + { + return toml::value(-std::numeric_limits::infinity()); + } + else + { + return toml::value(toml::detail::from_string(value).unwrap()); + } + } + } + else + { + return toml::detail::literal_internal_impl( + toml::detail::make_temporary_location(value)); + } + } + else // table. + { + toml::value t(toml::table{}); + for(const auto& kv : j.items()) + { + t[kv.key()] = convert_to_toml(kv.value()); + } + return t; + } +} + +int main(int argc, char** argv) +{ + try + { + if(argc == 2) + { + const std::string fname(argv[1]); + std::ifstream ifs(fname); + const auto j = nlohmann::json::parse(ifs); + const auto t = convert_to_toml(j); + std::cout << toml::format(t) << std::endl; + return 0; + } + else + { + std::vector buf; + std::cin.peek(); + + while(!std::cin.eof()) + { + buf.push_back(static_cast(std::cin.get())); + std::cin.peek(); + } + std::string str(buf.begin(), buf.end()); + const auto j = nlohmann::json::parse(str); + const auto t = convert_to_toml(j); + std::cout << toml::format(t) << std::endl; + return 0; + } + } + catch(const std::exception& err) + { + std::cout << "what(): " << err.what() << std::endl; + return 1; + } +} diff --git a/tests/unit_test.hpp b/tests/unit_test.hpp deleted file mode 100644 index 5999f57..0000000 --- a/tests/unit_test.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#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/tests/utility.cpp b/tests/utility.cpp new file mode 100644 index 0000000..f45eba0 --- /dev/null +++ b/tests/utility.cpp @@ -0,0 +1,104 @@ +#include "doctest.h" + +#include "utility.hpp" + +#include +#include + +#include + +void test_scan_success(const toml::detail::scanner_base& s, + const std::string& in, const std::string& out) +{ + auto loc = toml::detail::make_temporary_location(in); + const auto reg = s.scan(loc); + CHECK_UNARY(reg.is_ok()); + CHECK_EQ(reg.as_string(), out); +} +void test_scan_failure(const toml::detail::scanner_base& s, + const std::string& in) +{ + auto loc = toml::detail::make_temporary_location(in); + const auto reg = s.scan(loc); + CHECK_UNARY_FALSE(reg.is_ok()); +} + +namespace toml +{ + +std::ostream& operator<<(std::ostream& os, const integer_format_info& fmt) +{ + os << "integer_format_info{"; + os << "fmt = " << fmt.fmt << ", "; + os << "width = " << fmt.width << ", "; + os << "spacer = " << fmt.spacer << ", "; + os << "suffix = \"" << fmt.suffix << "\"}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const floating_format_info& fmt) +{ + os << "floating_format_info{"; + os << "fmt = " << fmt.fmt << ", "; + os << "prec = " << fmt.prec << ", "; + os << "suffix = \"" << fmt.suffix << "\"}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const string_format_info& fmt) +{ + os << "string_format_info{"; + os << "fmt = " << fmt.fmt << ", "; + os << "start_with_newline = " << fmt.start_with_newline << "}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const offset_datetime_format_info& fmt) +{ + os << "offset_datetime_format_info{"; + os << std::boolalpha; + os << "delimiter = " << fmt.delimiter << ", "; + os << "has_seconds = " << fmt.has_seconds << ", "; + os << "subsecond_precision = " << fmt.subsecond_precision << "}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const local_datetime_format_info& fmt) +{ + os << "local_datetime_format_info{"; + os << std::boolalpha; + os << "delimiter = " << fmt.delimiter << ", "; + os << "has_seconds = " << fmt.has_seconds << ", "; + os << "subsecond_precision = " << fmt.subsecond_precision << "}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const local_date_format_info&) +{ + os << "local_date_format_info{}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const local_time_format_info& fmt) +{ + os << "local_time_format_info{"; + os << std::boolalpha; + os << "has_seconds = " << fmt.has_seconds << ", "; + os << "subsecond_precision = " << fmt.subsecond_precision << "}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const array_format_info& fmt) +{ + os << "array_format_info{"; + os << "fmt = " << fmt.fmt << ", "; + os << "indent_type = " << fmt.indent_type << ", "; + os << "body_indent = " << fmt.body_indent << ", "; + os << "closing_indent = " << fmt.closing_indent << "}"; + return os; +} +std::ostream& operator<<(std::ostream& os, const table_format_info& fmt) +{ + os << "table_format_info{"; + os << "fmt = " << fmt.fmt << ", "; + os << "indent_type = " << fmt.indent_type << ", "; + os << "name_indent = " << fmt.name_indent << ", "; + os << "body_indent = " << fmt.body_indent << ", "; + os << "closing_indent = " << fmt.closing_indent << "}"; + return os; +} + +} // toml diff --git a/tests/utility.hpp b/tests/utility.hpp new file mode 100644 index 0000000..a4df9b2 --- /dev/null +++ b/tests/utility.hpp @@ -0,0 +1,107 @@ +#ifndef TOML11_TEST_UTILITY_HPP +#define TOML11_TEST_UTILITY_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include "doctest.h" + +#include +#include +#include +#include + +#include + +template +toml::basic_value const& as_const(toml::basic_value& v) noexcept +{ + return v; +} + +template +std::vector comments(Ts ... args) +{ + return std::vector{std::move(args)...}; +} + +void test_scan_success(const toml::detail::scanner_base& s, + const std::string& in, const std::string& out); +void test_scan_failure(const toml::detail::scanner_base& s, + const std::string& in); + +template +void toml11_test_parse_success( + std::string in, const T& out, + const std::vector& com, + const Format& fmt, + toml::detail::context ctx) +{ + auto loc = toml::detail::make_temporary_location(in); + + const auto res = toml::detail::parse_value(loc, ctx); + if(res.is_err()) + { + std::cerr << toml::format_error(res.unwrap_err()) << std::endl; + } + REQUIRE_UNARY(res.is_ok()); + + const auto val = res.unwrap(); + + REQUIRE(val.is(VT)); + REQUIRE_EQ(val.type(), VT); + + CHECK_EQ(val.template as(), out); + + const std::vector com_actual( + val.comments().begin(), val.comments().end()); + CHECK_EQ(com_actual, com); + + const auto fmt_actual = val.template as_fmt(); + CHECK_EQ(fmt_actual, fmt); +} + +template +void toml11_test_parse_failure(F fn, std::string in, toml::detail::context ctx) +{ + using namespace toml::detail; + auto loc = toml::detail::make_temporary_location(in); + const auto res = fn(loc, ctx); + REQUIRE_UNARY(res.is_err()); + + ctx.report_error(res.unwrap_err()); + + std::cerr << "-------- error messages about: `" << in.substr(0, in.find('\n')) << "` --------" << std::endl; + for(const auto& e : ctx.errors()) + { + std::cerr << toml::format_error(e) << std::endl; + } + std::cerr << "-------- end --------" << std::endl; +} + +namespace toml +{ +template +std::ostream& operator<<(std::ostream& os, const toml::basic_value& v) +{ + os << toml::format(v); + return os; +} + +std::ostream& operator<<(std::ostream& os, const integer_format_info&); +std::ostream& operator<<(std::ostream& os, const floating_format_info&); +std::ostream& operator<<(std::ostream& os, const string_format_info&); +std::ostream& operator<<(std::ostream& os, const offset_datetime_format_info&); +std::ostream& operator<<(std::ostream& os, const local_datetime_format_info&); +std::ostream& operator<<(std::ostream& os, const local_date_format_info&); +std::ostream& operator<<(std::ostream& os, const local_time_format_info&); +std::ostream& operator<<(std::ostream& os, const array_format_info&); +std::ostream& operator<<(std::ostream& os, const table_format_info&); + +} // toml +#endif// TOML11_TEST_UTILITY_HPP