78 lines
2.9 KiB
TypeScript
78 lines
2.9 KiB
TypeScript
import { JSONRPCMessage } from '../../src/types.js';
|
|
import { STDIO_DEFAULT_MAX_BUFFER_SIZE, ReadBuffer } from '../../src/shared/stdio.js';
|
|
|
|
const testMessage: JSONRPCMessage = {
|
|
jsonrpc: '2.0',
|
|
method: 'foobar'
|
|
};
|
|
|
|
test('should have no messages after initialization', () => {
|
|
const readBuffer = new ReadBuffer();
|
|
expect(readBuffer.readMessage()).toBeNull();
|
|
});
|
|
|
|
test('should only yield a message after a newline', () => {
|
|
const readBuffer = new ReadBuffer();
|
|
|
|
readBuffer.append(Buffer.from(JSON.stringify(testMessage)));
|
|
expect(readBuffer.readMessage()).toBeNull();
|
|
|
|
readBuffer.append(Buffer.from('\n'));
|
|
expect(readBuffer.readMessage()).toEqual(testMessage);
|
|
expect(readBuffer.readMessage()).toBeNull();
|
|
});
|
|
|
|
test('should be reusable after clearing', () => {
|
|
const readBuffer = new ReadBuffer();
|
|
|
|
readBuffer.append(Buffer.from('foobar'));
|
|
readBuffer.clear();
|
|
expect(readBuffer.readMessage()).toBeNull();
|
|
|
|
readBuffer.append(Buffer.from(JSON.stringify(testMessage)));
|
|
readBuffer.append(Buffer.from('\n'));
|
|
expect(readBuffer.readMessage()).toEqual(testMessage);
|
|
});
|
|
|
|
describe('buffer size limit', () => {
|
|
test('should throw when buffer exceeds default max size', () => {
|
|
const readBuffer = new ReadBuffer();
|
|
const chunkSize = 1024 * 1024; // 1 MB
|
|
const chunk = Buffer.alloc(chunkSize);
|
|
const chunksToFill = Math.floor(STDIO_DEFAULT_MAX_BUFFER_SIZE / chunkSize);
|
|
for (let i = 0; i < chunksToFill; i++) {
|
|
readBuffer.append(chunk);
|
|
}
|
|
expect(() => readBuffer.append(chunk)).toThrow(/ReadBuffer exceeded maximum size/);
|
|
});
|
|
|
|
test('should throw when buffer exceeds custom max size', () => {
|
|
const readBuffer = new ReadBuffer({ maxBufferSize: 100 });
|
|
readBuffer.append(Buffer.alloc(50));
|
|
expect(() => readBuffer.append(Buffer.alloc(51))).toThrow(/ReadBuffer exceeded maximum size/);
|
|
});
|
|
|
|
test('should clear buffer before throwing on overflow', () => {
|
|
const readBuffer = new ReadBuffer({ maxBufferSize: 100 });
|
|
readBuffer.append(Buffer.alloc(50));
|
|
expect(() => readBuffer.append(Buffer.alloc(51))).toThrow();
|
|
|
|
// Buffer should be cleared — can append again
|
|
readBuffer.append(Buffer.alloc(50));
|
|
// And read messages normally
|
|
expect(readBuffer.readMessage()).toBeNull();
|
|
});
|
|
|
|
test('should allow appending up to exactly the max size', () => {
|
|
const readBuffer = new ReadBuffer({ maxBufferSize: 100 });
|
|
// Should not throw — exactly at limit
|
|
expect(() => readBuffer.append(Buffer.alloc(100))).not.toThrow();
|
|
});
|
|
|
|
test('should work with no options (backwards compatible)', () => {
|
|
const readBuffer = new ReadBuffer();
|
|
// Small append should always work
|
|
readBuffer.append(Buffer.from(JSON.stringify({ jsonrpc: '2.0', method: 'ping' }) + '\n'));
|
|
expect(readBuffer.readMessage()).not.toBeNull();
|
|
});
|
|
});
|