//----------------------------------------------------------------------------- // ___ __ _ _ // / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ // / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / // / ___/ (_| | | \__ \ __/ /__| | | | | < // \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . // //----------------------------------------------------------------------------- // Author: Kurt Sassenrath // Module: msgpack // // Unpacker tests for unsigned integers. // // Copyright (c) 2023 Kurt Sassenrath. // // License TBD. //----------------------------------------------------------------------------- #include "test_unpacker.h" #include using namespace boost::ut; namespace { constexpr auto equal(auto a, auto b) { return std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b)); } template constexpr std::array make_bytes(Bytes&&... bytes) { return {std::byte(std::forward(bytes))...}; } template constexpr bool test_unpack(msgpack::unpacker unpacker) noexcept { auto wrong_type = tl::make_unexpected(msgpack::error::wrong_type); return std::same_as || unpacker.unpack() == wrong_type; } template constexpr bool test_types(msgpack::unpacker unpacker) noexcept { return ((test_unpack(unpacker)) && ...); } template constexpr bool expect_invalid(msgpack::unpacker unpacker) noexcept { return test_types(unpacker); } template struct get_marker; template <> struct get_marker { static constexpr std::byte marker = msgpack::format::uint8::marker; }; template <> struct get_marker { static constexpr std::byte marker = msgpack::format::uint16::marker; }; template <> struct get_marker { static constexpr std::byte marker = msgpack::format::uint32::marker; }; template <> struct get_marker { static constexpr std::byte marker = msgpack::format::uint64::marker; }; // Utilize rapidcheck to generate random packed payloads, and unpacking the // correct value template auto check_unpack_integer() noexcept { auto result = rc::check([](PackType value) { std::vector payload = {get_marker::marker}; auto bytes = host_to_be( std::bit_cast>(value)); std::copy(bytes.begin(), bytes.end(), std::back_inserter(payload)); msgpack::unpacker unpacker(payload); auto unpacked_value = unpacker.unpack(); if (std::numeric_limits::max() < value || std::numeric_limits::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_unsigned_types = [] { "unpacker::unpack"_test = [] { expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); }; "unpacker::unpack"_test = [] { expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); }; "unpacker::unpack"_test = [] { expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); }; "unpacker::unpack"_test = [] { expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); expect(check_unpack_integer()); }; };