Initial import

This commit is contained in:
2026-03-11 19:08:39 +01:00
commit 5bf12c326a
14 changed files with 4601 additions and 0 deletions

84
test/address.test.ts Normal file
View File

@@ -0,0 +1,84 @@
import { describe, it, expect } from 'vitest';
import { Address } from '../src/address';
describe('Address.constructor', () => {
it('truncates callsign to 6 chars and uppercases; accepts valid SSID', () => {
const a = new Address('abcdefg', 12);
expect(a.callsign).toBe('ABCDEF');
expect(a.ssid).toBe(12);
});
describe('input validation', () => {
it('rejects non-string callsign', () => {
expect(() => new Address(123 as any, 0)).toThrow(TypeError);
});
it('rejects empty callsign', () => {
expect(() => new Address(' ', 0)).toThrow();
});
it('rejects non-integer or out-of-range SSID', () => {
// non-integer
expect(() => new Address('ABC', 1.5 as any)).toThrow(TypeError);
// out of range
expect(() => new Address('ABC', -1)).toThrow(RangeError);
expect(() => new Address('ABC', 16)).toThrow(RangeError);
});
});
});
describe('Address.fromBytes', () => {
it('roundtrips to/from bytes and string', () => {
const a = new Address('NOCALL', 3);
const b = Address.fromBytes(a.toBytes(true));
expect(b.callsign).toBe('NOCALL');
expect(b.ssid).toBe(3);
expect(a.toString()).toBe('NOCALL-3');
});
it('throws on short buffer', () => {
expect(() => Address.fromBytes(new Uint8Array([1, 2, 3]))).toThrow();
});
});
describe('Address.fromString', () => {
it('parses string addresses', () => {
const a = Address.fromString('FOO-1');
expect(a.callsign).toBe('FOO');
expect(a.ssid).toBe(1);
});
describe('input validation', () => {
it('rejects invalid fromString inputs', () => {
// non-string
expect(() => Address.fromString(123 as any)).toThrow(TypeError);
// empty
expect(() => Address.fromString('-1')).toThrow();
// non-numeric SSID
expect(() => Address.fromString('FOO-A')).toThrow();
});
});
});
describe('Address.toBytes', () => {
it('encodes callsign bytes and SSID correctly with and without last bit', () => {
const a = new Address('AB', 5);
const b = a.toBytes(false);
expect(b[0]).toBe('A'.charCodeAt(0) << 1);
expect(b[1]).toBe('B'.charCodeAt(0) << 1);
// padding spaces are 0x20 << 1 == 0x40
expect(b[2]).toBe(0x40);
expect(b[6]).toBe(0x60 | ((5 << 1) & 0xfe));
const last = a.toBytes(true);
expect((last[6] & 0x01)).toBe(1);
});
});
describe('Address.toString', () => {
it('omits SSID when showSsid is false and supports custom separator', () => {
const a = new Address('call', 2);
expect(a.toString({ showSsid: false })).toBe('CALL');
expect(a.toString({ sep: ':' })).toBe('CALL:2');
});
});