util: Fix buffer expansion and reformat unit tests

This commit is contained in:
Joshua Scott 2018-10-20 18:17:35 +01:00
parent 5183131b69
commit 3f5450c64e
5 changed files with 179 additions and 115 deletions

View File

@ -21,4 +21,4 @@ steps:
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'build/**/test-*.xml'
testResultsFiles: 'build/Testing/reports/test-*.xml'

View File

@ -56,6 +56,11 @@ namespace ki
*/
void seek(stream_pos position);
/**
* @return The current size of the internal buffer.
*/
std::size_t capacity() const;
/**
* @return A pointer to the start of the internal buffer.
*/

View File

@ -141,6 +141,11 @@ namespace ki
validate_buffer();
}
std::size_t BitStream::capacity() const
{
return m_buffer_size;
}
const uint8_t *BitStream::data() const
{
return m_buffer;
@ -149,7 +154,7 @@ namespace ki
void BitStream::expand_buffer()
{
// Work out a new buffer size
auto new_size = (2 << (uint64_t)log2(m_position.get_byte())) + 2;
auto new_size = (2 << (uint64_t)log2(m_position.get_byte()) + 1) + 2;
if (new_size < m_buffer_size)
new_size = std::numeric_limits<size_t>::max();
@ -162,6 +167,7 @@ namespace ki
std::memcpy(new_buffer, m_buffer, m_buffer_size);
delete[] m_buffer;
m_buffer = new_buffer;
m_buffer_size = new_size;
}
void BitStream::validate_buffer()

View File

@ -3,6 +3,7 @@ add_library(Catch INTERFACE)
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
file(COPY "samples" DESTINATION "${PROJECT_BINARY_DIR}/test")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/reports/")
file(GLOB files "src/unit-*.cpp")
foreach (file ${files})
@ -15,5 +16,5 @@ foreach (file ${files})
CXX_STANDARD 11
)
target_link_libraries(${testcase} Catch ${PROJECT_NAME})
add_test(${testcase} ${testcase} -s -r junit -o ${PROJECT_BINARY_DIR}/Testing/${testcase}.xml)
add_test(${testcase} ${testcase} -s -r junit -o "${PROJECT_BINARY_DIR}/Testing/reports/${testcase}.xml")
endforeach()

View File

