Merge remote-tracking branch 'origin/develop' into feature/templated_define_type_macroses
This commit is contained in:
commit
ee88c8cf52
@ -6,6 +6,15 @@ cmake_minimum_required(VERSION 3.1)
|
||||
##
|
||||
project(nlohmann_json VERSION 3.9.1 LANGUAGES CXX)
|
||||
|
||||
##
|
||||
## MAIN_PROJECT CHECK
|
||||
## determine if nlohmann_json is built as a subproject (using add_subdirectory) or if it is the main project
|
||||
##
|
||||
set(MAIN_PROJECT OFF)
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(MAIN_PROJECT ON)
|
||||
endif()
|
||||
|
||||
##
|
||||
## INCLUDE
|
||||
##
|
||||
@ -21,8 +30,8 @@ if (POLICY CMP0077)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
endif ()
|
||||
|
||||
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
|
||||
option(JSON_Install "Install CMake targets during install step." ON)
|
||||
option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ${MAIN_PROJECT})
|
||||
option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT})
|
||||
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
||||
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
|
||||
|
||||
@ -101,9 +110,8 @@ CONFIGURE_FILE(
|
||||
## TESTS
|
||||
## create and configure the unit test target
|
||||
##
|
||||
include(CTest) #adds option BUILD_TESTING (default ON)
|
||||
|
||||
if(BUILD_TESTING AND JSON_BuildTests)
|
||||
if (JSON_BuildTests)
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
@ -2,19 +2,32 @@
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
||||
#include <utility> // index_sequence, make_index_sequence, index_sequence_for
|
||||
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// alias templates to reduce boilerplate
|
||||
template<bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template<typename T>
|
||||
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
// implementation of C++14 index_sequence and affiliates
|
||||
#ifdef JSON_HAS_CPP_14
|
||||
|
||||
// the following utilities are natively available in C++14
|
||||
using std::enable_if_t;
|
||||
using std::index_sequence;
|
||||
using std::make_index_sequence;
|
||||
using std::index_sequence_for;
|
||||
|
||||
#else
|
||||
|
||||
// alias templates to reduce boilerplate
|
||||
template<bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
// source: https://stackoverflow.com/a/32223343
|
||||
template<std::size_t... Ints>
|
||||
struct index_sequence
|
||||
@ -45,6 +58,8 @@ template<> struct make_index_sequence<1> : index_sequence<0> {};
|
||||
template<typename... Ts>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
||||
|
||||
#endif
|
||||
|
||||
// dispatch utility (taken from ranges-v3)
|
||||
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
||||
template<> struct priority_tag<0> {};
|
||||
@ -58,5 +73,6 @@ struct static_const
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
||||
|
||||
@ -168,7 +168,9 @@ struct is_iterator_traits<iterator_traits<T>>
|
||||
is_detected<reference_t, traits>::value;
|
||||
};
|
||||
|
||||
// source: https://stackoverflow.com/a/37193089/4116453
|
||||
// The following implementation of is_complete_type is taken from
|
||||
// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
|
||||
// and is written by Xiang Fan who agreed to using it in this library.
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_complete_type : std::false_type {};
|
||||
@ -186,7 +188,6 @@ struct is_compatible_object_type_impl <
|
||||
enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
|
||||
is_detected<key_type_t, CompatibleObjectType>::value >>
|
||||
{
|
||||
|
||||
using object_t = typename BasicJsonType::object_t;
|
||||
|
||||
// macOS's is_constructible does not play well with nonesuch...
|
||||
|
||||
@ -923,14 +923,14 @@ class basic_json
|
||||
AllocatorType<T> alloc;
|
||||
using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
|
||||
|
||||
auto deleter = [&](T * object)
|
||||
auto deleter = [&](T * obj)
|
||||
{
|
||||
AllocatorTraits::deallocate(alloc, object, 1);
|
||||
AllocatorTraits::deallocate(alloc, obj, 1);
|
||||
};
|
||||
std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
|
||||
AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
|
||||
JSON_ASSERT(object != nullptr);
|
||||
return object.release();
|
||||
std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
|
||||
AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
|
||||
JSON_ASSERT(obj != nullptr);
|
||||
return obj.release();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
|
||||
@ -2772,19 +2772,33 @@ class other_error : public exception
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
|
||||
#include <utility> // index_sequence, make_index_sequence, index_sequence_for
|
||||
|
||||
// #include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// alias templates to reduce boilerplate
|
||||
template<bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template<typename T>
|
||||
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
// implementation of C++14 index_sequence and affiliates
|
||||
#ifdef JSON_HAS_CPP_14
|
||||
|
||||
// the following utilities are natively available in C++14
|
||||
using std::enable_if_t;
|
||||
using std::index_sequence;
|
||||
using std::make_index_sequence;
|
||||
using std::index_sequence_for;
|
||||
|
||||
#else
|
||||
|
||||
// alias templates to reduce boilerplate
|
||||
template<bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
// source: https://stackoverflow.com/a/32223343
|
||||
template<std::size_t... Ints>
|
||||
struct index_sequence
|
||||
@ -2815,6 +2829,8 @@ template<> struct make_index_sequence<1> : index_sequence<0> {};
|
||||
template<typename... Ts>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
||||
|
||||
#endif
|
||||
|
||||
// dispatch utility (taken from ranges-v3)
|
||||
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
|
||||
template<> struct priority_tag<0> {};
|
||||
@ -2828,6 +2844,7 @@ struct static_const
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
||||
|
||||
@ -3210,7 +3227,9 @@ struct is_iterator_traits<iterator_traits<T>>
|
||||
is_detected<reference_t, traits>::value;
|
||||
};
|
||||
|
||||
// source: https://stackoverflow.com/a/37193089/4116453
|
||||
// The following implementation of is_complete_type is taken from
|
||||
// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
|
||||
// and is written by Xiang Fan who agreed to using it in this library.
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_complete_type : std::false_type {};
|
||||
@ -3228,7 +3247,6 @@ struct is_compatible_object_type_impl <
|
||||
enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
|
||||
is_detected<key_type_t, CompatibleObjectType>::value >>
|
||||
{
|
||||
|
||||
using object_t = typename BasicJsonType::object_t;
|
||||
|
||||
// macOS's is_constructible does not play well with nonesuch...
|
||||
@ -17531,14 +17549,14 @@ class basic_json
|
||||
AllocatorType<T> alloc;
|
||||
using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
|
||||
|
||||
auto deleter = [&](T * object)
|
||||
auto deleter = [&](T * obj)
|
||||
{
|
||||
AllocatorTraits::deallocate(alloc, object, 1);
|
||||
AllocatorTraits::deallocate(alloc, obj, 1);
|
||||
};
|
||||
std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
|
||||
AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
|
||||
JSON_ASSERT(object != nullptr);
|
||||
return object.release();
|
||||
std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
|
||||
AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
|
||||
JSON_ASSERT(obj != nullptr);
|
||||
return obj.release();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
|
||||
@ -867,8 +867,9 @@ TEST_CASE("Negative size of binary value")
|
||||
|
||||
0x00 // end marker
|
||||
};
|
||||
CHECK_THROWS_AS(json::from_bson(input), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_bson(input), "[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1");
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_bson(input), json::parse_error);
|
||||
CHECK_THROWS_WITH(_ = json::from_bson(input), "[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1");
|
||||
}
|
||||
|
||||
TEST_CASE("Unsupported BSON input")
|
||||
|
||||
@ -1591,14 +1591,16 @@ TEST_CASE("CBOR")
|
||||
{
|
||||
// array with three empty byte strings
|
||||
std::vector<std::uint8_t> input = {0x83, 0x40, 0x40, 0x40};
|
||||
CHECK_NOTHROW(json::from_cbor(input));
|
||||
json _;
|
||||
CHECK_NOTHROW(_ = json::from_cbor(input));
|
||||
}
|
||||
|
||||
SECTION("binary in object")
|
||||
{
|
||||
// object mapping "foo" to empty byte string
|
||||
std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x40};
|
||||
CHECK_NOTHROW(json::from_cbor(input));
|
||||
json _;
|
||||
CHECK_NOTHROW(_ = json::from_cbor(input));
|
||||
}
|
||||
|
||||
SECTION("SAX callback with binary")
|
||||
@ -2551,8 +2553,9 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), b);
|
||||
|
||||
// check that parsing fails in error mode
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
|
||||
// check that parsing succeeds and gets original value in ignore mode
|
||||
auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
|
||||
@ -2570,8 +2573,9 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xD8); // tag
|
||||
|
||||
// check that parsing fails in error mode
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
|
||||
// check that parsing succeeds and gets original value in ignore mode
|
||||
auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
|
||||
@ -2585,9 +2589,10 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xD8); // tag
|
||||
|
||||
// check that parsing fails in all modes
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2602,8 +2607,9 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xD9); // tag
|
||||
|
||||
// check that parsing fails in error mode
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
|
||||
// check that parsing succeeds and gets original value in ignore mode
|
||||
auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
|
||||
@ -2618,9 +2624,10 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xD9); // tag
|
||||
|
||||
// check that parsing fails in all modes
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2637,8 +2644,9 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xDA); // tag
|
||||
|
||||
// check that parsing fails in error mode
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
|
||||
// check that parsing succeeds and gets original value in ignore mode
|
||||
auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
|
||||
@ -2655,9 +2663,10 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xDA); // tag
|
||||
|
||||
// check that parsing fails in all modes
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2678,8 +2687,9 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xDB); // tag
|
||||
|
||||
// check that parsing fails in error mode
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
|
||||
// check that parsing succeeds and gets original value in ignore mode
|
||||
auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
|
||||
@ -2700,9 +2710,10 @@ TEST_CASE("Tagged values")
|
||||
v_tagged.insert(v_tagged.begin(), 0xDB); // tag
|
||||
|
||||
// check that parsing fails in all modes
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2717,8 +2728,9 @@ TEST_CASE("Tagged values")
|
||||
CHECK(vec == std::vector<std::uint8_t> {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE});
|
||||
|
||||
// parse error when parsing tagged value
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8");
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error);
|
||||
CHECK_THROWS_WITH(_ = json::from_cbor(vec), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8");
|
||||
|
||||
// binary without subtype when tags are ignored
|
||||
json jb = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);
|
||||
|
||||
@ -1879,7 +1879,8 @@ TEST_CASE("parser class")
|
||||
|
||||
SECTION("error messages for comments")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
|
||||
json _;
|
||||
CHECK_THROWS_WITH_AS(_ = json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(_ = json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,7 +537,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("with empty range")
|
||||
{
|
||||
std::vector<uint8_t> v;
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
SaxEventLogger l;
|
||||
@ -553,7 +554,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 1")
|
||||
{
|
||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -569,7 +571,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 2")
|
||||
{
|
||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -585,7 +588,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 3")
|
||||
{
|
||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -601,7 +605,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 4")
|
||||
{
|
||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -617,7 +622,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 5")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xC1};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -652,7 +658,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 7")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -668,7 +675,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 8")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -684,7 +692,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 9")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -700,7 +709,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 10")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -716,7 +726,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 11")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -732,7 +743,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 12")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -748,7 +760,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 13")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -764,7 +777,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 14")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -780,7 +794,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 15")
|
||||
{
|
||||
uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
@ -796,7 +811,8 @@ TEST_CASE("deserialization")
|
||||
SECTION("case 16")
|
||||
{
|
||||
uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'};
|
||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||
CHECK(!json::accept(std::begin(v), std::end(v)));
|
||||
|
||||
json j_error;
|
||||
|
||||
@ -805,12 +805,13 @@ TEST_CASE("UBJSON")
|
||||
std::vector<uint8_t> vec1 = {'H', 'i', '1'};
|
||||
CHECK(json::from_ubjson(vec1, true, false).is_discarded());
|
||||
|
||||
json _;
|
||||
std::vector<uint8_t> vec2 = {'H', 'i', 2, '1', 'A', '3'};
|
||||
CHECK_THROWS_WITH_AS(json::from_ubjson(vec2), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec2), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A", json::parse_error);
|
||||
std::vector<uint8_t> vec3 = {'H', 'i', 2, '1', '.'};
|
||||
CHECK_THROWS_WITH_AS(json::from_ubjson(vec3), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1.", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec3), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1.", json::parse_error);
|
||||
std::vector<uint8_t> vec4 = {'H', 2, '1', '0'};
|
||||
CHECK_THROWS_WITH_AS(json::from_ubjson(vec4), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x02", json::parse_error);
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec4), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x02", json::parse_error);
|
||||
}
|
||||
|
||||
SECTION("serialization")
|
||||
|
||||
@ -1201,7 +1201,8 @@ TEST_CASE("Unicode" * doctest::skip())
|
||||
SECTION("with an iterator")
|
||||
{
|
||||
std::string i = "\xef\xbb\xbf{\n \"foo\": true\n}";
|
||||
CHECK_NOTHROW(json::parse(i.begin(), i.end()));
|
||||
json _;
|
||||
CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
272
test/thirdparty/doctest/doctest.h
vendored
Executable file → Normal file
272
test/thirdparty/doctest/doctest.h
vendored
Executable file → Normal file
@ -48,8 +48,8 @@
|
||||
|
||||
#define DOCTEST_VERSION_MAJOR 2
|
||||
#define DOCTEST_VERSION_MINOR 4
|
||||
#define DOCTEST_VERSION_PATCH 1
|
||||
#define DOCTEST_VERSION_STR "2.4.1"
|
||||
#define DOCTEST_VERSION_PATCH 3
|
||||
#define DOCTEST_VERSION_STR "2.4.3"
|
||||
|
||||
#define DOCTEST_VERSION \
|
||||
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
|
||||
@ -368,7 +368,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
|
||||
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
|
||||
#endif
|
||||
#elif defined(DOCTEST_PLATFORM_MAC)
|
||||
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
|
||||
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
|
||||
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
|
||||
#else
|
||||
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
|
||||
@ -747,6 +747,7 @@ struct ContextOptions //!OCLINT too many fields
|
||||
bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
|
||||
bool no_path_in_filenames; // if the path to files should be removed from the output
|
||||
bool no_line_numbers; // if source code line numbers should be omitted from the output
|
||||
bool no_debug_output; // no output in the debug console when a debugger is attached
|
||||
bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
|
||||
bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
|
||||
|
||||
@ -806,7 +807,7 @@ namespace detail {
|
||||
} // namespace has_insertion_operator_impl
|
||||
|
||||
template<class T>
|
||||
using has_insertion_operator = has_insertion_operator_impl::check<T>;
|
||||
using has_insertion_operator = has_insertion_operator_impl::check<const T>;
|
||||
|
||||
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);
|
||||
|
||||
@ -1035,6 +1036,7 @@ namespace detail {
|
||||
template <typename L, typename R>
|
||||
String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
|
||||
const DOCTEST_REF_WRAP(R) rhs) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
return toString(lhs) + op + toString(rhs);
|
||||
}
|
||||
|
||||
@ -1122,6 +1124,7 @@ namespace detail {
|
||||
#define DOCTEST_COMPARISON_RETURN_TYPE bool
|
||||
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
|
||||
#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
|
||||
inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
|
||||
inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
|
||||
@ -1510,7 +1513,7 @@ namespace detail {
|
||||
DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
|
||||
DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
|
||||
|
||||
// ContextScope base class used to allow implementing methods of ContextScope
|
||||
// ContextScope base class used to allow implementing methods of ContextScope
|
||||
// that don't depend on the template parameter in doctest.cpp.
|
||||
class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
|
||||
protected:
|
||||
@ -1541,12 +1544,24 @@ namespace detail {
|
||||
MessageBuilder() = delete;
|
||||
~MessageBuilder();
|
||||
|
||||
// the preferred way of chaining parameters for stringification
|
||||
template <typename T>
|
||||
MessageBuilder& operator<<(const T& in) {
|
||||
MessageBuilder& operator,(const T& in) {
|
||||
toStream(m_stream, in);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// kept here just for backwards-compatibility - the comma operator should be preferred now
|
||||
template <typename T>
|
||||
MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
|
||||
|
||||
// the `,` operator has the lowest operator precedence - if `<<` is used by the user then
|
||||
// the `,` operator will be called last which is not what we want and thus the `*` operator
|
||||
// is used first (has higher operator precedence compared to `<<`) so that we guarantee that
|
||||
// an operator of the MessageBuilder class is called first before the rest of the parameters
|
||||
template <typename T>
|
||||
MessageBuilder& operator*(const T& in) { return this->operator,(in); }
|
||||
|
||||
bool log();
|
||||
void react();
|
||||
};
|
||||
@ -1962,38 +1977,38 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
|
||||
|
||||
// for logging
|
||||
#define DOCTEST_INFO(expression) \
|
||||
#define DOCTEST_INFO(...) \
|
||||
DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
|
||||
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), expression)
|
||||
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), __VA_ARGS__)
|
||||
|
||||
#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, expression) \
|
||||
#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, ...) \
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626) \
|
||||
auto lambda_name = [&](std::ostream* s_name) { \
|
||||
doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
|
||||
mb_name.m_stream = s_name; \
|
||||
mb_name << expression; \
|
||||
mb_name * __VA_ARGS__; \
|
||||
}; \
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
|
||||
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name)
|
||||
|
||||
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x)
|
||||
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
|
||||
|
||||
#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \
|
||||
#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
|
||||
do { \
|
||||
doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
|
||||
mb << x; \
|
||||
mb * __VA_ARGS__; \
|
||||
DOCTEST_ASSERT_LOG_AND_REACT(mb); \
|
||||
} while(false)
|
||||
|
||||
// clang-format off
|
||||
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
|
||||
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
|
||||
#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
|
||||
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
|
||||
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
|
||||
#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
|
||||
// clang-format on
|
||||
|
||||
#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x)
|
||||
#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x)
|
||||
#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x)
|
||||
#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
|
||||
#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
|
||||
#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
|
||||
|
||||
@ -2036,12 +2051,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
|
||||
|
||||
// clang-format off
|
||||
#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
|
||||
#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
|
||||
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
|
||||
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
|
||||
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
|
||||
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
|
||||
#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
|
||||
#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
|
||||
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
|
||||
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
|
||||
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
|
||||
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
|
||||
// clang-format on
|
||||
|
||||
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
|
||||
@ -2103,21 +2118,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
|
||||
#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
|
||||
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while(false)
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while(false)
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false)
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false)
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
|
||||
// clang-format on
|
||||
|
||||
#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
|
||||
@ -2230,21 +2245,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
|
||||
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
|
||||
|
||||
@ -2335,14 +2350,14 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
|
||||
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
|
||||
|
||||
#define DOCTEST_INFO(x) (static_cast<void>(0))
|
||||
#define DOCTEST_INFO(...) (static_cast<void>(0))
|
||||
#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0))
|
||||
#define DOCTEST_MESSAGE(x) (static_cast<void>(0))
|
||||
#define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0))
|
||||
#define DOCTEST_FAIL(x) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_MESSAGE(...) (static_cast<void>(0))
|
||||
#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
|
||||
#define DOCTEST_FAIL(...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN(...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK(...) (static_cast<void>(0))
|
||||
@ -2351,12 +2366,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
|
||||
@ -2374,21 +2389,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
|
||||
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
|
||||
|
||||
#define DOCTEST_WARN_EQ(...) (static_cast<void>(0))
|
||||
#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
|
||||
@ -2754,9 +2769,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
|
||||
#include <map>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#ifdef DOCTEST_CONFIG_POSIX_SIGNALS
|
||||
#include <csignal>
|
||||
#endif // DOCTEST_CONFIG_POSIX_SIGNALS
|
||||
#include <cfloat>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
@ -2912,7 +2925,7 @@ namespace detail {
|
||||
|
||||
namespace timer_large_integer
|
||||
{
|
||||
|
||||
|
||||
#if defined(DOCTEST_PLATFORM_WINDOWS)
|
||||
typedef ULONGLONG type;
|
||||
#else // DOCTEST_PLATFORM_WINDOWS
|
||||
@ -3071,6 +3084,7 @@ String::String() {
|
||||
String::~String() {
|
||||
if(!isOnStack())
|
||||
delete[] data.ptr;
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
String::String(const char* in)
|
||||
@ -3112,6 +3126,7 @@ String& String::operator+=(const String& other) {
|
||||
if(total_size < len) {
|
||||
// append to the current stack space
|
||||
memcpy(buf + my_old_size, other.c_str(), other_size + 1);
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
setLast(last - total_size);
|
||||
} else {
|
||||
// alloc new chunk
|
||||
@ -3153,6 +3168,7 @@ String& String::operator+=(const String& other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
String String::operator+(const String& other) const { return String(*this) += other; }
|
||||
|
||||
String::String(String&& other) {
|
||||
@ -3307,6 +3323,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
|
||||
// depending on the current options this will remove the path of filenames
|
||||
const char* skipPathFromFilename(const char* file) {
|
||||
#ifndef DOCTEST_CONFIG_DISABLE
|
||||
if(getContextOptions()->no_path_in_filenames) {
|
||||
auto back = std::strrchr(file, '\\');
|
||||
auto forward = std::strrchr(file, '/');
|
||||
@ -3316,6 +3333,7 @@ const char* skipPathFromFilename(const char* file) {
|
||||
return forward + 1;
|
||||
}
|
||||
}
|
||||
#endif // DOCTEST_CONFIG_DISABLE
|
||||
return file;
|
||||
}
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
@ -3334,6 +3352,7 @@ IContextScope::~IContextScope() = default;
|
||||
|
||||
#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
|
||||
String toString(char* in) { return toString(static_cast<const char*>(in)); }
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
|
||||
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
|
||||
String toString(bool in) { return in ? "true" : "false"; }
|
||||
@ -3406,6 +3425,7 @@ bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs
|
||||
bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
|
||||
|
||||
String toString(const Approx& in) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
return String("Approx( ") + doctest::toString(in.m_value) + " )";
|
||||
}
|
||||
const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
|
||||
@ -3594,8 +3614,8 @@ namespace detail {
|
||||
DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
|
||||
}
|
||||
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
|
||||
Subcase::~Subcase() {
|
||||
@ -3622,8 +3642,8 @@ namespace detail {
|
||||
}
|
||||
}
|
||||
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||
|
||||
Subcase::operator bool() const { return m_entered; }
|
||||
@ -3703,6 +3723,9 @@ namespace detail {
|
||||
const int file_cmp = m_file.compare(other.m_file);
|
||||
if(file_cmp != 0)
|
||||
return file_cmp < 0;
|
||||
const int name_cmp = strcmp(m_name, other.m_name);
|
||||
if(name_cmp != 0)
|
||||
return name_cmp < 0;
|
||||
return m_template_id < other.m_template_id;
|
||||
}
|
||||
} // namespace detail
|
||||
@ -3962,8 +3985,8 @@ namespace detail {
|
||||
g_infoContexts.push_back(this);
|
||||
}
|
||||
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
|
||||
|
||||
// destroy cannot be inlined into the destructor because that would mean calling stringify after
|
||||
@ -3982,8 +4005,8 @@ namespace detail {
|
||||
g_infoContexts.pop_back();
|
||||
}
|
||||
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||
} // namespace detail
|
||||
namespace {
|
||||
@ -4009,10 +4032,12 @@ namespace {
|
||||
// Windows can easily distinguish between SO and SigSegV,
|
||||
// but SigInt, SigTerm, etc are handled differently.
|
||||
SignalDefs signalDefs[] = {
|
||||
{EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"},
|
||||
{EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"},
|
||||
{EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"},
|
||||
{EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"},
|
||||
{static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
|
||||
"SIGILL - Illegal instruction signal"},
|
||||
{static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
|
||||
{static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
|
||||
"SIGSEGV - Segmentation violation signal"},
|
||||
{static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
|
||||
};
|
||||
|
||||
struct FatalConditionHandler
|
||||
@ -4038,6 +4063,28 @@ namespace {
|
||||
previousTop = SetUnhandledExceptionFilter(handleException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
|
||||
// On Windows uncaught exceptions from another thread, exceptions from
|
||||
// destructors, or calls to std::terminate are not a SEH exception
|
||||
|
||||
// The terminal handler gets called when:
|
||||
// - std::terminate is called FROM THE TEST RUNNER THREAD
|
||||
// - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
|
||||
original_terminate_handler = std::get_terminate();
|
||||
std::set_terminate([]() noexcept {
|
||||
reportFatal("Terminate handler called");
|
||||
std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
|
||||
});
|
||||
|
||||
// SIGABRT is raised when:
|
||||
// - std::terminate is called FROM A DIFFERENT THREAD
|
||||
// - an exception is thrown from a destructor FROM A DIFFERENT THREAD
|
||||
// - an uncaught exception is thrown FROM A DIFFERENT THREAD
|
||||
prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) noexcept {
|
||||
if(signal == SIGABRT) {
|
||||
reportFatal("SIGABRT - Abort (abnormal termination) signal");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
@ -4047,17 +4094,23 @@ namespace {
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
previousTop = nullptr;
|
||||
isSet = false;
|
||||
std::set_terminate(original_terminate_handler);
|
||||
std::signal(SIGABRT, prev_sigabrt_handler);
|
||||
}
|
||||
}
|
||||
|
||||
~FatalConditionHandler() { reset(); }
|
||||
|
||||
private:
|
||||
static void (*prev_sigabrt_handler)(int);
|
||||
static std::terminate_handler original_terminate_handler;
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
|
||||
};
|
||||
|
||||
void (*FatalConditionHandler::prev_sigabrt_handler)(int);
|
||||
std::terminate_handler FatalConditionHandler::original_terminate_handler;
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
|
||||
@ -4257,6 +4310,7 @@ namespace detail {
|
||||
// ###################################################################################
|
||||
DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
|
||||
DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
|
||||
@ -4979,7 +5033,6 @@ namespace {
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - log_contexts()
|
||||
// - log_message()
|
||||
// - respond to queries
|
||||
// - honor remaining options
|
||||
@ -5175,12 +5228,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
<< line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
|
||||
|
||||
fulltext_log_assert_to_stream(os, rb);
|
||||
log_contexts(os);
|
||||
testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
|
||||
}
|
||||
|
||||
void log_message(const MessageData&) override {}
|
||||
|
||||
void test_case_skipped(const TestCaseData&) override {}
|
||||
|
||||
void log_contexts(std::ostringstream& s) {
|
||||
int num_contexts = get_num_active_contexts();
|
||||
if(num_contexts) {
|
||||
auto contexts = get_active_contexts();
|
||||
|
||||
s << " logged: ";
|
||||
for(int i = 0; i < num_contexts; ++i) {
|
||||
s << (i == 0 ? "" : " ");
|
||||
contexts[i]->stringify(&s);
|
||||
s << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
|
||||
@ -5894,6 +5962,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false);
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
|
||||
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
|
||||
// clang-format on
|
||||
@ -5951,6 +6020,7 @@ void Context::clearFilters() {
|
||||
// allows the user to override procedurally the int/bool options from the command line
|
||||
void Context::setOption(const char* option, int value) {
|
||||
setOption(option, toString(value).c_str());
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
// allows the user to override procedurally the string options from the command line
|
||||
@ -6026,7 +6096,7 @@ int Context::run() {
|
||||
p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
|
||||
|
||||
#ifdef DOCTEST_PLATFORM_WINDOWS
|
||||
if(isDebuggerActive())
|
||||
if(isDebuggerActive() && p->no_debug_output == false)
|
||||
p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
|
||||
#endif // DOCTEST_PLATFORM_WINDOWS
|
||||
|
||||
@ -6257,4 +6327,4 @@ DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||
DOCTEST_GCC_SUPPRESS_WARNING_POP
|
||||
|
||||
#endif // DOCTEST_LIBRARY_IMPLEMENTATION
|
||||
#endif // DOCTEST_CONFIG_IMPLEMENT
|
||||
#endif // DOCTEST_CONFIG_IMPLEMENT
|
||||
|
||||
Loading…
Reference in New Issue
Block a user