Test buffer

This commit is contained in:
Victor Zverovich 2014-10-01 08:12:10 -07:00
parent 74dc571ba0
commit 8b9a6e03f6
3 changed files with 108 additions and 80 deletions

View File

@ -306,13 +306,14 @@ class MemoryBuffer : private Allocator, public Buffer<T> {
private: private:
T data_[SIZE]; T data_[SIZE];
void grow(std::size_t size);
// Free memory allocated by the buffer. // Free memory allocated by the buffer.
void free() { void free() {
if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_); if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_);
} }
protected:
void grow(std::size_t size);
public: public:
explicit MemoryBuffer(const Allocator &alloc = Allocator()) explicit MemoryBuffer(const Allocator &alloc = Allocator())
: Allocator(alloc), Buffer<T>(data_, SIZE) {} : Allocator(alloc), Buffer<T>(data_, SIZE) {}

View File

@ -33,6 +33,8 @@
template <typename T> template <typename T>
class MockAllocator { class MockAllocator {
public: public:
MockAllocator() {}
MockAllocator(const MockAllocator &) {}
typedef T value_type; typedef T value_type;
MOCK_METHOD1_T(allocate, T* (std::size_t n)); MOCK_METHOD1_T(allocate, T* (std::size_t n));
MOCK_METHOD2_T(deallocate, void (T* p, std::size_t n)); MOCK_METHOD2_T(deallocate, void (T* p, std::size_t n));

View File

@ -103,27 +103,30 @@ TEST(AllocatorTest, AllocatorRef) {
} }
#if FMT_USE_TYPE_TRAITS #if FMT_USE_TYPE_TRAITS
TEST(BufferTest, NotCopyConstructible) { TEST(BufferTest, Noncopyable) {
EXPECT_FALSE(std::is_copy_constructible<Buffer<char> >::value); EXPECT_FALSE(std::is_copy_constructible<Buffer<char> >::value);
EXPECT_FALSE(std::is_copy_assignable<Buffer<char> >::value);
} }
TEST(BufferTest, NotCopyAssignable) { TEST(BufferTest, Nonmoveable) {
EXPECT_FALSE(std::is_copy_assignable<Buffer<char> >::value); EXPECT_FALSE(std::is_move_constructible<Buffer<char> >::value);
EXPECT_FALSE(std::is_move_assignable<Buffer<char> >::value);
} }
#endif #endif
// A test buffer with a dummy grow method.
template <typename T> template <typename T>
class MockBuffer : public Buffer<T> { struct TestBuffer : Buffer<T> {
protected: void grow(std::size_t size) { this->capacity_ = size; }
MOCK_METHOD1(grow, void (std::size_t size)); };
public: template <typename T>
MOCK_METHOD0(Die, void()); struct MockBuffer : Buffer<T> {
MOCK_METHOD1(grow, void (std::size_t size));
MockBuffer() {} MockBuffer() {}
MockBuffer(T *ptr) : Buffer<T>(ptr) {} MockBuffer(T *ptr) : Buffer<T>(ptr) {}
MockBuffer(T *ptr, std::size_t capacity) : Buffer<T>(ptr, capacity) {} MockBuffer(T *ptr, std::size_t capacity) : Buffer<T>(ptr, capacity) {}
~MockBuffer() { Die(); }
}; };
TEST(BufferTest, Ctor) { TEST(BufferTest, Ctor) {
@ -151,16 +154,20 @@ TEST(BufferTest, Ctor) {
} }
TEST(BufferTest, VirtualDtor) { TEST(BufferTest, VirtualDtor) {
typedef StrictMock< MockBuffer<int> > StictMockBuffer; struct DyingBuffer : TestBuffer<int> {
MOCK_METHOD0(die, void());
~DyingBuffer() { die(); }
};
typedef StrictMock<DyingBuffer> StictMockBuffer;
StictMockBuffer *mock_buffer = new StictMockBuffer(); StictMockBuffer *mock_buffer = new StictMockBuffer();
EXPECT_CALL(*mock_buffer, Die()); EXPECT_CALL(*mock_buffer, die());
Buffer<int> *buffer = mock_buffer; Buffer<int> *buffer = mock_buffer;
delete buffer; delete buffer;
} }
TEST(BufferTest, Access) { TEST(BufferTest, Access) {
char data[10]; char data[10];
MockBuffer<char> buffer(data, 10); MockBuffer<char> buffer(data, sizeof(data));
buffer[0] = 11; buffer[0] = 11;
EXPECT_EQ(11, buffer[0]); EXPECT_EQ(11, buffer[0]);
buffer[3] = 42; buffer[3] = 42;
@ -169,6 +176,71 @@ TEST(BufferTest, Access) {
EXPECT_EQ(42, const_buffer[3]); EXPECT_EQ(42, const_buffer[3]);
} }
TEST(BufferTest, Resize) {
char data[123];
MockBuffer<char> buffer(data, sizeof(data));
buffer[10] = 42;
EXPECT_EQ(42, buffer[10]);
buffer.resize(20);
EXPECT_EQ(20u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
buffer.resize(5);
EXPECT_EQ(5u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
// Check if resize calls grow.
EXPECT_CALL(buffer, grow(124));
buffer.resize(124);
EXPECT_CALL(buffer, grow(200));
buffer.resize(200);
}
TEST(BufferTest, Clear) {
TestBuffer<char> buffer;
buffer.resize(20);
buffer.clear();
EXPECT_EQ(0u, buffer.size());
EXPECT_EQ(20u, buffer.capacity());
}
TEST(BufferTest, PushBack) {
int data[15];
MockBuffer<int> buffer(data, 10);
buffer.push_back(11);
EXPECT_EQ(11, buffer[0]);
EXPECT_EQ(1u, buffer.size());
buffer.resize(10);
EXPECT_CALL(buffer, grow(11));
buffer.push_back(22);
EXPECT_EQ(22, buffer[10]);
EXPECT_EQ(11u, buffer.size());
}
TEST(BufferTest, Append) {
char data[15];
MockBuffer<char> buffer(data, 10);
const char *test = "test";
buffer.append(test, test + 5);
EXPECT_STREQ(test, &buffer[0]);
EXPECT_EQ(5u, buffer.size());
buffer.resize(10);
EXPECT_CALL(buffer, grow(12));
buffer.append(test, test + 2);
EXPECT_EQ('t', buffer[10]);
EXPECT_EQ('e', buffer[11]);
EXPECT_EQ(12u, buffer.size());
}
TEST(BufferTest, AppendAllocatesEnoughStorage) {
char data[19];
MockBuffer<char> buffer(data, 10);
const char *test = "abcdefgh";
buffer.resize(10);
EXPECT_CALL(buffer, grow(19));
buffer.append(test, test + 9);
}
TEST(MemoryBufferTest, Ctor) { TEST(MemoryBufferTest, Ctor) {
MemoryBuffer<char, 123> buffer; MemoryBuffer<char, 123> buffer;
EXPECT_EQ(0u, buffer.size()); EXPECT_EQ(0u, buffer.size());
@ -245,74 +317,29 @@ TEST(MemoryBufferTest, MoveAssignment) {
#endif // FMT_USE_RVALUE_REFERENCES #endif // FMT_USE_RVALUE_REFERENCES
TEST(MemoryBufferTest, Resize) {
MemoryBuffer<char, 123> buffer;
buffer[10] = 42;
EXPECT_EQ(42, buffer[10]);
buffer.resize(20);
EXPECT_EQ(20u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
buffer.resize(5);
EXPECT_EQ(5u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
}
TEST(MemoryBufferTest, Grow) { TEST(MemoryBufferTest, Grow) {
MemoryBuffer<int, 10> buffer; typedef AllocatorRef< MockAllocator<int> > Allocator;
buffer.resize(10); typedef MemoryBuffer<int, 10, Allocator> Base;
for (int i = 0; i < 10; ++i) MockAllocator<int> alloc;
struct TestMemoryBuffer : Base {
TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
void grow(std::size_t size) { Base::grow(size); }
} buffer((Allocator(&alloc)));
buffer.resize(7);
for (int i = 0; i < 7; ++i)
buffer[i] = i * i; buffer[i] = i * i;
buffer.resize(20); EXPECT_EQ(10u, buffer.capacity());
EXPECT_EQ(20u, buffer.size()); int mem[20];
mem[7] = 0xdead;
EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem));
buffer.grow(20);
EXPECT_EQ(20u, buffer.capacity()); EXPECT_EQ(20u, buffer.capacity());
for (int i = 0; i < 10; ++i) // Check if size elements have been copied
for (int i = 0; i < 7; ++i)
EXPECT_EQ(i * i, buffer[i]); EXPECT_EQ(i * i, buffer[i]);
} // and no more than that.
EXPECT_EQ(0xdead, buffer[7]);
TEST(MemoryBufferTest, Clear) { EXPECT_CALL(alloc, deallocate(mem, 20));
MemoryBuffer<char, 10> buffer;
buffer.resize(20);
buffer.clear();
EXPECT_EQ(0u, buffer.size());
EXPECT_EQ(20u, buffer.capacity());
}
TEST(MemoryBufferTest, PushBack) {
MemoryBuffer<int, 10> buffer;
buffer.push_back(11);
EXPECT_EQ(11, buffer[0]);
EXPECT_EQ(1u, buffer.size());
buffer.resize(10);
buffer.push_back(22);
EXPECT_EQ(22, buffer[10]);
EXPECT_EQ(11u, buffer.size());
EXPECT_EQ(15u, buffer.capacity());
}
TEST(MemoryBufferTest, Append) {
MemoryBuffer<char, 10> buffer;
const char *test = "test";
buffer.append(test, test + 5);
EXPECT_STREQ(test, &buffer[0]);
EXPECT_EQ(5u, buffer.size());
buffer.resize(10);
buffer.append(test, test + 2);
EXPECT_EQ('t', buffer[10]);
EXPECT_EQ('e', buffer[11]);
EXPECT_EQ(12u, buffer.size());
EXPECT_EQ(15u, buffer.capacity());
}
TEST(MemoryBufferTest, AppendAllocatesEnoughStorage) {
MemoryBuffer<char, 10> buffer;
const char *test = "abcdefgh";
buffer.resize(10);
buffer.append(test, test + 9);
EXPECT_STREQ(test, &buffer[10]);
EXPECT_EQ(19u, buffer.size());
EXPECT_EQ(19u, buffer.capacity());
} }
TEST(MemoryBufferTest, Allocator) { TEST(MemoryBufferTest, Allocator) {
@ -792,5 +819,3 @@ TEST(UtilTest, ReportWindowsError) {
} }
#endif // _WIN32 #endif // _WIN32
// TODO: test Buffer