Refactor packer tests to make recompilation faster
This commit is contained in:
parent
eb7a02d5c4
commit
c0945246de
@ -26,24 +26,6 @@ cc_test(
|
|||||||
deps = ["common"],
|
deps = ["common"],
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_test(
|
|
||||||
name = "packer",
|
|
||||||
size = "small",
|
|
||||||
srcs = [
|
|
||||||
"test_packer.cpp",
|
|
||||||
],
|
|
||||||
deps = ["common"],
|
|
||||||
)
|
|
||||||
|
|
||||||
cc_test(
|
|
||||||
name = "packer_rc",
|
|
||||||
size = "small",
|
|
||||||
srcs = [
|
|
||||||
"test_packer_rc.cpp",
|
|
||||||
],
|
|
||||||
deps = ["common", "@rapidcheck"],
|
|
||||||
)
|
|
||||||
|
|
||||||
cc_test(
|
cc_test(
|
||||||
name = "writer",
|
name = "writer",
|
||||||
size = "small",
|
size = "small",
|
||||||
|
|||||||
9
tests/msgpack/packer/BUILD
Normal file
9
tests/msgpack/packer/BUILD
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
cc_test(
|
||||||
|
name = "packer",
|
||||||
|
size = "small",
|
||||||
|
srcs = glob([
|
||||||
|
"*.cpp",
|
||||||
|
"*.h",
|
||||||
|
]),
|
||||||
|
deps = ["//tests/msgpack:common", "@rapidcheck"],
|
||||||
|
)
|
||||||
63
tests/msgpack/packer/bytes.cpp
Normal file
63
tests/msgpack/packer/bytes.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, byte types
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
suite pack_bytes = [] {
|
||||||
|
#if 0
|
||||||
|
// Byte ranges -> Binary
|
||||||
|
"packer::pack<std::span<std::byte>>"_test = [] {
|
||||||
|
expect(test_deduced<std::span<std::byte const>>());
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
"packer::pack<std::array<std::byte, N>>"_test = [] {
|
||||||
|
{
|
||||||
|
constexpr auto data = test::make_bytes(0x01, 0x02, 0x03, 0x04);
|
||||||
|
constexpr auto expected =
|
||||||
|
test::make_bytes(0xc4, 0x04, 0x01, 0x02, 0x03, 0x04);
|
||||||
|
std::array<std::byte, std::size(expected)> payload;
|
||||||
|
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(data));
|
||||||
|
expect(std::ranges::equal(payload, expected));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr std::array<std::byte, 256> data{};
|
||||||
|
constexpr std::array<std::byte, 259> expected{
|
||||||
|
std::byte(0xc5), std::byte(0x01), std::byte(0x00)};
|
||||||
|
std::array<std::byte, std::size(expected)> payload;
|
||||||
|
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(data));
|
||||||
|
expect(std::ranges::equal(payload, expected));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr std::array<std::byte, 65536> data{};
|
||||||
|
constexpr std::array<std::byte, std::size(data) + 5> expected{
|
||||||
|
std::byte(0xc6), std::byte(0x00), std::byte(0x01),
|
||||||
|
std::byte(0x00), std::byte(0x00)};
|
||||||
|
std::array<std::byte, std::size(expected)> payload;
|
||||||
|
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(data));
|
||||||
|
expect(std::ranges::equal(payload, expected));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
63
tests/msgpack/packer/ranges.cpp
Normal file
63
tests/msgpack/packer/ranges.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, ranges (for types that serialize to array / map formats)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr bool expect_equal(auto const& expected, auto const& actual) {
|
||||||
|
if (!std::ranges::equal(expected, actual)) {
|
||||||
|
fmt::print("\n\tExpected: ");
|
||||||
|
for (auto x : expected) {
|
||||||
|
fmt::print("{:02x} ", x);
|
||||||
|
}
|
||||||
|
fmt::print("\n\t Actual: ");
|
||||||
|
for (auto x : actual) {
|
||||||
|
fmt::print("{:02x} ", x);
|
||||||
|
}
|
||||||
|
fmt::print("\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
suite pack_ranges = [] {
|
||||||
|
"packer::pack<std::array/std::span<int>>"_test = [] {
|
||||||
|
constexpr auto data_array = std::to_array<int>({5, 10, 15, 20});
|
||||||
|
constexpr auto expected = test::make_bytes(0x94, 0x05, 0xa, 0xf, 0x14);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::array<std::byte, std::size(expected)> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(data_array));
|
||||||
|
expect(expect_equal(std::span(expected), payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::span data_span{data_array};
|
||||||
|
std::array<std::byte, std::size(expected)> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(data_span));
|
||||||
|
expect(expect_equal(expected, payload));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
71
tests/msgpack/packer/signed.cpp
Normal file
71
tests/msgpack/packer/signed.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, signed ints.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
#include <rapidcheck.h>
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto check_pack() {
|
||||||
|
return rc::check([](T value) {
|
||||||
|
std::array<std::byte, 16> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
if (!packer.pack(value)) return false;
|
||||||
|
|
||||||
|
if (value < 128 && value >= -32) {
|
||||||
|
// positive_fixint/negative_fixint
|
||||||
|
return packer.tell() == 1
|
||||||
|
&& payload[0] == static_cast<std::byte>(value);
|
||||||
|
} else if (within<std::int8_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::int8::marker
|
||||||
|
&& verify_packed<std::int8_t>(packer, value);
|
||||||
|
} else if (within<std::int16_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::int16::marker
|
||||||
|
&& verify_packed<std::int16_t>(packer, value);
|
||||||
|
} else if (within<std::int32_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::int32::marker
|
||||||
|
&& verify_packed<std::int32_t>(packer, value);
|
||||||
|
} else {
|
||||||
|
return payload[0] == msgpack::format::int64::marker
|
||||||
|
&& verify_packed<std::int64_t>(packer, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
suite pack_signed_types = [] {
|
||||||
|
"packer::pack<std::int8_t>"_test = [] {
|
||||||
|
expect(check_pack<std::int8_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::int16_t>"_test = [] {
|
||||||
|
expect(check_pack<std::int16_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::int32_t>"_test = [] {
|
||||||
|
expect(check_pack<std::int32_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::int64_t>"_test = [] {
|
||||||
|
expect(check_pack<std::int64_t>());
|
||||||
|
};
|
||||||
|
};
|
||||||
50
tests/msgpack/packer/simple_types.cpp
Normal file
50
tests/msgpack/packer/simple_types.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, simple types
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
suite pack_simple_types = [] {
|
||||||
|
"packer::pack<nil>"_test = [] {
|
||||||
|
std::array<std::byte, 8> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(msgpack::nil{}));
|
||||||
|
expect(packer.tell() == 1);
|
||||||
|
expect(payload[0] == std::byte{0xc0});
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<invalid>"_test = [] {
|
||||||
|
std::array<std::byte, 8> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(msgpack::invalid{}));
|
||||||
|
expect(packer.tell() == 1);
|
||||||
|
expect(payload[0] == std::byte{0xc1});
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<bool>"_test = [] {
|
||||||
|
std::array<std::byte, 8> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
expect(!!packer.pack(false));
|
||||||
|
expect(packer.tell() == 1);
|
||||||
|
expect(payload[0] == std::byte{0xc2});
|
||||||
|
expect(!!packer.pack(true));
|
||||||
|
expect(packer.tell() == 2);
|
||||||
|
expect(payload[1] == std::byte{0xc3});
|
||||||
|
};
|
||||||
|
};
|
||||||
46
tests/msgpack/packer/strings.cpp
Normal file
46
tests/msgpack/packer/strings.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, strings.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
#include <rapidcheck.h>
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <std::unsigned_integral LenType, typename StrType = std::string>
|
||||||
|
auto check_string() {
|
||||||
|
return rc::check([](LenType value) {
|
||||||
|
auto str = *rc::gen::container<std::string>(
|
||||||
|
value, rc::gen::character<char>());
|
||||||
|
std::vector<std::byte> payload;
|
||||||
|
payload.resize(value + 32);
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
if (!packer.pack(str)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
suite pack_strings = [] {
|
||||||
|
"packer::pack<std::string>"_test = [] {
|
||||||
|
expect(check_string<std::uint8_t>());
|
||||||
|
expect(check_string<std::uint16_t>());
|
||||||
|
};
|
||||||
|
};
|
||||||
42
tests/msgpack/packer/test_packer.h
Normal file
42
tests/msgpack/packer/test_packer.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, common code.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#ifndef tests_msgpack_packer_6e9a5bf8e14223bc
|
||||||
|
#define tests_msgpack_packer_6e9a5bf8e14223bc
|
||||||
|
|
||||||
|
#include "parselink/msgpack/core/packer.h"
|
||||||
|
|
||||||
|
#include "test_utils.h"
|
||||||
|
|
||||||
|
template <std::integral T>
|
||||||
|
constexpr auto within(auto value) noexcept {
|
||||||
|
return value >= std::numeric_limits<T>::min()
|
||||||
|
&& value <= std::numeric_limits<T>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::integral T>
|
||||||
|
constexpr auto verify_packed(auto const& packer, auto value) noexcept {
|
||||||
|
std::array<std::byte, (std::numeric_limits<T>::digits + 7) / 8> raw;
|
||||||
|
if (packer.tell() != 1 + raw.size()) return false;
|
||||||
|
|
||||||
|
auto packed = packer.subspan().subspan(1);
|
||||||
|
be_to_host(packed.begin(), packed.end(), raw.begin());
|
||||||
|
auto actual = std::bit_cast<T>(raw);
|
||||||
|
return actual == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // tests_msgpack_packer_6e9a5bf8e14223bc
|
||||||
71
tests/msgpack/packer/unsigned.cpp
Normal file
71
tests/msgpack/packer/unsigned.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ___ __ _ _
|
||||||
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||||
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||||
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||||
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Author: Kurt Sassenrath
|
||||||
|
// Module: msgpack
|
||||||
|
//
|
||||||
|
// Packer tests, unsigned ints.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Kurt Sassenrath.
|
||||||
|
//
|
||||||
|
// License TBD.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "test_packer.h"
|
||||||
|
|
||||||
|
#include <rapidcheck.h>
|
||||||
|
|
||||||
|
using namespace boost::ut;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto check_unsigned() {
|
||||||
|
return rc::check([](T value) {
|
||||||
|
std::array<std::byte, 16> payload;
|
||||||
|
msgpack::packer packer(payload);
|
||||||
|
if (!packer.pack(value)) return false;
|
||||||
|
|
||||||
|
if (value < 128) {
|
||||||
|
// positive_fixint
|
||||||
|
return packer.tell() == 1
|
||||||
|
&& payload[0] == static_cast<std::byte>(value);
|
||||||
|
} else if (within<std::uint8_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::uint8::marker
|
||||||
|
&& verify_packed<std::uint8_t>(packer, value);
|
||||||
|
} else if (within<std::uint16_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::uint16::marker
|
||||||
|
&& verify_packed<std::uint16_t>(packer, value);
|
||||||
|
} else if (within<std::uint32_t>(value)) {
|
||||||
|
return payload[0] == msgpack::format::uint32::marker
|
||||||
|
&& verify_packed<std::uint32_t>(packer, value);
|
||||||
|
} else {
|
||||||
|
return payload[0] == msgpack::format::uint64::marker
|
||||||
|
&& verify_packed<std::uint64_t>(packer, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
suite packer_unsigned_ints = [] {
|
||||||
|
"packer::pack<std::uint8_t>"_test = [] {
|
||||||
|
expect(check_unsigned<std::uint8_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::uint16_t>"_test = [] {
|
||||||
|
expect(check_unsigned<std::uint16_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::uint32_t>"_test = [] {
|
||||||
|
expect(check_unsigned<std::uint32_t>());
|
||||||
|
};
|
||||||
|
|
||||||
|
"packer::pack<std::uint64_t>"_test = [] {
|
||||||
|
expect(check_unsigned<std::uint64_t>());
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,306 +0,0 @@
|
|||||||
//-----------------------------------------------------------------------------
|
|
||||||
// ___ __ _ _
|
|
||||||
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
|
||||||
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
|
||||||
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
|
||||||
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Author: Kurt Sassenrath
|
|
||||||
// Module: msgpack
|
|
||||||
//
|
|
||||||
// Default packer tests.
|
|
||||||
//
|
|
||||||
// Copyright (c) 2023 Kurt Sassenrath.
|
|
||||||
//
|
|
||||||
// License TBD.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "parselink/msgpack/core/packer.h"
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <fmt/ranges.h>
|
|
||||||
|
|
||||||
#include "rng.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <boost/ut.hpp>
|
|
||||||
#include <chrono>
|
|
||||||
#include <rapidcheck.h>
|
|
||||||
|
|
||||||
using namespace boost::ut;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct fmt::formatter<msgpack::invalid> : fmt::formatter<std::string_view> {
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(msgpack::nil const&, FormatContext& ctx) const {
|
|
||||||
return fmt::format_to(ctx.out(), "{{msgpack::invalid}}");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct fmt::formatter<msgpack::nil> : fmt::formatter<std::string_view> {
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(msgpack::nil const&, FormatContext& ctx) const {
|
|
||||||
return fmt::format_to(ctx.out(), "{{msgpack::nil}}");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct fmt::formatter<msgpack::map_desc> : fmt::formatter<std::string_view> {
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(msgpack::map_desc const& value, FormatContext& ctx) const {
|
|
||||||
return fmt::format_to(
|
|
||||||
ctx.out(), "{{msgpack::map_desc: {}}}", value.count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct fmt::formatter<msgpack::array_desc> : fmt::formatter<std::string_view> {
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(msgpack::array_desc const& value, FormatContext& ctx) const {
|
|
||||||
return fmt::format_to(
|
|
||||||
ctx.out(), "{{msgpack::array_desc: {}}}", value.count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr auto within(auto value) noexcept {
|
|
||||||
return value >= std::numeric_limits<T>::min()
|
|
||||||
&& value <= std::numeric_limits<T>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::byte marker_for;
|
|
||||||
|
|
||||||
template <std::integral T>
|
|
||||||
constexpr auto verify_packed(auto const& packer, auto value) noexcept {
|
|
||||||
std::array<std::byte, (std::numeric_limits<T>::digits + 7) / 8> raw;
|
|
||||||
if (packer.tell() != 1 + raw.size()) return false;
|
|
||||||
|
|
||||||
auto packed = packer.subspan().subspan(1);
|
|
||||||
be_to_host(packed.begin(), packed.end(), raw.begin());
|
|
||||||
auto actual = std::bit_cast<T>(raw);
|
|
||||||
return actual == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
auto check_signed() {
|
|
||||||
return rc::check([](T value) {
|
|
||||||
std::array<std::byte, 16> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
if (!packer.pack(value)) return false;
|
|
||||||
|
|
||||||
if (value < 128 && value >= -32) {
|
|
||||||
// positive_fixint/negative_fixint
|
|
||||||
return packer.tell() == 1
|
|
||||||
&& payload[0] == static_cast<std::byte>(value);
|
|
||||||
} else if (within<std::int8_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::int8::marker
|
|
||||||
&& verify_packed<std::int8_t>(packer, value);
|
|
||||||
} else if (within<std::int16_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::int16::marker
|
|
||||||
&& verify_packed<std::int16_t>(packer, value);
|
|
||||||
} else if (within<std::int32_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::int32::marker
|
|
||||||
&& verify_packed<std::int32_t>(packer, value);
|
|
||||||
} else {
|
|
||||||
return payload[0] == msgpack::format::int64::marker
|
|
||||||
&& verify_packed<std::int64_t>(packer, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
auto check_unsigned() {
|
|
||||||
return rc::check([](T value) {
|
|
||||||
std::array<std::byte, 16> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
if (!packer.pack(value)) return false;
|
|
||||||
|
|
||||||
if (value < 128) {
|
|
||||||
// positive_fixint
|
|
||||||
return packer.tell() == 1
|
|
||||||
&& payload[0] == static_cast<std::byte>(value);
|
|
||||||
} else if (within<std::uint8_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::uint8::marker
|
|
||||||
&& verify_packed<std::uint8_t>(packer, value);
|
|
||||||
} else if (within<std::uint16_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::uint16::marker
|
|
||||||
&& verify_packed<std::uint16_t>(packer, value);
|
|
||||||
} else if (within<std::uint32_t>(value)) {
|
|
||||||
return payload[0] == msgpack::format::uint32::marker
|
|
||||||
&& verify_packed<std::uint32_t>(packer, value);
|
|
||||||
} else {
|
|
||||||
return payload[0] == msgpack::format::uint64::marker
|
|
||||||
&& verify_packed<std::uint64_t>(packer, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::unsigned_integral LenType, typename StrType = std::string>
|
|
||||||
auto check_string() {
|
|
||||||
return rc::check([](LenType value) {
|
|
||||||
auto str = *rc::gen::container<std::string>(
|
|
||||||
value, rc::gen::character<char>());
|
|
||||||
std::vector<std::byte> payload;
|
|
||||||
payload.resize(value + 32);
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
if (!packer.pack(str)) return false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
suite packer_single_format = [] {
|
|
||||||
"packer::pack<nil>"_test = [] {
|
|
||||||
std::array<std::byte, 8> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(msgpack::nil{}));
|
|
||||||
expect(packer.tell() == 1);
|
|
||||||
expect(payload[0] == std::byte{0xc0});
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<invalid>"_test = [] {
|
|
||||||
std::array<std::byte, 8> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(msgpack::invalid{}));
|
|
||||||
expect(packer.tell() == 1);
|
|
||||||
expect(payload[0] == std::byte{0xc1});
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<bool>"_test = [] {
|
|
||||||
std::array<std::byte, 8> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(false));
|
|
||||||
expect(packer.tell() == 1);
|
|
||||||
expect(payload[0] == std::byte{0xc2});
|
|
||||||
expect(!!packer.pack(true));
|
|
||||||
expect(packer.tell() == 2);
|
|
||||||
expect(payload[1] == std::byte{0xc3});
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::uint8_t>"_test = [] {
|
|
||||||
expect(check_unsigned<std::uint8_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::uint16_t>"_test = [] {
|
|
||||||
expect(check_unsigned<std::uint16_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::uint32_t>"_test = [] {
|
|
||||||
expect(check_unsigned<std::uint32_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::uint64_t>"_test = [] {
|
|
||||||
expect(check_unsigned<std::uint64_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::int8_t>"_test = [] {
|
|
||||||
expect(check_signed<std::int8_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::int16_t>"_test = [] {
|
|
||||||
expect(check_signed<std::int16_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::int32_t>"_test = [] {
|
|
||||||
expect(check_signed<std::int32_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::int64_t>"_test = [] {
|
|
||||||
expect(check_signed<std::int64_t>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::string>"_test = [] {
|
|
||||||
expect(check_string<std::uint8_t>());
|
|
||||||
expect(check_string<std::uint16_t>());
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#if 0
|
|
||||||
// Strings
|
|
||||||
"packer::pack<std::string_view>"_test = [] {
|
|
||||||
expect(test_deduced<std::string_view>());
|
|
||||||
};
|
|
||||||
#if 0
|
|
||||||
"packer::pack<char const*>"_test = [] {
|
|
||||||
expect(test_deduced<char const*>());
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Byte ranges -> Binary
|
|
||||||
|
|
||||||
"packer::pack<std::span<std::byte>>"_test = [] {
|
|
||||||
expect(test_deduced<std::span<std::byte const>>());
|
|
||||||
};
|
|
||||||
|
|
||||||
"packer::pack<std::array<std::byte, N>>"_test = [] {
|
|
||||||
{
|
|
||||||
constexpr auto data = make_bytes(0x01, 0x02, 0x03, 0x04);
|
|
||||||
constexpr auto expected =
|
|
||||||
make_bytes(0xc4, 0x04, 0x01, 0x02, 0x03, 0x04);
|
|
||||||
std::array<std::byte, std::size(expected)> payload;
|
|
||||||
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(data));
|
|
||||||
expect(std::ranges::equal(payload, expected));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
constexpr std::array<std::byte, 256> data{};
|
|
||||||
constexpr std::array<std::byte, 259> expected{
|
|
||||||
std::byte(0xc5), std::byte(0x01), std::byte(0x00)};
|
|
||||||
std::array<std::byte, std::size(expected)> payload;
|
|
||||||
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(data));
|
|
||||||
expect(std::ranges::equal(payload, expected));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
constexpr std::array<std::byte, 65536> data{};
|
|
||||||
constexpr std::array<std::byte, std::size(data) + 5> expected{
|
|
||||||
std::byte(0xc6), std::byte(0x00), std::byte(0x01),
|
|
||||||
std::byte(0x00), std::byte(0x00)};
|
|
||||||
std::array<std::byte, std::size(expected)> payload;
|
|
||||||
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(data));
|
|
||||||
expect(std::ranges::equal(payload, expected));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// array_desc - Just the header of the array.
|
|
||||||
"packer::pack<msgpack::array_desc>"_test = [] {
|
|
||||||
expect(test_deduced<msgpack::array_desc>());
|
|
||||||
};
|
|
||||||
|
|
||||||
// map_desc - Just the header of the map.
|
|
||||||
"packer::pack<msgpack::map_desc>"_test = [] {
|
|
||||||
expect(test_deduced<msgpack::map_desc>());
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
suite packer_ranges = [] {
|
|
||||||
"packer::pack<std::array/std::span<int>>"_test = [] {
|
|
||||||
constexpr auto data_array = std::to_array<int>({5, 10, 15, 20});
|
|
||||||
constexpr auto expected =
|
|
||||||
make_bytes(0x94, 0xd0, 0x05, 0xd0, 0xa, 0xd0, 0xf, 0xd0, 0x14);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::array<std::byte, std::size(expected)> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(data_array));
|
|
||||||
expect(std::ranges::equal(payload, expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::span data_span{data_array};
|
|
||||||
std::array<std::byte, std::size(expected)> payload;
|
|
||||||
msgpack::packer packer(payload);
|
|
||||||
expect(!!packer.pack(data_span));
|
|
||||||
expect(std::ranges::equal(payload, expected));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
Loading…
Reference in New Issue
Block a user