123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- local helpers = require("test.unit.helpers")(after_each)
- local itp = helpers.gen_itp(it)
- local eq = helpers.eq
- local ffi = helpers.ffi
- local cstr = helpers.cstr
- local to_cstr = helpers.to_cstr
- local child_call_once = helpers.child_call_once
- local rbuffer = helpers.cimport("./test/unit/fixtures/rbuffer.h")
- describe('rbuffer functions', function()
- local capacity = 16
- local rbuf
- local function inspect()
- return ffi.string(rbuf.start_ptr, capacity)
- end
- local function write(str)
- local buf = to_cstr(str)
- return rbuffer.rbuffer_write(rbuf, buf, #str)
- end
- local function read(len)
- local buf = cstr(len)
- len = rbuffer.rbuffer_read(rbuf, buf, len)
- return ffi.string(buf, len)
- end
- local function get(idx)
- return ffi.string(rbuffer.rbuffer_get(rbuf, idx), 1)
- end
- before_each(function()
- child_call_once(function()
- rbuf = ffi.gc(rbuffer.rbuffer_new(capacity), rbuffer.rbuffer_free)
- -- fill the internal buffer with the character '0' to simplify inspecting
- ffi.C.memset(rbuf.start_ptr, string.byte('0'), capacity)
- end)
- end)
- describe('RBUFFER_UNTIL_FULL', function()
- local chunks
- local function collect_write_chunks()
- rbuffer.ut_rbuffer_each_write_chunk(rbuf, function(wptr, wcnt)
- table.insert(chunks, ffi.string(wptr, wcnt))
- end)
- end
- before_each(function()
- chunks = {}
- end)
- describe('with empty buffer in one contiguous chunk', function()
- itp('is called once with the empty chunk', function()
- collect_write_chunks()
- eq({'0000000000000000'}, chunks)
- end)
- end)
- describe('with partially empty buffer in one contiguous chunk', function()
- itp('is called once with the empty chunk', function()
- write('string')
- collect_write_chunks()
- eq({'0000000000'}, chunks)
- end)
- end)
- describe('with filled buffer in one contiguous chunk', function()
- itp('is not called', function()
- write('abcdefghijklmnopq')
- collect_write_chunks()
- eq({}, chunks)
- end)
- end)
- describe('with buffer partially empty in two contiguous chunks', function()
- itp('is called twice with each filled chunk', function()
- write('1234567890')
- read(8)
- collect_write_chunks()
- eq({'000000', '12345678'}, chunks)
- end)
- end)
- describe('with buffer empty in two contiguous chunks', function()
- itp('is called twice with each filled chunk', function()
- write('12345678')
- read(8)
- collect_write_chunks()
- eq({'00000000', '12345678'}, chunks)
- end)
- end)
- describe('with buffer filled in two contiguous chunks', function()
- itp('is not called', function()
- write('12345678')
- read(8)
- write('abcdefghijklmnopq')
- collect_write_chunks()
- eq({}, chunks)
- end)
- end)
- end)
- describe('RBUFFER_UNTIL_EMPTY', function()
- local chunks
- local function collect_read_chunks()
- rbuffer.ut_rbuffer_each_read_chunk(rbuf, function(rptr, rcnt)
- table.insert(chunks, ffi.string(rptr, rcnt))
- end)
- end
- before_each(function()
- chunks = {}
- end)
- describe('with empty buffer', function()
- itp('is not called', function()
- collect_read_chunks()
- eq({}, chunks)
- end)
- end)
- describe('with partially filled buffer in one contiguous chunk', function()
- itp('is called once with the filled chunk', function()
- write('string')
- collect_read_chunks()
- eq({'string'}, chunks)
- end)
- end)
- describe('with filled buffer in one contiguous chunk', function()
- itp('is called once with the filled chunk', function()
- write('abcdefghijklmnopq')
- collect_read_chunks()
- eq({'abcdefghijklmnop'}, chunks)
- end)
- end)
- describe('with buffer partially filled in two contiguous chunks', function()
- itp('is called twice with each filled chunk', function()
- write('1234567890')
- read(10)
- write('long string')
- collect_read_chunks()
- eq({'long s', 'tring'}, chunks)
- end)
- end)
- describe('with buffer filled in two contiguous chunks', function()
- itp('is called twice with each filled chunk', function()
- write('12345678')
- read(8)
- write('abcdefghijklmnopq')
- collect_read_chunks()
- eq({'abcdefgh', 'ijklmnop'}, chunks)
- end)
- end)
- end)
- describe('RBUFFER_EACH', function()
- local chars
- local function collect_chars()
- rbuffer.ut_rbuffer_each(rbuf, function(c, i)
- table.insert(chars, {string.char(c), tonumber(i)})
- end)
- end
- before_each(function()
- chars = {}
- end)
- describe('with empty buffer', function()
- itp('is not called', function()
- collect_chars()
- eq({}, chars)
- end)
- end)
- describe('with buffer filled in two contiguous chunks', function()
- itp('collects each character and index', function()
- write('1234567890')
- read(10)
- write('long string')
- collect_chars()
- eq({{'l', 0}, {'o', 1}, {'n', 2}, {'g', 3}, {' ', 4}, {'s', 5},
- {'t', 6}, {'r', 7}, {'i', 8}, {'n', 9}, {'g', 10}}, chars)
- end)
- end)
- end)
- describe('RBUFFER_EACH_REVERSE', function()
- local chars
- local function collect_chars()
- rbuffer.ut_rbuffer_each_reverse(rbuf, function(c, i)
- table.insert(chars, {string.char(c), tonumber(i)})
- end)
- end
- before_each(function()
- chars = {}
- end)
- describe('with empty buffer', function()
- itp('is not called', function()
- collect_chars()
- eq({}, chars)
- end)
- end)
- describe('with buffer filled in two contiguous chunks', function()
- itp('collects each character and index', function()
- write('1234567890')
- read(10)
- write('long string')
- collect_chars()
- eq({{'g', 10}, {'n', 9}, {'i', 8}, {'r', 7}, {'t', 6}, {'s', 5},
- {' ', 4}, {'g', 3}, {'n', 2}, {'o', 1}, {'l', 0}}, chars)
- end)
- end)
- end)
- describe('rbuffer_cmp', function()
- local function cmp(str)
- local rv = rbuffer.rbuffer_cmp(rbuf, to_cstr(str), #str)
- if rv == 0 then
- return 0
- else
- return rv / math.abs(rv)
- end
- end
- describe('with buffer filled in two contiguous chunks', function()
- itp('compares the common longest sequence', function()
- write('1234567890')
- read(10)
- write('long string')
- eq(0, cmp('long string'))
- eq(0, cmp('long strin'))
- eq(-1, cmp('long striM'))
- eq(1, cmp('long strio'))
- eq(0, cmp('long'))
- eq(-1, cmp('lonG'))
- eq(1, cmp('lonh'))
- end)
- end)
- describe('with empty buffer', function()
- itp('returns 0 since no characters are compared', function()
- eq(0, cmp(''))
- end)
- end)
- end)
- describe('rbuffer_write', function()
- itp('fills the internal buffer and returns the write count', function()
- eq(12, write('short string'))
- eq('short string0000', inspect())
- end)
- itp('wont write beyond capacity', function()
- eq(16, write('very very long string'))
- eq('very very long s', inspect())
- end)
- end)
- describe('rbuffer_read', function()
- itp('reads what was previously written', function()
- write('to read')
- eq('to read', read(20))
- end)
- itp('reads nothing if the buffer is empty', function()
- eq('', read(20))
- write('empty')
- eq('empty', read(20))
- eq('', read(20))
- end)
- end)
- describe('rbuffer_get', function()
- itp('fetch the pointer at offset, wrapping if required', function()
- write('1234567890')
- read(10)
- write('long string')
- eq('l', get(0))
- eq('o', get(1))
- eq('n', get(2))
- eq('g', get(3))
- eq(' ', get(4))
- eq('s', get(5))
- eq('t', get(6))
- eq('r', get(7))
- eq('i', get(8))
- eq('n', get(9))
- eq('g', get(10))
- end)
- end)
- describe('wrapping behavior', function()
- itp('writing/reading wraps across the end of the internal buffer', function()
- write('1234567890')
- eq('1234', read(4))
- eq('5678', read(4))
- write('987654321')
- eq('3214567890987654', inspect())
- eq('90987654321', read(20))
- eq('', read(4))
- write('abcdefghijklmnopqrs')
- eq('nopabcdefghijklm', inspect())
- eq('abcdefghijklmnop', read(20))
- end)
- end)
- end)
|