@joystick.js/db-canary
Version:
JoystickDB - A minimalist database server for the Joystick framework
170 lines (127 loc) • 5 kB
JavaScript
import test from 'ava';
import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
test('encode_message - should encode message with length prefix', (t) => {
const data = { test: 'data', number: 42 };
const result = encode_message(data);
t.true(Buffer.isBuffer(result));
t.true(result.length > 4);
const length = result.readUInt32BE(0);
const payload = result.slice(4);
t.is(payload.length, length);
});
test('encode_message - should handle empty object', (t) => {
const data = {};
const result = encode_message(data);
t.true(Buffer.isBuffer(result));
const length = result.readUInt32BE(0);
t.true(length > 0);
});
test('encode_message - should handle complex nested data', (t) => {
const data = {
nested: {
array: [1, 2, 3],
string: 'test',
boolean: true
}
};
const result = encode_message(data);
t.true(Buffer.isBuffer(result));
t.true(result.length > 4);
});
test('create_message_parser - should parse single complete message', (t) => {
const parser = create_message_parser();
const test_data = { op: 'test', data: { value: 123 } };
const encoded = encode_message(test_data);
const messages = parser.parse_messages(encoded);
t.is(messages.length, 1);
t.deepEqual(messages[0], test_data);
});
test('create_message_parser - should parse multiple messages', (t) => {
const parser = create_message_parser();
const test_data_1 = { op: 'test1', data: { value: 123 } };
const test_data_2 = { op: 'test2', data: { value: 456 } };
const encoded_1 = encode_message(test_data_1);
const encoded_2 = encode_message(test_data_2);
const combined = Buffer.concat([encoded_1, encoded_2]);
const messages = parser.parse_messages(combined);
t.is(messages.length, 2);
t.deepEqual(messages[0], test_data_1);
t.deepEqual(messages[1], test_data_2);
});
test('create_message_parser - should handle partial messages', (t) => {
const parser = create_message_parser();
const test_data = { op: 'test', data: { value: 123 } };
const encoded = encode_message(test_data);
const partial_1 = encoded.slice(0, 2);
const partial_2 = encoded.slice(2);
let messages = parser.parse_messages(partial_1);
t.is(messages.length, 0);
messages = parser.parse_messages(partial_2);
t.is(messages.length, 1);
t.deepEqual(messages[0], test_data);
});
test('create_message_parser - should handle partial length prefix', (t) => {
const parser = create_message_parser();
const test_data = { op: 'test', data: { value: 123 } };
const encoded = encode_message(test_data);
const partial_length = encoded.slice(0, 3);
const remaining = encoded.slice(3);
let messages = parser.parse_messages(partial_length);
t.is(messages.length, 0);
messages = parser.parse_messages(remaining);
t.is(messages.length, 1);
t.deepEqual(messages[0], test_data);
});
test('create_message_parser - should handle partial payload', (t) => {
const parser = create_message_parser();
const test_data = { op: 'test', data: { value: 123 } };
const encoded = encode_message(test_data);
const length_and_partial = encoded.slice(0, encoded.length - 2);
const remaining_payload = encoded.slice(encoded.length - 2);
let messages = parser.parse_messages(length_and_partial);
t.is(messages.length, 0);
messages = parser.parse_messages(remaining_payload);
t.is(messages.length, 1);
t.deepEqual(messages[0], test_data);
});
test('create_message_parser - should throw on invalid messagepack', (t) => {
const parser = create_message_parser();
const invalid_length = Buffer.allocUnsafe(4);
invalid_length.writeUInt32BE(5, 0);
const invalid_payload = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
const invalid_message = Buffer.concat([invalid_length, invalid_payload]);
t.throws(
() => {
parser.parse_messages(invalid_message);
},
{ message: /Invalid message format/ }
);
});
test('create_message_parser - reset should clear internal state', (t) => {
const parser = create_message_parser();
const test_data = { op: 'test', data: { value: 123 } };
const encoded = encode_message(test_data);
const partial = encoded.slice(0, 2);
parser.parse_messages(partial);
parser.reset();
const messages = parser.parse_messages(encoded);
t.is(messages.length, 1);
t.deepEqual(messages[0], test_data);
});
test('create_message_parser - should handle empty buffer', (t) => {
const parser = create_message_parser();
const empty_buffer = Buffer.alloc(0);
const messages = parser.parse_messages(empty_buffer);
t.is(messages.length, 0);
});
test('create_message_parser - should handle zero-length message', (t) => {
const parser = create_message_parser();
const zero_length = Buffer.allocUnsafe(4);
zero_length.writeUInt32BE(0, 0);
t.throws(
() => {
parser.parse_messages(zero_length);
},
{ message: /Invalid message format/ }
);
});