Move the custom BinaryType tests into their own translation unit

The two sections added to unit-regression2.cpp brought a third full
basic_json instantiation into a translation unit that was already large.
With Clang on MinGW that pushed the object over the reach of a 32-bit
relocation and test-regression2_cpp20.exe failed to link:

    relocation truncated to fit: IMAGE_REL_AMD64_REL32 against `.rdata'

unit-regression2.cpp is restored to exactly what it was before, and the
coverage moves to unit-custom-binary-type.cpp, next to the object and array
type tests it belongs with. The signed value type is now also covered in
C++11, where std::byte is not available.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-08-28 19:02:04 +00:00
parent 3b28316ee4
commit 8ce64b9c16
2 changed files with 79 additions and 33 deletions
+79
View File
@@ -0,0 +1,79 @@
// __ _____ _____ _____
// __| | __| | | | 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
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
#ifdef JSON_HAS_CPP_17
#include <cstddef>
#endif
namespace
{
// a BinaryType whose value type is signed: the elements must still be
// processed as the numbers 0..255
using char_binary_json = nlohmann::basic_json <
std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t,
double, std::allocator, nlohmann::adl_serializer, std::vector<char>, void >;
#ifdef JSON_HAS_CPP_17
// a BinaryType whose value type is not an integer type at all
using byte_binary_json = nlohmann::basic_json <
std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t,
double, std::allocator, nlohmann::adl_serializer, std::vector<std::byte>, void >;
#endif
} // namespace
TEST_CASE("binary type whose value type is not std::uint8_t")
{
SECTION("a signed value type does not dump negative numbers")
{
const std::vector<char> chars{'\0', '\x01', '\xFF'};
CHECK(char_binary_json::binary(chars).dump() == R"({"bytes":[0,1,255],"subtype":null})");
CHECK(char_binary_json::binary(chars, 42).dump() == R"({"bytes":[0,1,255],"subtype":42})");
CHECK(char_binary_json::binary({}).dump() == R"({"bytes":[],"subtype":null})");
}
SECTION("the default binary type is unchanged")
{
CHECK(nlohmann::json::binary({0, 1, 255}, 42).dump() == R"({"bytes":[0,1,255],"subtype":42})");
}
#ifdef JSON_HAS_CPP_17
SECTION("dumping a value type that is not an integer")
{
const std::vector<std::byte> bytes{std::byte{0}, std::byte{1}, std::byte{0xFF}};
CHECK(byte_binary_json::binary(bytes).dump() == R"({"bytes":[0,1,255],"subtype":null})");
CHECK(byte_binary_json::binary(bytes, 42).dump() == R"({"bytes":[0,1,255],"subtype":42})");
CHECK(byte_binary_json::binary({}).dump() == R"({"bytes":[],"subtype":null})");
}
SECTION("hashing and the binary formats")
{
const std::vector<std::byte> bytes{std::byte{0}, std::byte{1}, std::byte{0xFF}};
const auto j = byte_binary_json::binary(bytes);
CHECK(std::hash<byte_binary_json> {}(j) == std::hash<byte_binary_json> {}(j));
CHECK(byte_binary_json::from_cbor(byte_binary_json::to_cbor(j)) == j);
CHECK(byte_binary_json::from_msgpack(byte_binary_json::to_msgpack(j)) == j);
// UBJSON has no binary type, so binary values are written as an array
CHECK(byte_binary_json::from_ubjson(byte_binary_json::to_ubjson(j)) == byte_binary_json({0, 1, 255}));
}
#endif
}
-33
View File
@@ -1154,39 +1154,6 @@ TEST_CASE("regression tests 2")
CHECK(!default_json.is_binary());
}
SECTION("dumping a binary value with a custom BinaryType")
{
// the elements of a binary value are dumped as the numbers 0..255,
// whatever the value type of the configured BinaryType is
const std::vector<std::byte> bytes{std::byte{0}, std::byte{1}, std::byte{0xFF}};
CHECK(json_4804::binary(bytes).dump() == R"({"bytes":[0,1,255],"subtype":null})");
CHECK(json_4804::binary(bytes, 42).dump() == R"({"bytes":[0,1,255],"subtype":42})");
CHECK(json_4804::binary({}).dump() == R"({"bytes":[],"subtype":null})");
// a signed byte type must not dump negative numbers
using json_char_binary = nlohmann::basic_json <
std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t,
double, std::allocator, nlohmann::adl_serializer, std::vector<char>, void >;
const std::vector<char> chars{'\0', '\x01', '\xFF'};
CHECK(json_char_binary::binary(chars).dump() == R"({"bytes":[0,1,255],"subtype":null})");
// the default binary type is unchanged
CHECK(json::binary({0, 1, 255}, 42).dump() == R"({"bytes":[0,1,255],"subtype":42})");
}
SECTION("hashing and UBJSON with a custom BinaryType")
{
const std::vector<std::byte> bytes{std::byte{0}, std::byte{1}, std::byte{0xFF}};
const auto j = json_4804::binary(bytes);
CHECK(std::hash<json_4804> {}(j) == std::hash<json_4804> {}(j));
CHECK(json_4804::from_cbor(json_4804::to_cbor(j)) == j);
CHECK(json_4804::from_msgpack(json_4804::to_msgpack(j)) == j);
// UBJSON has no binary type, so binary values are written as arrays
CHECK(json_4804::from_ubjson(json_4804::to_ubjson(j)) == json_4804({0, 1, 255}));
}
SECTION("discussion #4209 - custom BinaryType extraction from parsed array")
{
// Test that extracting a custom BinaryType from a parsed JSON array still works