@ -1,23 +1,43 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <ki/util/BitStream.h>
/*
* Define values we expect during testing.
*/
#define KI_TEST_BITSTREAM_BUI1 0b1
#define KI_TEST_BITSTREAM_BUI2 0b10
#define KI_TEST_BITSTREAM_BUI3 0b010
#define KI_TEST_BITSTREAM_BUI4 0b0101
#define KI_TEST_BITSTREAM_BUI5 0b10101
#define KI_TEST_BITSTREAM_BUI6 0b101010
#define KI_TEST_BITSTREAM_BUI7 0b0101010
#define KI_TEST_BITSTREAM_U8 0x01
#define KI_TEST_BITSTREAM_U16 0x0302
#define KI_TEST_BITSTREAM_U24 0x060504
#define KI_TEST_BITSTREAM_U32 0x0A090807
#define KI_TEST_BITSTREAM_U64 0x1211100F0E0D0C0BL
#define KI_TEST_WRITE_BUI(n) bit_stream->write(KI_TEST_BITSTREAM_BUI##n, n)
#define KI_TEST_READ_BUI(n) bit_stream->read<uint8_t>(n) == KI_TEST_BITSTREAM_BUI##n
using namespace ki;
TEST_CASE("Write bits", "[bit-stream]")
TEST_CASE("BitStream Functionality", "[bit-stream]")
{
auto *bit_stream = new BitStream();
SECTION("Writing values with a size less than 8 bits")
{
// Write an alternating pattern of bits
bit_stream->write(0b1, 1);
bit_stream->write(0b10, 2);
bit_stream->write(0b010, 3);
bit_stream->write(0b0101, 4);
bit_stream->write(0b10101, 5);
bit_stream->write(0b101010, 6);
bit_stream->write(0b0101010, 7);
bit_stream->write(0b0101, 4);
KI_TEST_WRITE_BUI(1);
KI_TEST_WRITE_BUI(2);
KI_TEST_WRITE_BUI(3);
KI_TEST_WRITE_BUI(4);
KI_TEST_WRITE_BUI(5);
KI_TEST_WRITE_BUI(6);
KI_TEST_WRITE_BUI(7);
KI_TEST_WRITE_BUI(4);
// Make sure tell is reporting the right position
auto position = bit_stream->tell();
@ -37,20 +57,18 @@ TEST_CASE("Write bits", "[bit-stream]")
FAIL();
// Free resources
delete bit_stream;
delete[] sample_data;
SUCCEED();
}
TEST_CASE("Write bytes", "[bit-stream]")
SECTION("Writing values with a size greater than 8 bits")
{
auto *bit_stream = new BitStream();
// Write an alternating pattern of bits
bit_stream->write<uint8_t>(0x01, 8);
bit_stream->write<uint16_t>(0x0302, 16);
bit_stream->write<uint32_t>(0x060504, 24);
bit_stream->write<uint32_t>(0x0A090807, 32);
bit_stream->write<uint64_t>(0x1211100F0E0D0C0BL, 64);
// Write some values
bit_stream->write<uint8_t>(KI_TEST_BITSTREAM_U8, 8);
bit_stream->write<uint16_t>(KI_TEST_BITSTREAM_U16, 16);
bit_stream->write<uint32_t>(KI_TEST_BITSTREAM_U24, 24);
bit_stream->write<uint32_t>(KI_TEST_BITSTREAM_U32, 32);
bit_stream->write<uint64_t>(KI_TEST_BITSTREAM_U64, 64);
// Make sure tell is reporting the right position
auto position = bit_stream->tell();
@ -70,15 +88,13 @@ TEST_CASE("Write bytes", "[bit-stream]")
FAIL();
// Free resources
delete bit_stream;
delete[] sample_data;
SUCCEED();
}
TEST_CASE("Read bits", "[bit-stream]")
SECTION("Reading values with a size lower than 8 bits")
{
auto *bit_stream = new BitStream();
// Validate what we've got here with a hand-written sample
// Open a previously hand-written sample
std::ifstream sample("samples/bitstream1.bin", std::ios::binary);
if (!sample.is_open())
FAIL();
@ -92,32 +108,29 @@ TEST_CASE("Read bits", "[bit-stream]")
sample.read((char *)bit_stream->data(), size);
// Read the values and check they are what we are expecting
if (bit_stream->read<uint8_t>(1) != 0b1)
if (!KI_TEST_READ_BUI(1))
FAIL();
if (bit_stream->read<uint8_t>(2) != 0b10)
if (!KI_TEST_READ_BUI(2))
FAIL();
if (bit_stream->read<uint8_t>(3) != 0b010)
if (!KI_TEST_READ_BUI(3))
FAIL();
if (bit_stream->read<uint8_t>(4) != 0b0101)
if (!KI_TEST_READ_BUI(4))
FAIL();
if (bit_stream->read<uint8_t>(5) != 0b10101)
if (!KI_TEST_READ_BUI(5))
FAIL();
if (bit_stream->read<uint8_t>(6) != 0b101010)
if (!KI_TEST_READ_BUI(6))
FAIL();
if (bit_stream->read<uint8_t>(7) != 0b0101010)
if (!KI_TEST_READ_BUI(7))
FAIL();
if (bit_stream->read<uint8_t>(4) != 0b0101)
if (!KI_TEST_READ_BUI(4))
FAIL();
// Free resources
delete bit_stream;
SUCCEED();
}
TEST_CASE("Read bytes", "[bit-stream]")
SECTION("Reading values with a size greater than 8 bits")
{
auto *bit_stream = new BitStream();
// Validate what we've got here with a hand-written sample
// Open a previously hand-written sample
std::ifstream sample("samples/bitstream2.bin", std::ios::binary);
if (!sample.is_open())
FAIL();
@ -131,17 +144,56 @@ TEST_CASE("Read bytes", "[bit-stream]")
sample.read((char *)bit_stream->data(), size);
// Read the values and check they are what we are expecting
if (bit_stream->read<uint8_t>(8) != 0x01)
if (bit_stream->read<uint8_t>(8) != KI_TEST_BITSTREAM_U8)
FAIL();
if (bit_stream->read<uint16_t>(16) != 0x0302)
if (bit_stream->read<uint16_t>(16) != KI_TEST_BITSTREAM_U16)
FAIL();
if (bit_stream->read<uint32_t>(24) != 0x060504)
if (bit_stream->read<uint32_t>(24) != KI_TEST_BITSTREAM_U24)
FAIL();
if (bit_stream->read<uint32_t>(32) != 0x0A090807)
if (bit_stream->read<uint32_t>(32) != KI_TEST_BITSTREAM_U32)
FAIL();
if (bit_stream->read<uint64_t>(64) != 0x1211100F0E0D0C0BU)
if (bit_stream->read<uint64_t>(64) != KI_TEST_BITSTREAM_U64)
FAIL();
SUCCEED();
}
SECTION("Buffer underflow")
{
try
{
// Attempt to set the position less than 0
bit_stream->seek(BitStream::stream_pos(-1, 0));
FAIL();
}
catch (std::runtime_error &e)
{
// An exception was thrown, which is intended behaviour
SUCCEED();
}
}
// Free resources
delete bit_stream;
}
TEST_CASE("BitStream buffer expansion", "[bit-stream]")
{
// Create a very small buffer that we know is going to expand
auto *bit_stream = new BitStream(1);
// Write a byte, and then check if the capacity grows
bit_stream->write<uint8_t>(0x55, 8);
if (bit_stream->capacity() != 6)
FAIL();
// Go back to the first byte, and make sure what we wrote stuck
// around after the expansion
bit_stream->seek(BitStream::stream_pos(0, 0));
if (bit_stream->read<uint8_t>(8) != 0x55)
FAIL();
// Free resources
delete bit_stream;
SUCCEED();
}