106 lines
3.6 KiB
C++
106 lines
3.6 KiB
C++
//-----------------------------------------------------------------------------
|
|
// ___ __ _ _
|
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// Author: Kurt Sassenrath
|
|
// Module: msgpack
|
|
//
|
|
// Unpacker tests for signed integer values
|
|
//
|
|
// Copyright (c) 2023 Kurt Sassenrath.
|
|
//
|
|
// License TBD.
|
|
//-----------------------------------------------------------------------------
|
|
#include "test_unpacker.h"
|
|
|
|
#include <rapidcheck.h>
|
|
|
|
using namespace boost::ut;
|
|
|
|
namespace {
|
|
|
|
template <typename T>
|
|
struct get_marker;
|
|
|
|
template <>
|
|
struct get_marker<std::int8_t> {
|
|
static constexpr std::byte marker = msgpack::format::int8::marker;
|
|
};
|
|
|
|
template <>
|
|
struct get_marker<std::int16_t> {
|
|
static constexpr std::byte marker = msgpack::format::int16::marker;
|
|
};
|
|
|
|
template <>
|
|
struct get_marker<std::int32_t> {
|
|
static constexpr std::byte marker = msgpack::format::int32::marker;
|
|
};
|
|
|
|
template <>
|
|
struct get_marker<std::int64_t> {
|
|
static constexpr std::byte marker = msgpack::format::int64::marker;
|
|
};
|
|
|
|
// Utilize rapidcheck to generate random packed payloads, and unpacking the
|
|
// correct value
|
|
template <typename PackType, typename UnpackType>
|
|
auto check_unpack_integer() noexcept {
|
|
auto result = rc::check([](PackType value) {
|
|
std::vector<std::byte> payload = {get_marker<PackType>::marker};
|
|
auto bytes = host_to_be(
|
|
std::bit_cast<std::array<std::byte, sizeof(PackType)>>(value));
|
|
std::copy(bytes.begin(), bytes.end(), std::back_inserter(payload));
|
|
msgpack::unpacker unpacker(payload);
|
|
auto unpacked_value = unpacker.unpack<UnpackType>();
|
|
if (std::numeric_limits<UnpackType>::max() < value
|
|
|| std::numeric_limits<UnpackType>::min() > value) {
|
|
return unpacked_value
|
|
== tl::make_unexpected(msgpack::error::will_truncate);
|
|
} else {
|
|
return unpacked_value.has_value() && unpacked_value == value;
|
|
}
|
|
});
|
|
if (!result) {
|
|
fmt::print("Failed on {}\n",
|
|
std::source_location::current().function_name());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
suite unpack_signed_types = [] {
|
|
"unpacker::unpack<std::int8_t>"_test = [] {
|
|
expect(check_unpack_integer<std::int8_t, std::int8_t>());
|
|
expect(check_unpack_integer<std::int16_t, std::int8_t>());
|
|
expect(check_unpack_integer<std::int32_t, std::int8_t>());
|
|
expect(check_unpack_integer<std::int64_t, std::int8_t>());
|
|
};
|
|
|
|
"unpacker::unpack<std::int16_t>"_test = [] {
|
|
expect(check_unpack_integer<std::int8_t, std::int16_t>());
|
|
expect(check_unpack_integer<std::int16_t, std::int16_t>());
|
|
expect(check_unpack_integer<std::int32_t, std::int16_t>());
|
|
expect(check_unpack_integer<std::int64_t, std::int16_t>());
|
|
};
|
|
|
|
"unpacker::unpack<std::int32_t>"_test = [] {
|
|
expect(check_unpack_integer<std::int8_t, std::int32_t>());
|
|
expect(check_unpack_integer<std::int16_t, std::int32_t>());
|
|
expect(check_unpack_integer<std::int32_t, std::int32_t>());
|
|
expect(check_unpack_integer<std::int64_t, std::int32_t>());
|
|
};
|
|
|
|
"unpacker::unpack<std::int64_t>"_test = [] {
|
|
expect(check_unpack_integer<std::int8_t, std::int64_t>());
|
|
expect(check_unpack_integer<std::int32_t, std::int64_t>());
|
|
expect(check_unpack_integer<std::int32_t, std::int64_t>());
|
|
expect(check_unpack_integer<std::int64_t, std::int64_t>());
|
|
};
|
|
};
|