import { describe, it, expect } from 'vitest'; import { Buffer } from 'node:buffer'; import { encodeVarint, decodeVarint } from '../src/connection.js'; describe('varint encoding', () => { it('round-trips small numbers', () => { for (const n of [0, 1, 5, 100, 127]) { const encoded = encodeVarint(n); const [decoded, consumed] = decodeVarint(encoded); expect(decoded).toBe(n); expect(consumed).toBe(encoded.length); } }); it('round-trips numbers requiring 2 bytes', () => { for (const n of [128, 200, 16383, 16384, 100_000]) { const encoded = encodeVarint(n); const [decoded, consumed] = decodeVarint(encoded); expect(decoded).toBe(n); expect(consumed).toBe(encoded.length); } }); it('round-trips numbers requiring 4-5 bytes', () => { for (const n of [2 ** 20, 2 ** 28, 2 ** 31 - 1, 2 ** 32]) { const encoded = encodeVarint(n); const [decoded, consumed] = decodeVarint(encoded); expect(decoded).toBe(n); expect(consumed).toBe(encoded.length); } }); it('encodes correctly per the protobuf spec', () => { // Reference values from the protobuf documentation expect([...encodeVarint(0)]).toEqual([0x00]); expect([...encodeVarint(1)]).toEqual([0x01]); expect([...encodeVarint(127)]).toEqual([0x7f]); expect([...encodeVarint(128)]).toEqual([0x80, 0x01]); expect([...encodeVarint(300)]).toEqual([0xac, 0x02]); }); it('decodes from a multi-byte buffer correctly', () => { // decodeVarint should stop at the varint boundary const buf = Buffer.concat([encodeVarint(42), Buffer.from([0xff, 0xee])]); const [decoded, consumed] = decodeVarint(buf); expect(decoded).toBe(42); expect(consumed).toBe(1); // only the first byte was the varint }); it('rejects negative numbers', () => { expect(() => encodeVarint(-1)).toThrow(); }); }); describe('varint edge cases', () => { it('decodes 0', () => { const [v, c] = decodeVarint(Buffer.from([0])); expect(v).toBe(0); expect(c).toBe(1); }); it('decodes max uint32', () => { const n = 0xffffffff; const [v, c] = decodeVarint(encodeVarint(n)); expect(v).toBe(n); expect(c).toBe(encodeVarint(n).length); }); });