parselink-old/tests/msgpack/test_writer.cpp

434 lines
16 KiB
C++

#include "parselink/msgpack/core/writer.h"
#include <boost/ut.hpp>
#include <string>
using namespace boost::ut;
namespace format = msgpack::format;
namespace {
template <typename... Bytes>
constexpr std::array<std::byte, sizeof...(Bytes)> make_bytes(Bytes&&... bytes) {
return {std::byte(std::forward<Bytes>(bytes))...};
}
template <typename T, std::size_t C = 1024>
struct oversized_array {
std::array<T, C> data;
std::size_t size;
};
constexpr auto to_bytes_array_oversized(auto const& container) {
oversized_array<std::byte> arr;
std::copy(std::begin(container), std::end(container), std::begin(arr.data));
arr.size = std::distance(std::begin(container), std::end(container));
return arr;
}
consteval auto generate_bytes(auto callable) {
constexpr auto oversized = to_bytes_array_oversized(callable());
std::array<std::byte, oversized.size> out;
std::copy(std::begin(oversized.data),
std::next(std::begin(oversized.data), oversized.size),
std::begin(out));
return out;
}
template <std::size_t A, std::size_t B>
consteval auto cat(
std::array<std::byte, A> const& a, std::array<std::byte, B> const& b) {
std::array<std::byte, A + B> out;
std::copy(std::begin(a), std::next(std::begin(a), std::size(a)),
std::begin(out));
std::copy(std::begin(b), std::next(std::begin(b), std::size(b)),
std::next(std::begin(out), std::size(a)));
return out;
}
template <typename T, typename Itr>
constexpr auto zip(T val, Itr begin, Itr end) {
std::vector<T> output;
for (auto itr = begin; itr != end; ++itr) {
output.emplace_back(val);
output.emplace_back(*itr);
}
return output;
}
template <typename T, typename Iterable>
constexpr auto zip(T val, Iterable const& itr) {
return zip(val, std::begin(itr), std::end(itr));
}
constexpr auto from_string_view(std::string_view sv) {
std::vector<std::byte> range;
range.resize(sv.size());
auto itr = range.begin();
for (auto c : sv) {
*itr = std::byte(c);
++itr;
}
return range;
}
constexpr auto make_contiguous_range(std::uint8_t start, std::uint8_t end) {
auto count = std::size_t(end) - std::size_t(start) + 1;
std::vector<std::byte> range;
range.resize(count);
for (auto i = std::size_t(start); i <= std::size_t(end); ++i) {
range[i - std::size_t(start)] = std::byte(i);
}
return range;
}
constexpr auto equal(auto a, auto b) {
return std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b));
}
} // namespace
suite writer = [] {
"writer empty span"_test = [] {
std::array<std::byte, 16> payload;
msgpack::writer writer(payload);
expect(writer.tell() == 0);
};
"writer::write<format::positive_fixint>"_test = [] {
using fmt = format::positive_fixint;
using error = msgpack::error;
std::array<std::byte, 2> payload;
auto constexpr expected = make_bytes(0x32, 0x55);
msgpack::writer writer(payload);
auto result = writer.write<fmt>(std::uint8_t{0x32});
expect(!!result);
expect(writer.tell() == 1);
expect(*writer.subspan().begin() == std::byte{0x32});
expect(writer.write<fmt>(std::uint8_t{0x82})
== tl::make_unexpected(error::bad_value));
writer.write(std::uint8_t{0x55});
expect(writer.tell() == 2);
expect(equal(writer.subspan(), expected));
expect(writer.write(std::uint8_t{0x01})
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::uint8>"_test = [] {
using fmt = format::uint8;
using error = msgpack::error;
std::array<std::byte, 4> payload;
auto constexpr expected = make_bytes(0xcc, 0x32, 0xcc, 0x82);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(std::uint8_t{0x32}));
expect(writer.tell() == 2);
expect(equal(writer.subspan(), std::span{expected.begin(), 2}));
expect(!!writer.write<fmt>(std::uint8_t{0x82}));
expect(equal(writer.subspan(), expected));
expect(writer.write(std::uint8_t{0x01})
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::uint16>"_test = [] {
using fmt = format::uint16;
using error = msgpack::error;
std::array<std::byte, 6> payload;
auto constexpr expected =
make_bytes(0xcd, 0x32, 0xcc, 0xcd, 0xaa, 0xff);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(std::uint16_t{0x32cc}));
expect(writer.tell() == 3);
expect(equal(writer.subspan(), std::span{expected.begin(), 3}));
expect(!!writer.write<fmt>(0xaaff));
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::uint32>"_test = [] {
using fmt = format::uint32;
using error = msgpack::error;
std::array<std::byte, 5> payload;
auto constexpr expected = make_bytes(0xce, 0x01, 0x02, 0x03, 0x04);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(0x01020304));
expect(writer.tell() == 5);
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::uint64>"_test = [] {
using fmt = format::uint64;
using error = msgpack::error;
std::array<std::byte, 9> payload;
auto constexpr expected = make_bytes(
0xcf, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(0x0102030405060708));
expect(writer.tell() == 9);
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::negative_fixint>"_test = [] {
using fmt = format::negative_fixint;
using error = msgpack::error;
std::array<std::byte, 2> payload;
auto constexpr expected = make_bytes(0xff, 0xe0);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(-1));
expect(writer.tell() == 1);
expect(*writer.subspan().begin() == std::byte{0xff});
expect(writer.write<fmt>(-33) == tl::make_unexpected(error::bad_value));
expect(!!writer.write<fmt>(-32));
expect(writer.tell() == 2);
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(-5)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::int8>"_test = [] {
using fmt = format::int8;
using error = msgpack::error;
std::array<std::byte, 4> payload;
auto constexpr expected = make_bytes(0xd0, 0x32, 0xd0, 0xfb);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(std::int8_t{0x32}));
expect(writer.tell() == 2);
expect(equal(writer.subspan(), std::span{expected.begin(), 2}));
expect(!!writer.write<fmt>(std::int8_t{-5}));
expect(equal(writer.subspan(), expected));
expect(writer.write(std::uint8_t{0x01})
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::int16>"_test = [] {
using fmt = format::int16;
using error = msgpack::error;
std::array<std::byte, 6> payload;
auto constexpr expected =
make_bytes(0xd1, 0x32, 0xcc, 0xd1, 0xff, 0xfa);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(std::int16_t{0x32cc}));
expect(writer.tell() == 3);
expect(equal(writer.subspan(), std::span{expected.begin(), 3}));
expect(!!writer.write<fmt>(-6));
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::int32>"_test = [] {
using fmt = format::int32;
using error = msgpack::error;
std::array<std::byte, 5> payload;
auto constexpr expected = make_bytes(0xd2, 0x01, 0x02, 0x03, 0x04);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(0x01020304));
expect(writer.tell() == 5);
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::int64>"_test = [] {
using fmt = format::int64;
using error = msgpack::error;
std::array<std::byte, 9> payload;
auto constexpr expected = make_bytes(
0xd3, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(std::int64_t{0x0102030405060708}));
expect(writer.tell() == 9);
expect(equal(writer.subspan(), expected));
expect(writer.write<fmt>(0x01)
== tl::make_unexpected(error::out_of_space));
};
"writer::write<format::fixstr>"_test = [] {
using fmt = format::fixstr;
std::array<std::byte, 4> payload;
auto constexpr expected = make_bytes(0xa2, 'o', 'h');
msgpack::writer writer(payload);
expect(!!writer.write<fmt>("oh"));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::str8>"_test = [] {
using fmt = format::str8;
std::array<std::byte, 46> payload;
auto constexpr expected = make_bytes(0xd9, 44, 't', 'h', 'e', ' ', 'q',
'u', 'i', 'c', 'k', ' ', 'b', 'r', 'o', 'w', 'n', ' ', 'f', 'o',
'x', ' ', 'j', 'u', 'm', 'p', 'e', 'd', ' ', 'o', 'v', 'e', 'r',
' ', 't', 'h', 'e', ' ', 'l', 'a', 'z', 'y', ' ', 'd', 'o',
'g');
msgpack::writer writer(payload);
std::string_view txt = "the quick brown fox jumped over the lazy dog";
expect(!!writer.write<fmt>(std::move(txt)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::str16>"_test = [] {
using fmt = format::str16;
std::array<std::byte, 47> payload;
auto constexpr expected = make_bytes(0xda, 0, 44, 't', 'h', 'e', ' ',
'q', 'u', 'i', 'c', 'k', ' ', 'b', 'r', 'o', 'w', 'n', ' ', 'f',
'o', 'x', ' ', 'j', 'u', 'm', 'p', 'e', 'd', ' ', 'o', 'v', 'e',
'r', ' ', 't', 'h', 'e', ' ', 'l', 'a', 'z', 'y', ' ', 'd', 'o',
'g');
msgpack::writer writer(payload);
std::string_view txt = "the quick brown fox jumped over the lazy dog";
expect(!!writer.write<fmt>(std::move(txt)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::str32>"_test = [] {
using fmt = format::str32;
std::array<std::byte, 49> payload;
auto constexpr expected = make_bytes(0xdb, 0, 0, 0, 44, 't', 'h', 'e',
' ', 'q', 'u', 'i', 'c', 'k', ' ', 'b', 'r', 'o', 'w', 'n', ' ',
'f', 'o', 'x', ' ', 'j', 'u', 'm', 'p', 'e', 'd', ' ', 'o', 'v',
'e', 'r', ' ', 't', 'h', 'e', ' ', 'l', 'a', 'z', 'y', ' ', 'd',
'o', 'g');
msgpack::writer writer(payload);
std::string_view txt = "the quick brown fox jumped over the lazy dog";
expect(!!writer.write<fmt>(std::move(txt)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::bin8>"_test = [] {
using fmt = format::bin8;
std::array<std::byte, 12> payload;
auto constexpr expected = make_bytes(
0xc4, 0x07, 0x01, 0x02, 0x03, 0x04, 0xf8, 0xf9, 0xfa);
msgpack::writer writer(payload);
std::span<std::byte const> bv(expected.begin() + 2, expected.end());
expect(!!writer.write<fmt>(std::move(bv)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::bin16>"_test = [] {
using fmt = format::bin16;
std::array<std::byte, 12> payload;
auto constexpr expected = make_bytes(
0xc5, 0x0, 0x07, 0x01, 0x02, 0x03, 0x04, 0xf8, 0xf9, 0xfa);
msgpack::writer writer(payload);
std::span<std::byte const> bv(expected.begin() + 3, expected.end());
expect(!!writer.write<fmt>(std::move(bv)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::bin32>"_test = [] {
using fmt = format::bin32;
std::array<std::byte, 12> payload;
auto constexpr expected = make_bytes(0xc6, 0x0, 0x0, 0x0, 0x07, 0x01,
0x02, 0x03, 0x04, 0xf8, 0xf9, 0xfa);
msgpack::writer writer(payload);
std::span<std::byte const> bv(expected.begin() + 5, expected.end());
expect(!!writer.write<fmt>(std::move(bv)));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::fixmap>"_test = [] {
using fmt = format::fixmap;
std::array<std::byte, 1> payload;
auto constexpr expected = make_bytes(0x83);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::map_desc{3}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::map16>"_test = [] {
using fmt = format::map16;
std::array<std::byte, 3> payload;
auto constexpr expected = make_bytes(0xde, 0x01, 0x00);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::map_desc{256}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::map32>"_test = [] {
using fmt = format::map32;
std::array<std::byte, 5> payload;
auto constexpr expected = make_bytes(0xdf, 0x00, 0x01, 0x00, 0x00);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::map_desc{0x10000}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::fixarray>"_test = [] {
using fmt = format::fixarray;
std::array<std::byte, 1> payload;
auto constexpr expected = make_bytes(0x93);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::array_desc{3}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::array16>"_test = [] {
using fmt = format::array16;
std::array<std::byte, 3> payload;
auto constexpr expected = make_bytes(0xdc, 0x01, 0x00);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::array_desc{256}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::array32>"_test = [] {
using fmt = format::array32;
std::array<std::byte, 5> payload;
auto constexpr expected = make_bytes(0xdd, 0x00, 0x01, 0x00, 0x00);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(msgpack::array_desc{0x10000}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::nil>"_test = [] {
using fmt = format::nil;
std::array<std::byte, 1> payload;
auto constexpr expected = make_bytes(0xc0);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>({}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::invalid>"_test = [] {
using fmt = format::invalid;
std::array<std::byte, 1> payload;
auto constexpr expected = make_bytes(0xc1);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>({}));
expect(equal(writer.subspan(), expected));
};
"writer::write<format::boolean>"_test = [] {
using fmt = format::boolean;
std::array<std::byte, 2> payload;
auto constexpr expected = make_bytes(0xc2, 0xc3);
msgpack::writer writer(payload);
expect(!!writer.write<fmt>(false));
expect(!!writer.write<fmt>(true));
expect(equal(writer.subspan(), expected));
};
};