emberemu/tests/BufferAdaptor.cpp

189 lines
5.6 KiB
C++
Raw Permalink Normal View History

2024-07-04 00:19:38 +01:00
/*
* Copyright (c) 2024 - 2025 Ember
2024-07-04 00:19:38 +01:00
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
2024-08-27 14:20:07 +01:00
#include <spark/buffers/BufferAdaptor.h>
2024-07-04 00:19:38 +01:00
#include <gtest/gtest.h>
#include <algorithm>
#include <array>
#include <span>
#include <string_view>
2024-07-04 00:19:38 +01:00
#include <vector>
#include <cstdint>
2024-08-27 14:20:07 +01:00
using namespace ember;
using namespace std::literals;
2024-07-04 00:19:38 +01:00
TEST(BufferAdaptor, SizeEmptyInitial) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 0> buffer;
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
ASSERT_EQ(adaptor.size(), 0);
}
2024-07-04 23:45:25 +01:00
TEST(BufferAdaptor, Empty) {
std::vector<std::uint8_t> buffer;
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 23:45:25 +01:00
ASSERT_TRUE(adaptor.empty());
buffer.emplace_back(1);
2024-08-27 14:20:07 +01:00
adaptor.advance_write(1);
2024-07-04 23:45:25 +01:00
ASSERT_FALSE(adaptor.empty());
}
2024-07-04 00:19:38 +01:00
TEST(BufferAdaptor, SizePopulatedInitial) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 1> buffer { 1 };
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
ASSERT_EQ(adaptor.size(), buffer.size());
}
TEST(BufferAdaptor, ResizeMatch) {
std::vector<std::uint8_t> buffer { 1, 2, 3, 4, 5 };
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
ASSERT_EQ(adaptor.size(), buffer.size());
buffer.emplace_back(6);
adaptor.advance_write(1);
2024-07-04 00:19:38 +01:00
ASSERT_EQ(adaptor.size(), buffer.size());
}
TEST(BufferAdaptor, ReadOne) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 3> buffer { 1, 2, 3 };
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::uint8_t value = 0;
adaptor.read(&value, 1);
ASSERT_EQ(adaptor.size(), buffer.size() - 1);
ASSERT_EQ(value, 1);
}
TEST(BufferAdaptor, ReadAll) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 3> buffer { 1, 2, 3 };
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::array<std::uint8_t, 3> values{};
adaptor.read(&values, values.size());
ASSERT_TRUE(std::ranges::equal(buffer, values));
2024-07-04 00:19:38 +01:00
}
TEST(BufferAdaptor, SingleSkipRead) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 3> buffer { 1, 2, 3 };
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::uint8_t value = 0;
adaptor.skip(1);
adaptor.read(&value, 1);
ASSERT_EQ(adaptor.size(), 1);
ASSERT_EQ(value, buffer[1]);
}
TEST(BufferAdaptor, MultiskipRead) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 6> buffer { 1, 2, 3, 4, 5, 6 };
spark::io::BufferAdaptor<decltype(buffer), false> adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::uint8_t value = 0;
adaptor.skip(5);
adaptor.read(&value, 1);
ASSERT_TRUE(adaptor.empty());
ASSERT_EQ(value, buffer[5]);
}
TEST(BufferAdaptor, Write) {
std::vector<std::uint8_t> buffer;
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::array<std::uint8_t, 6> values { 1, 2, 3, 4, 5, 6 };
adaptor.write(values.data(), values.size());
ASSERT_EQ(adaptor.size(), values.size());
ASSERT_EQ(buffer.size(), values.size());
ASSERT_TRUE(std::ranges::equal(values, buffer));
const auto size = adaptor.size();
adaptor.write('\0');
ASSERT_EQ(adaptor.size(), size + 1);
2024-07-04 00:19:38 +01:00
}
TEST(BufferAdaptor, WriteAppend) {
std::vector<std::uint8_t> buffer { 1, 2, 3 };
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::array<std::uint8_t, 3> values { 4, 5, 6 };
adaptor.write(values.data(), values.size());
ASSERT_EQ(buffer.size(), 6);
ASSERT_EQ(adaptor.size(), buffer.size());
std::array<std::uint8_t, 6> expected { 1, 2, 3, 4, 5, 6 };
ASSERT_TRUE(std::ranges::equal(expected, buffer));
2024-07-04 00:19:38 +01:00
}
TEST(BufferAdaptor, CanWriteSeek) {
std::vector<std::uint8_t> buffer;
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
ASSERT_TRUE(adaptor.can_write_seek());
}
TEST(BufferAdaptor, WriteSeekBack) {
std::vector<std::uint8_t> buffer { 1, 2, 3 };
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::array<std::uint8_t, 3> values { 4, 5, 6 };
adaptor.write_seek(spark::io::BufferSeek::sk_backward, 2);
2024-07-04 00:19:38 +01:00
adaptor.write(values.data(), values.size());
ASSERT_EQ(buffer.size(), 4);
ASSERT_EQ(adaptor.size(), buffer.size());
std::array<std::uint8_t, 4> expected { 1, 4, 5, 6 };
ASSERT_TRUE(std::ranges::equal(expected, buffer));
2024-07-04 00:19:38 +01:00
}
TEST(BufferAdaptor, WriteSeekStart) {
std::vector<std::uint8_t> buffer { 1, 2, 3 };
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
std::array<std::uint8_t, 3> values { 4, 5, 6 };
adaptor.write_seek(spark::io::BufferSeek::sk_absolute, 0);
2024-07-04 00:19:38 +01:00
adaptor.write(values.data(), values.size());
ASSERT_EQ(buffer.size(), values.size());
ASSERT_EQ(adaptor.size(), buffer.size());
ASSERT_TRUE(std::ranges::equal(buffer, values));
2024-07-04 00:19:38 +01:00
}
TEST(BufferAdaptor, ReadPtr) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 3> buffer { 1, 2, 3 };
spark::io::BufferAdaptor adaptor(buffer);
2024-07-04 00:19:38 +01:00
auto ptr = adaptor.read_ptr();
ASSERT_EQ(*ptr, buffer[0]);
adaptor.skip(1);
ptr = adaptor.read_ptr();
ASSERT_EQ(*ptr, buffer[1]);
adaptor.skip(1);
ptr = adaptor.read_ptr();
ASSERT_EQ(*ptr, buffer[2]);
}
TEST(BufferAdaptor, Subscript) {
2024-08-27 14:20:07 +01:00
std::array<std::uint8_t, 3> buffer { 1, 2, 3 };
spark::io::BufferAdaptor adaptor(buffer);
ASSERT_EQ(adaptor[0], 1);
ASSERT_EQ(adaptor[1], 2);
ASSERT_EQ(adaptor[2], 3);
2024-07-04 00:19:38 +01:00
buffer[0] = 4;
2024-08-27 14:20:07 +01:00
ASSERT_EQ(adaptor[0], 4);
adaptor[0] = 5;
ASSERT_EQ(adaptor[0], 5);
ASSERT_EQ(adaptor[0], buffer[0]);
}
TEST(BufferAdaptor, FindFirstOf) {
std::vector<char> buffer;
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
const auto str = "The quick brown fox jumped over the lazy dog"sv;
adaptor.write(str.data(), str.size());
2024-08-27 14:20:07 +01:00
auto pos = adaptor.find_first_of('\0');
ASSERT_EQ(pos, adaptor.npos); // direct string write is not terminated
2024-08-27 14:20:07 +01:00
pos = adaptor.find_first_of('g');
ASSERT_EQ(pos, 43);
2024-08-27 14:20:07 +01:00
pos = adaptor.find_first_of('T');
ASSERT_EQ(pos, 0);
2024-08-27 14:20:07 +01:00
pos = adaptor.find_first_of('t');
ASSERT_EQ(pos, 32);
}
// test optimised write() for buffers supporting resize_and_overwrite
TEST(BufferAdaptor, StringBuffer) {
std::string buffer;
2024-08-27 14:20:07 +01:00
spark::io::BufferAdaptor adaptor(buffer);
const auto str = "The quick brown fox jumped over the lazy dog"sv;
adaptor.write(str.data(), str.size());
ASSERT_EQ(buffer, str);
2024-07-04 00:19:38 +01:00
}