81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { extractFrames, frame } from './codec.js';
|
|
|
|
const F = (payload: number[]) => [
|
|
0x94,
|
|
0xc3,
|
|
(payload.length >> 8) & 0xff,
|
|
payload.length & 0xff,
|
|
...payload,
|
|
];
|
|
|
|
describe('extractFrames', () => {
|
|
it('emits one complete frame and empties rest', () => {
|
|
const { packets, rest } = extractFrames(Uint8Array.from(F([1, 2, 3])));
|
|
expect(packets).toHaveLength(1);
|
|
expect(Array.from(packets[0])).toEqual([1, 2, 3]);
|
|
expect(rest.length).toBe(0);
|
|
});
|
|
|
|
it('emits two frames from one chunk', () => {
|
|
const buf = Uint8Array.from([...F([1]), ...F([2, 2])]);
|
|
const { packets, rest } = extractFrames(buf);
|
|
expect(packets.map((p) => Array.from(p))).toEqual([[1], [2, 2]]);
|
|
expect(rest.length).toBe(0);
|
|
});
|
|
|
|
it('reassembles a frame split across two feedings', () => {
|
|
const full = Uint8Array.from(F([9, 8, 7]));
|
|
const first = extractFrames(full.subarray(0, 5)); // header + 1 payload byte
|
|
expect(first.packets).toHaveLength(0);
|
|
expect(Array.from(first.rest)).toEqual(Array.from(full.subarray(0, 5)));
|
|
|
|
const second = extractFrames(
|
|
Uint8Array.from([...first.rest, ...full.subarray(5)]),
|
|
);
|
|
expect(second.packets.map((p) => Array.from(p))).toEqual([[9, 8, 7]]);
|
|
expect(second.rest.length).toBe(0);
|
|
});
|
|
|
|
it('discards garbage bytes before the header', () => {
|
|
const buf = Uint8Array.from([0xaa, 0xbb, ...F([5])]);
|
|
const { packets, rest } = extractFrames(buf);
|
|
expect(packets.map((p) => Array.from(p))).toEqual([[5]]);
|
|
expect(rest.length).toBe(0);
|
|
});
|
|
|
|
it('resyncs past a bogus len > 1024 and finds the real frame', () => {
|
|
const buf = Uint8Array.from([0x94, 0xc3, 0xff, 0xfe, ...F([7, 6])]);
|
|
const { packets, rest } = extractFrames(buf);
|
|
expect(packets.map((p) => Array.from(p))).toEqual([[7, 6]]);
|
|
expect(rest.length).toBe(0);
|
|
});
|
|
|
|
it('keeps a trailing lone 0x94 in rest', () => {
|
|
const { packets, rest } = extractFrames(Uint8Array.from([0xaa, 0x94]));
|
|
expect(packets).toHaveLength(0);
|
|
expect(Array.from(rest)).toEqual([0x94]);
|
|
});
|
|
});
|
|
|
|
describe('frame', () => {
|
|
it('prepends the 0x94 0xC3 big-endian length header', () => {
|
|
const out = frame(Uint8Array.from([1, 2, 3]));
|
|
expect(Array.from(out)).toEqual([0x94, 0xc3, 0x00, 0x03, 1, 2, 3]);
|
|
});
|
|
|
|
it('encodes lengths above 255 in two bytes', () => {
|
|
const payload = new Uint8Array(300).fill(7);
|
|
const out = frame(payload);
|
|
expect(Array.from(out.subarray(0, 4))).toEqual([0x94, 0xc3, 0x01, 0x2c]);
|
|
expect(out.length).toBe(304);
|
|
});
|
|
|
|
it('round-trips through extractFrames', () => {
|
|
const framed = frame(Uint8Array.from([4, 5]));
|
|
const { packets, rest } = extractFrames(framed);
|
|
expect(packets.map((p) => Array.from(p))).toEqual([[4, 5]]);
|
|
expect(rest.length).toBe(0);
|
|
});
|
|
});
|