/*!
  \file
  \brief RingBuffer のテスト

  \author Satofumi KAMIMURA

  $Id: TestRingBuffer.cpp 1811 2010-04-30 16:12:05Z satofumi $
*/

#include "TestRingBuffer.h"
#include "RingBuffer.h"
#include <cstring>

using namespace qrk;
using namespace std;


CPPUNIT_TEST_SUITE_REGISTRATION(TestRingBuffer);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestRingBuffer, "TestRingBuffer");


void TestRingBuffer::compileTest(void)
{
    RingBuffer<char> buffer;
}


void TestRingBuffer::putTest(void)
{
    RingBuffer<char> buffer;
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), buffer.size());

    buffer.put("0", 1);
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), buffer.size());

    char ch;
    int n = buffer.get(&ch, 1);
    CPPUNIT_ASSERT_EQUAL('0', ch);
    CPPUNIT_ASSERT_EQUAL(1, n);

    buffer.clear();
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), buffer.size());
}


void TestRingBuffer::extendTest(void)
{
    RingBuffer<char> buffer;

    enum { BufferSize = 256 };
    char recvBuffer[BufferSize];
    memset(recvBuffer, 0, sizeof(recvBuffer[0]) * BufferSize);

    buffer.put("0", 1);
    int n = buffer.get(recvBuffer, 8);
    CPPUNIT_ASSERT_EQUAL(1, n);
    CPPUNIT_ASSERT_EQUAL(string("0"), string(recvBuffer));

    buffer.put("1", 1);
    n = buffer.get(recvBuffer, 8);
    CPPUNIT_ASSERT_EQUAL(1, n);
    CPPUNIT_ASSERT_EQUAL(string("1"), string(recvBuffer));

    buffer.put("23", 2);
    n = buffer.get(recvBuffer, 8);
    CPPUNIT_ASSERT_EQUAL(2, n);
    CPPUNIT_ASSERT_EQUAL(string("23"), string(recvBuffer));

    buffer.put("01234567", 8);
    n = buffer.get(recvBuffer, 8);
    CPPUNIT_ASSERT_EQUAL(8, n);
    CPPUNIT_ASSERT_EQUAL(string("01234567"), string(recvBuffer));

    buffer.put("9876543210", 10);
    n = buffer.get(recvBuffer, 10);
    CPPUNIT_ASSERT_EQUAL(10, n);
    CPPUNIT_ASSERT_EQUAL(string("9876543210"), string(recvBuffer));

    buffer.put("9876543210abcdefg", 17);
    buffer.put("ABC", 3);
    n = buffer.get(recvBuffer, 17);
    CPPUNIT_ASSERT_EQUAL(17, n);
    CPPUNIT_ASSERT_EQUAL(string("9876543210abcdefg"), string(recvBuffer));

    n = buffer.get(recvBuffer, 3);
    CPPUNIT_ASSERT_EQUAL(3, n);
    recvBuffer[n] = '\0';
    CPPUNIT_ASSERT_EQUAL(string("ABC"), string(recvBuffer));
}


void TestRingBuffer::rotateTest(void)
{
    RingBuffer<char> buffer;

    char recvBuffer[] = { '\0', '\0', '\0', '\0', '\0' };

    for (int i = 0; i < 3; ++i) {
        char ch = '0' + i;
        buffer.put(&ch, 1);
    }
    int n = buffer.get(recvBuffer, 3);
    CPPUNIT_ASSERT_EQUAL(3, n);
    CPPUNIT_ASSERT_EQUAL(string("012"), string(recvBuffer));

    buffer.put("abc", 3);
    n = buffer.get(recvBuffer, 3);
    CPPUNIT_ASSERT_EQUAL(3, n);
    CPPUNIT_ASSERT_EQUAL(string("abc"), string(recvBuffer));
}


void TestRingBuffer::ungetcTest(void)
{
    RingBuffer<char> buffer;

    CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(buffer.size()));
    buffer.ungetc('a');

    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(buffer.size()));
    buffer.ungetc('b');

    CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(buffer.size()));
    buffer.ungetc('c');


    enum { BufferSize = 256 };
    char recvBuffer[BufferSize];
    memset(recvBuffer, 0, BufferSize);
    int n = buffer.get(recvBuffer, BufferSize);
    CPPUNIT_ASSERT_EQUAL(3, n);
    CPPUNIT_ASSERT_EQUAL(string("cba"), string(recvBuffer));
}
