mirror of
https://github.com/nlohmann/json.git
synced 2026-10-07 06:57:14 +00:00
Deduplicate SaxCountdown and other test helpers across formats
SaxCountdown was copied byte-for-byte into six binary-format test files (unit-cbor.cpp, unit-msgpack.cpp, unit-ubjson.cpp, unit-bjdata.cpp, unit-bon8.cpp, unit-bson.cpp), about 370 redundant lines. Move it into tests/src/sax_countdown.hpp (namespace utils, alongside test_utils.hpp and round_trip_corpus.hpp) and include it from all six. trait_test_arg and the "value_in_range_of trait" TEST_CASE_TEMPLATE_DEFINE were duplicated between unit-32bit.cpp and unit-bjdata.cpp; the trait is a detail/meta trait, not specific to either file. Move it into tests/src/value_in_range_of_test.hpp; unit-32bit.cpp keeps its own include, since JSON_32bitTest=ONLY builds only that file. Each file keeps its own TEST_CASE_TEMPLATE_INVOKE list. sax_no_exception and the "issue #2824" section were duplicated in unit-regression2.cpp and unit-disabled_exceptions.cpp. Drop the copy from unit-regression2.cpp; unit-disabled_exceptions.cpp already covers the no-exceptions case that #2824 was about, and ci_test_noexceptions reruns it. No behavior change. Verified by building and running unit-cbor, unit-msgpack, unit-ubjson, unit-bjdata, unit-bon8, unit-bson, unit-32bit, unit-regression2 and unit-disabled_exceptions against include/ (clang++ -std=c++11, ASan/UBSan where applicable); assertion counts are unchanged from before the refactor. Part of #5714 Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
10 files changed
+210
-638
No files matched your search
@@ -0,0 +1,99 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
/// a SAX event consumer that stops accepting events after a fixed count,
|
||||||
|
/// used by the binary-format tests to check behavior when the SAX consumer
|
||||||
|
/// rejects an event partway through parsing
|
||||||
|
class SaxCountdown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
explicit SaxCountdown(const int count) : events_left(count)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool null()
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boolean(bool /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool number_integer(json::number_integer_t /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool string(std::string& /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool start_object(std::size_t /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool key(std::string& /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool end_object()
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool start_array(std::size_t /*unused*/)
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool end_array()
|
||||||
|
{
|
||||||
|
return events_left-- > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int events_left = 0;
|
||||||
|
};
|
||||||
|
} // namespace utils
|
||||||
@@ -12,80 +12,11 @@
|
|||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#include <climits> // SIZE_MAX
|
#include <climits> // SIZE_MAX
|
||||||
#include <limits> // numeric_limits
|
|
||||||
|
|
||||||
template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
|
// JSON_32bitTest=ONLY builds only this file, so it must keep its own
|
||||||
struct trait_test_arg
|
// include of the shared trait/TEST_CASE_TEMPLATE_DEFINE rather than relying
|
||||||
{
|
// on unit-bjdata.cpp to provide it
|
||||||
using of_type = OfType;
|
#include "value_in_range_of_test.hpp"
|
||||||
using type = T;
|
|
||||||
static constexpr bool min_in_range = MinInRange;
|
|
||||||
static constexpr bool max_in_range = MaxInRange;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test) // NOLINT(readability-math-missing-parentheses)
|
|
||||||
{
|
|
||||||
using nlohmann::detail::value_in_range_of;
|
|
||||||
|
|
||||||
using of_type = typename T::of_type;
|
|
||||||
using type = typename T::type;
|
|
||||||
constexpr bool min_in_range = T::min_in_range;
|
|
||||||
constexpr bool max_in_range = T::max_in_range;
|
|
||||||
|
|
||||||
type const val_min = std::numeric_limits<type>::min();
|
|
||||||
type const val_min2 = val_min + 1;
|
|
||||||
type const val_max = std::numeric_limits<type>::max();
|
|
||||||
type const val_max2 = val_max - 1;
|
|
||||||
|
|
||||||
REQUIRE(CHAR_BIT == 8);
|
|
||||||
|
|
||||||
std::string of_type_str;
|
|
||||||
if (std::is_unsigned<of_type>::value)
|
|
||||||
{
|
|
||||||
of_type_str += "u";
|
|
||||||
}
|
|
||||||
of_type_str += "int";
|
|
||||||
of_type_str += std::to_string(sizeof(of_type) * 8);
|
|
||||||
|
|
||||||
INFO("of_type := ", of_type_str);
|
|
||||||
|
|
||||||
std::string type_str;
|
|
||||||
if (std::is_unsigned<type>::value)
|
|
||||||
{
|
|
||||||
type_str += "u";
|
|
||||||
}
|
|
||||||
type_str += "int";
|
|
||||||
type_str += std::to_string(sizeof(type) * 8);
|
|
||||||
|
|
||||||
INFO("type := ", type_str);
|
|
||||||
|
|
||||||
CAPTURE(val_min);
|
|
||||||
CAPTURE(min_in_range);
|
|
||||||
CAPTURE(val_max);
|
|
||||||
CAPTURE(max_in_range);
|
|
||||||
|
|
||||||
if (min_in_range)
|
|
||||||
{
|
|
||||||
CHECK(value_in_range_of<of_type>(val_min));
|
|
||||||
CHECK(value_in_range_of<of_type>(val_min2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_min));
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_min2));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_in_range)
|
|
||||||
{
|
|
||||||
CHECK(value_in_range_of<of_type>(val_max));
|
|
||||||
CHECK(value_in_range_of<of_type>(val_max2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_max));
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_max2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("32bit")
|
TEST_CASE("32bit")
|
||||||
{
|
{
|
||||||
|
|||||||
+5
-150
@@ -21,158 +21,13 @@ using nlohmann::json;
|
|||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "round_trip_corpus.hpp"
|
#include "round_trip_corpus.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
// trait_test_arg and the "value_in_range_of trait" TEST_CASE_TEMPLATE_DEFINE
|
||||||
{
|
// are shared with unit-32bit.cpp
|
||||||
return events_left-- > 0;
|
#include "value_in_range_of_test.hpp"
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// at some point in the future, a unit test dedicated to type traits might be a good idea
|
|
||||||
template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
|
|
||||||
struct trait_test_arg
|
|
||||||
{
|
|
||||||
using of_type = OfType;
|
|
||||||
using type = T;
|
|
||||||
static constexpr bool min_in_range = MinInRange;
|
|
||||||
static constexpr bool max_in_range = MaxInRange;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test) // NOLINT(readability-math-missing-parentheses)
|
|
||||||
{
|
|
||||||
using nlohmann::detail::value_in_range_of;
|
|
||||||
|
|
||||||
using of_type = typename T::of_type;
|
|
||||||
using type = typename T::type;
|
|
||||||
constexpr bool min_in_range = T::min_in_range;
|
|
||||||
constexpr bool max_in_range = T::max_in_range;
|
|
||||||
|
|
||||||
type const val_min = std::numeric_limits<type>::min();
|
|
||||||
type const val_min2 = val_min + 1;
|
|
||||||
type const val_max = std::numeric_limits<type>::max();
|
|
||||||
type const val_max2 = val_max - 1;
|
|
||||||
|
|
||||||
REQUIRE(CHAR_BIT == 8);
|
|
||||||
|
|
||||||
std::string of_type_str;
|
|
||||||
if (std::is_unsigned<of_type>::value)
|
|
||||||
{
|
|
||||||
of_type_str += "u";
|
|
||||||
}
|
|
||||||
of_type_str += "int";
|
|
||||||
of_type_str += std::to_string(sizeof(of_type) * 8);
|
|
||||||
|
|
||||||
INFO("of_type := ", of_type_str);
|
|
||||||
|
|
||||||
std::string type_str;
|
|
||||||
if (std::is_unsigned<type>::value)
|
|
||||||
{
|
|
||||||
type_str += "u";
|
|
||||||
}
|
|
||||||
type_str += "int";
|
|
||||||
type_str += std::to_string(sizeof(type) * 8);
|
|
||||||
|
|
||||||
INFO("type := ", type_str);
|
|
||||||
|
|
||||||
CAPTURE(val_min);
|
|
||||||
CAPTURE(min_in_range);
|
|
||||||
CAPTURE(val_max);
|
|
||||||
CAPTURE(max_in_range);
|
|
||||||
|
|
||||||
if (min_in_range)
|
|
||||||
{
|
|
||||||
CHECK(value_in_range_of<of_type>(val_min));
|
|
||||||
CHECK(value_in_range_of<of_type>(val_min2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_min));
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_min2));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_in_range)
|
|
||||||
{
|
|
||||||
CHECK(value_in_range_of<of_type>(val_max));
|
|
||||||
CHECK(value_in_range_of<of_type>(val_max2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_max));
|
|
||||||
CHECK_FALSE(value_in_range_of<of_type>(val_max2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE(bugprone-throwing-static-initialization)
|
// NOLINTNEXTLINE(bugprone-throwing-static-initialization)
|
||||||
TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
|
TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
|
||||||
|
|||||||
+2
-75
@@ -22,84 +22,11 @@ using nlohmann::json;
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
using bytes = std::vector<std::uint8_t>;
|
using bytes = std::vector<std::uint8_t>;
|
||||||
|
|
||||||
/// @return the string with the given bytes
|
/// @return the string with the given bytes
|
||||||
|
|||||||
+2
-77
@@ -18,6 +18,8 @@ using nlohmann::json;
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -857,83 +859,6 @@ TEST_CASE("BSON input/output_adapters")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("Incomplete BSON Input")
|
TEST_CASE("Incomplete BSON Input")
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-77
@@ -19,84 +19,9 @@ using nlohmann::json;
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("CBOR")
|
TEST_CASE("CBOR")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,84 +22,9 @@ using nlohmann::json;
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("MessagePack")
|
TEST_CASE("MessagePack")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -199,28 +199,6 @@ struct adl_serializer<NonDefaultConstructible>
|
|||||||
};
|
};
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
// for #2824
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit sax_no_exception(json& j)
|
|
||||||
: nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>(j, false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
|
|
||||||
{
|
|
||||||
error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string* error_string;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string* sax_no_exception::error_string = nullptr;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// for #2982
|
// for #2982
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -723,16 +701,6 @@ TEST_CASE("regression tests 2")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #2824 - encoding of json::exception::what()")
|
|
||||||
{
|
|
||||||
json j;
|
|
||||||
sax_no_exception sax(j);
|
|
||||||
|
|
||||||
CHECK(!json::sax_parse("xyz", &sax));
|
|
||||||
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
|
|
||||||
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("issue #2825 - Properly constrain the basic_json conversion operator")
|
SECTION("issue #2825 - Properly constrain the basic_json conversion operator")
|
||||||
{
|
{
|
||||||
static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "ordered_json must be copy assignable");
|
static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "ordered_json must be copy assignable");
|
||||||
|
|||||||
@@ -17,84 +17,9 @@ using nlohmann::json;
|
|||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
#include "round_trip_corpus.hpp"
|
#include "round_trip_corpus.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
#include "sax_countdown.hpp"
|
||||||
|
using utils::SaxCountdown;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class SaxCountdown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SaxCountdown(const int count) : events_left(count)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool null()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool boolean(bool /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_integer(json::number_integer_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_unsigned(json::number_unsigned_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool binary(std::vector<std::uint8_t>& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key(std::string& /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_object()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start_array(std::size_t /*unused*/)
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool end_array()
|
|
||||||
{
|
|
||||||
return events_left-- > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int events_left = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("UBJSON")
|
TEST_CASE("UBJSON")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
// __ _____ _____ _____
|
||||||
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||||
|
// | | |__ | | | | | | version 3.12.0
|
||||||
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// shared between unit-32bit.cpp (which must keep including this header,
|
||||||
|
// because JSON_32bitTest=ONLY builds only that file) and unit-bjdata.cpp
|
||||||
|
|
||||||
|
#include <climits> // CHAR_BIT
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
|
||||||
|
struct trait_test_arg
|
||||||
|
{
|
||||||
|
using of_type = OfType;
|
||||||
|
using type = T;
|
||||||
|
static constexpr bool min_in_range = MinInRange;
|
||||||
|
static constexpr bool max_in_range = MaxInRange;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test) // NOLINT(readability-math-missing-parentheses)
|
||||||
|
{
|
||||||
|
using nlohmann::detail::value_in_range_of;
|
||||||
|
|
||||||
|
using of_type = typename T::of_type;
|
||||||
|
using type = typename T::type;
|
||||||
|
constexpr bool min_in_range = T::min_in_range;
|
||||||
|
constexpr bool max_in_range = T::max_in_range;
|
||||||
|
|
||||||
|
type const val_min = std::numeric_limits<type>::min();
|
||||||
|
type const val_min2 = val_min + 1;
|
||||||
|
type const val_max = std::numeric_limits<type>::max();
|
||||||
|
type const val_max2 = val_max - 1;
|
||||||
|
|
||||||
|
REQUIRE(CHAR_BIT == 8);
|
||||||
|
|
||||||
|
std::string of_type_str;
|
||||||
|
if (std::is_unsigned<of_type>::value)
|
||||||
|
{
|
||||||
|
of_type_str += "u";
|
||||||
|
}
|
||||||
|
of_type_str += "int";
|
||||||
|
of_type_str += std::to_string(sizeof(of_type) * 8);
|
||||||
|
|
||||||
|
INFO("of_type := ", of_type_str);
|
||||||
|
|
||||||
|
std::string type_str;
|
||||||
|
if (std::is_unsigned<type>::value)
|
||||||
|
{
|
||||||
|
type_str += "u";
|
||||||
|
}
|
||||||
|
type_str += "int";
|
||||||
|
type_str += std::to_string(sizeof(type) * 8);
|
||||||
|
|
||||||
|
INFO("type := ", type_str);
|
||||||
|
|
||||||
|
CAPTURE(val_min);
|
||||||
|
CAPTURE(min_in_range);
|
||||||
|
CAPTURE(val_max);
|
||||||
|
CAPTURE(max_in_range);
|
||||||
|
|
||||||
|
if (min_in_range)
|
||||||
|
{
|
||||||
|
CHECK(value_in_range_of<of_type>(val_min));
|
||||||
|
CHECK(value_in_range_of<of_type>(val_min2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CHECK_FALSE(value_in_range_of<of_type>(val_min));
|
||||||
|
CHECK_FALSE(value_in_range_of<of_type>(val_min2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_in_range)
|
||||||
|
{
|
||||||
|
CHECK(value_in_range_of<of_type>(val_max));
|
||||||
|
CHECK(value_in_range_of<of_type>(val_max2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CHECK_FALSE(value_in_range_of<of_type>(val_max));
|
||||||
|
CHECK_FALSE(value_in_range_of<of_type>(val_max2));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user