summaryrefslogtreecommitdiff
path: root/sax/tst/test_buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sax/tst/test_buffer.cc')
-rw-r--r--sax/tst/test_buffer.cc272
1 files changed, 272 insertions, 0 deletions
diff --git a/sax/tst/test_buffer.cc b/sax/tst/test_buffer.cc
new file mode 100644
index 0000000..13bc6d4
--- /dev/null
+++ b/sax/tst/test_buffer.cc
@@ -0,0 +1,272 @@
+#include "buffer.hh"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+enum class BufferType {
+ FIXED,
+ DYNAMIC,
+};
+
+class BufferTest : public testing::TestWithParam<BufferType> {
+ protected:
+ std::unique_ptr<modxml::sax::Buffer> make_buffer(std::size_t size) {
+ switch (GetParam()) {
+ case BufferType::FIXED:
+ return modxml::sax::make_buffer(size, size);
+ case BufferType::DYNAMIC:
+ return modxml::sax::make_buffer(size / 2, size);
+ }
+ return nullptr;
+ }
+};
+
+std::array<uint8_t, 10> AAAAAAAAAA{
+ 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'};
+std::array<uint8_t, 5> BBBBB{
+ 'B', 'B', 'B', 'B', 'B'};
+
+} // namespace
+
+TEST_P(BufferTest, sanity) {
+ auto buf = make_buffer(10);
+ EXPECT_TRUE(buf->empty());
+ EXPECT_FALSE(buf->full());
+
+ EXPECT_TRUE(buf->write_all(AAAAAAAAAA));
+ EXPECT_TRUE(buf->full());
+ EXPECT_FALSE(buf->empty());
+
+ EXPECT_FALSE(buf->write_all(AAAAAAAAAA));
+
+ std::array<uint8_t, 10> tmp10;
+ EXPECT_TRUE(buf->read_all(tmp10));
+ EXPECT_THAT(tmp10, testing::ContainerEq(AAAAAAAAAA));
+ EXPECT_TRUE(buf->empty());
+ EXPECT_FALSE(buf->full());
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+ EXPECT_FALSE(buf->full());
+ EXPECT_FALSE(buf->empty());
+
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+ EXPECT_TRUE(buf->full());
+ EXPECT_FALSE(buf->empty());
+
+ std::array<uint8_t, 3> tmp3;
+ EXPECT_TRUE(buf->read_all(tmp3));
+ EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'B'));
+
+ EXPECT_EQ(3u, buf->write(BBBBB));
+
+ EXPECT_TRUE(buf->read_all(tmp3));
+ EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'A'));
+
+ std::array<uint8_t, 5> tmp5;
+ EXPECT_TRUE(buf->read_all(tmp5));
+ EXPECT_THAT(tmp5, testing::ElementsAre('A', 'A', 'A', 'A', 'B'));
+
+ EXPECT_FALSE(buf->read_all(tmp3));
+ tmp3[2] = 'X';
+ EXPECT_EQ(2u, buf->read(tmp3));
+ EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'X'));
+}
+
+TEST_P(BufferTest, noop) {
+ auto buf = make_buffer(10);
+ EXPECT_TRUE(buf->empty());
+
+ std::array<uint8_t, 0> empty;
+ EXPECT_EQ(0u, buf->write(empty));
+ EXPECT_EQ(0u, buf->read(empty));
+
+ EXPECT_TRUE(buf->write_all(empty));
+ EXPECT_TRUE(buf->read_all(empty));
+
+ buf->commit(0);
+ buf->consume(0);
+
+ EXPECT_TRUE(buf->empty());
+}
+
+TEST_P(BufferTest, one_byte_filler) {
+ auto buf = make_buffer(10);
+
+ std::array<uint8_t, 1> tmp1;
+ uint8_t out = 0;
+ for (uint8_t in = 0; in <= 20; ++in) {
+ tmp1[0] = in;
+ EXPECT_TRUE(buf->write_all(tmp1));
+ if (in >= 9) {
+ EXPECT_TRUE(buf->read_all(tmp1));
+ EXPECT_EQ(tmp1[0], out);
+ ++out;
+ }
+ }
+ for (; out <= 20; ++out) {
+ EXPECT_TRUE(buf->read_all(tmp1));
+ EXPECT_EQ(tmp1[0], out);
+ }
+ EXPECT_TRUE(buf->empty());
+}
+
+TEST_P(BufferTest, read_wrap) {
+ auto buf = make_buffer(10);
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+
+ std::array<uint8_t, 5> tmp5;
+ EXPECT_TRUE(buf->read_all(tmp5));
+ EXPECT_THAT(tmp5, testing::ContainerEq(BBBBB));
+
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+
+ std::array<uint8_t, 10> tmp10;
+ EXPECT_TRUE(buf->read_all(tmp10));
+ EXPECT_THAT(tmp10, testing::ContainerEq(AAAAAAAAAA));
+}
+
+TEST_P(BufferTest, skip_wrap) {
+ auto buf = make_buffer(10);
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+
+ buf->consume(5);
+ EXPECT_FALSE(buf->empty());
+
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+
+ buf->consume(10);
+ EXPECT_TRUE(buf->empty());
+}
+
+TEST_P(BufferTest, write_wrap) {
+ auto buf = make_buffer(12);
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+
+ std::array<uint8_t, 3> tmp3;
+ EXPECT_TRUE(buf->read_all(tmp3));
+ EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'B'));
+
+ EXPECT_TRUE(buf->write_all(AAAAAAAAAA));
+
+ std::array<uint8_t, 12> tmp12;
+ EXPECT_EQ(12u, buf->read(tmp12));
+ EXPECT_THAT(tmp12, testing::ElementsAre(
+ 'B', 'B', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'));
+}
+
+TEST_P(BufferTest, read_wrap2) {
+ auto buf = make_buffer(12);
+
+ EXPECT_TRUE(buf->write_all(AAAAAAAAAA));
+
+ std::array<uint8_t, 7> tmp7;
+ EXPECT_TRUE(buf->read_all(tmp7));
+ EXPECT_THAT(tmp7, testing::ElementsAre('A', 'A', 'A', 'A', 'A', 'A', 'A'));
+
+ EXPECT_EQ(5u, buf->write(BBBBB));
+ EXPECT_EQ(4u, buf->write(BBBBB));
+
+ std::array<uint8_t, 12> tmp12;
+ EXPECT_TRUE(buf->read_all(tmp12));
+ EXPECT_THAT(tmp12, testing::ElementsAre(
+ 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'));
+}
+
+TEST(Buffer, dynamic_resize) {
+ auto buf = modxml::sax::make_buffer(10, 1000);
+
+ std::array<uint8_t, 30> tmp30;
+ for (uint8_t i = 0; i < 30; ++i)
+ tmp30[i] = i;
+
+ EXPECT_TRUE(buf->write_all(tmp30));
+ EXPECT_TRUE(buf->write_all(tmp30));
+
+ std::array<uint8_t, 60> tmp60;
+ EXPECT_TRUE(buf->read_all(tmp60));
+ for (uint8_t i = 0; i < 60; ++i)
+ EXPECT_EQ(i % 30, tmp60[i]) << i;
+}
+
+TEST(Buffer, dynamic_overalloc) {
+ // This test can fail, but in most configurations trying to allocate
+ // std::numeric_limits<std::size_t>::max() will fail.
+ auto buf = modxml::sax::make_buffer(10, std::numeric_limits<std::size_t>::max());
+ EXPECT_FALSE(buf->wspan(10000).empty());
+ EXPECT_TRUE(buf->wspan(std::numeric_limits<std::size_t>::max()).empty());
+}
+
+TEST_P(BufferTest, modify) {
+ auto buf = make_buffer(10);
+
+ EXPECT_TRUE(buf->write_all(AAAAAAAAAA));
+
+ auto span = buf->mspan(5);
+ EXPECT_EQ(10u, span.size());
+ auto len = std::min(static_cast<std::size_t>(5), span.size());
+ for (uint8_t i = 0; i < len; ++i)
+ span[i] = 'C';
+
+ std::array<uint8_t, 10> tmp10;
+ EXPECT_TRUE(buf->read_all(tmp10));
+ EXPECT_THAT(tmp10, testing::ElementsAre(
+ 'C', 'C', 'C', 'C', 'C', 'A', 'A', 'A', 'A', 'A'));
+}
+
+TEST_P(BufferTest, uncommit) {
+ auto buf = make_buffer(10);
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+
+ EXPECT_EQ(0u, buf->uncommit(0));
+
+ EXPECT_EQ(5u, buf->write(AAAAAAAAAA));
+
+ std::array<uint8_t, 2> tmp2;
+ EXPECT_TRUE(buf->read_all(tmp2));
+ EXPECT_THAT(tmp2, testing::ElementsAre('B', 'B'));
+
+ EXPECT_EQ(3u, buf->uncommit(3));
+ std::array<uint8_t, 5> tmp5;
+ EXPECT_TRUE(buf->read_all(tmp5));
+ EXPECT_THAT(tmp5, testing::ElementsAre('B', 'B', 'B', 'A', 'A'));
+
+ EXPECT_EQ(0u, buf->uncommit(2));
+}
+
+TEST_P(BufferTest, uncommit_wrap) {
+ auto buf = make_buffer(10);
+
+ EXPECT_TRUE(buf->write_all(AAAAAAAAAA));
+ std::array<uint8_t, 5> tmp5;
+ EXPECT_TRUE(buf->read_all(tmp5));
+
+ EXPECT_TRUE(buf->write_all(BBBBB));
+
+ EXPECT_EQ(8u, buf->uncommit(8));
+ std::array<uint8_t, 2> tmp2;
+ EXPECT_TRUE(buf->read_all(tmp2));
+ EXPECT_THAT(tmp2, testing::ElementsAre('A', 'A'));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ BufferTests,
+ BufferTest,
+ testing::Values(BufferType::FIXED, BufferType::DYNAMIC),
+ [](auto& info) {
+ switch (info.param) {
+ case BufferType::FIXED:
+ return "fixed";
+ case BufferType::DYNAMIC:
+ return "dynamic";
+ }
+ return "";
+ }
+);