From d4742334cef2a5e9fcb9349ba7e8a14788614cf0 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 2 Jul 2024 23:34:20 +0900 Subject: [PATCH 1/2] fix: add detail::make_error_info_rec overload that converts basic_value to location --- include/toml11/fwd/error_info_fwd.hpp | 8 ++++++++ include/toml11/value.hpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/include/toml11/fwd/error_info_fwd.hpp b/include/toml11/fwd/error_info_fwd.hpp index 5d30b86..5b8600c 100644 --- a/include/toml11/fwd/error_info_fwd.hpp +++ b/include/toml11/fwd/error_info_fwd.hpp @@ -41,6 +41,10 @@ struct error_info std::string suffix_; // hint or something like that }; +// forward decl +template +class basic_value; + namespace detail { inline error_info make_error_info_rec(error_info e) @@ -53,6 +57,10 @@ inline error_info make_error_info_rec(error_info e, std::string s) return e; } +template +error_info make_error_info_rec(error_info e, + const basic_value& v, std::string msg, Ts&& ... tail); + template error_info make_error_info_rec(error_info e, source_location loc, std::string msg, Ts&& ... tail) diff --git a/include/toml11/value.hpp b/include/toml11/value.hpp index fe1720d..6139ad9 100644 --- a/include/toml11/value.hpp +++ b/include/toml11/value.hpp @@ -2026,12 +2026,16 @@ operator>=(const basic_value& lhs, const basic_value& rhs) } // error_info helper +namespace detail +{ template error_info make_error_info_rec(error_info e, const basic_value& v, std::string msg, Ts&& ... tail) { return make_error_info_rec(std::move(e), v.location(), std::move(msg), std::forward(tail)...); } +} // detail + template error_info make_error_info( std::string title, const basic_value& v, std::string msg, Ts&& ... tail) From 37d0391b9d24cce5d8baca878b413c297940d48a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 2 Jul 2024 23:35:16 +0900 Subject: [PATCH 2/2] test: add test to make error_info check if it compiles --- tests/CMakeLists.txt | 1 + tests/test_error_message.cpp | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/test_error_message.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3ca04aa..d95901e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,7 @@ set(TOML11_TEST_NAMES test_comments test_datetime + test_error_message test_find test_find_or test_format_integer diff --git a/tests/test_error_message.cpp b/tests/test_error_message.cpp new file mode 100644 index 0000000..567dc4a --- /dev/null +++ b/tests/test_error_message.cpp @@ -0,0 +1,79 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +TEST_CASE("testing custom error message using source_location") +{ + const toml::value root = toml::parse_str(R"( + range = [0, 42] + val = 54 + )"); + + const auto& lower = root.at("range").at(0); + const auto& upper = root.at("range").at(1); + const auto& val = root.at("val"); + + const auto err = toml::make_error_info("val not in range", + lower.location(), "lower limit is defined here", + upper.location(), "upper limit is defined here", + val.location(), "this is not in the range", + "Hint: upper limit is inclusive" + ); + + CHECK_EQ(err.title(), "val not in range"); + CHECK_EQ(err.locations().size(), 3); + CHECK_EQ(err.locations().at(0).second, "lower limit is defined here"); + CHECK_EQ(err.locations().at(1).second, "upper limit is defined here"); + CHECK_EQ(err.locations().at(2).second, "this is not in the range" ); +} + +TEST_CASE("testing custom error message using value") +{ + const toml::value root = toml::parse_str(R"( + range = [0, 42] + val = 54 + )"); + + const auto& lower = root.at("range").at(0); + const auto& upper = root.at("range").at(1); + const auto& val = root.at("val"); + + const auto err = toml::make_error_info("val not in range", + lower, "lower limit is defined here", + upper, "upper limit is defined here", + val, "this is not in the range", + "Hint: upper limit is inclusive" + ); + + CHECK_EQ(err.title(), "val not in range"); + CHECK_EQ(err.locations().size(), 3); + CHECK_EQ(err.locations().at(0).second, "lower limit is defined here"); + CHECK_EQ(err.locations().at(1).second, "upper limit is defined here"); + CHECK_EQ(err.locations().at(2).second, "this is not in the range" ); +} + +TEST_CASE("testing custom error message using source_location and value") +{ + const toml::value root = toml::parse_str(R"( + range = [0, 42] + val = 54 + )"); + + const auto& lower = root.at("range").at(0); + const auto& upper = root.at("range").at(1); + const auto& val = root.at("val"); + + const auto err = toml::make_error_info("val not in range", + lower, "lower limit is defined here", + upper, "upper limit is defined here", + val.location(), "this is not in the range", + "Hint: upper limit is inclusive" + ); + + CHECK_EQ(err.title(), "val not in range"); + CHECK_EQ(err.locations().size(), 3); + CHECK_EQ(err.locations().at(0).second, "lower limit is defined here"); + CHECK_EQ(err.locations().at(1).second, "upper limit is defined here"); + CHECK_EQ(err.locations().at(2).second, "this is not in the range" ); +}