import { test } from '@japa/runner' import { delimitedReader } from '#lib/nntp/delimited_reader' const CRLF = Buffer.from('\r\n') const END = Buffer.from('\r\n.\r\n') async function* chunks(...parts: string[]) { for (const part of parts) yield Buffer.from(part, 'latin1') } test.group('nntp / delimitedReader', () => { test('reads an empty multi-line reply (XOVER of a range without articles)', async ({ assert }) => { const reader = delimitedReader(chunks('224 Overview follows\r\n.\r\n', '211 1 2 3 g\r\n'), CRLF) assert.equal((await reader.next()).value!.toString(), '224 Overview follows') assert.equal((await reader.next(END)).value!.toString(), '') assert.equal((await reader.next(CRLF)).value!.toString(), '211 1 2 3 g') }) test('reads multi-line data, also with the terminator split over chunks', async ({ assert }) => { for (const split of [1, 2, 3, 4, 5, 6, 7]) { const reply = '224 ok\r\nline 1\r\n..dotted\r\nline 3\r\n.\r\n200 next\r\n' const at = reply.indexOf('.\r\n200') - 2 + split - 1 const reader = delimitedReader(chunks(reply.slice(0, at), reply.slice(at)), CRLF) assert.equal((await reader.next()).value!.toString(), '224 ok') assert.equal((await reader.next(END)).value!.toString(), 'line 1\r\n..dotted\r\nline 3', `split ${split}`) assert.equal((await reader.next(CRLF)).value!.toString(), '200 next') } }) test('reads replies byte by byte', async ({ assert }) => { const text = '200 welcome\r\n224 ok\r\na\r\n.\r\n224 ok\r\n.\r\n211 x\r\n' const reader = delimitedReader(chunks(...text.split('')), CRLF) assert.equal((await reader.next()).value!.toString(), '200 welcome') assert.equal((await reader.next(CRLF)).value!.toString(), '224 ok') assert.equal((await reader.next(END)).value!.toString(), 'a') assert.equal((await reader.next(CRLF)).value!.toString(), '224 ok') assert.equal((await reader.next(END)).value!.toString(), '') assert.equal((await reader.next(CRLF)).value!.toString(), '211 x') }) test('keeps binary data intact', async ({ assert }) => { const body = Buffer.from([0, 13, 255, 10, 46, 13, 46, 10, 13]) const source = (async function* () { yield Buffer.from('222 body\r\n') yield body yield Buffer.from('\r\n.\r\n') })() const reader = delimitedReader(source, CRLF) await reader.next() assert.deepEqual((await reader.next(END)).value, body) }) })