Stricter decoding

This commit is contained in:
2026-03-15 20:21:26 +01:00
parent 4669783b67
commit e0d4844c5b
12 changed files with 1241 additions and 4188 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
import { describe, it, expect } from 'vitest';
import { describe, it, expect } from "vitest";
import {
base91ToNumber,
knotsToKmh,
@@ -7,79 +7,79 @@ import {
metersToFeet,
celsiusToFahrenheit,
fahrenheitToCelsius,
} from '../src/parser';
} from "../src/parser";
describe('parser utilities', () => {
describe('base91ToNumber', () => {
it('decodes all-! to 0', () => {
expect(base91ToNumber('!!!!')).toBe(0);
describe("parser utilities", () => {
describe("base91ToNumber", () => {
it("decodes all-! to 0", () => {
expect(base91ToNumber("!!!!")).toBe(0);
});
it('decodes single character correctly', () => {
it("decodes single character correctly", () => {
// 'A' === 65, digit = 65 - 33 = 32
expect(base91ToNumber('A')).toBe(32);
expect(base91ToNumber("A")).toBe(32);
});
it('should decode multiple Base91 characters', () => {
it("should decode multiple Base91 characters", () => {
// "!!" = 0 * 91 + 0 = 0
expect(base91ToNumber('!!')).toBe(0);
expect(base91ToNumber("!!")).toBe(0);
// "!#" = 0 * 91 + 2 = 2
expect(base91ToNumber('!#')).toBe(2);
expect(base91ToNumber("!#")).toBe(2);
// "#!" = 2 * 91 + 0 = 182
expect(base91ToNumber('#!')).toBe(182);
expect(base91ToNumber("#!")).toBe(182);
// "##" = 2 * 91 + 2 = 184
expect(base91ToNumber('##')).toBe(184);
expect(base91ToNumber("##")).toBe(184);
});
it('should decode 4-character Base91 strings (used in APRS)', () => {
it("should decode 4-character Base91 strings (used in APRS)", () => {
// Test with printable ASCII Base91 characters (33-123)
const testValue = base91ToNumber('!#%\'');
const testValue = base91ToNumber("!#%'");
expect(testValue).toBeGreaterThan(0);
expect(testValue).toBeLessThan(91 * 91 * 91 * 91);
});
it('should decode maximum valid Base91 value', () => {
it("should decode maximum valid Base91 value", () => {
// Maximum is '{' (ASCII 123, digit 90) repeated
const maxValue = base91ToNumber('{{{{');
const maxValue = base91ToNumber("{{{{");
const expected = 90 * 91 * 91 * 91 + 90 * 91 * 91 + 90 * 91 + 90;
expect(maxValue).toBe(expected);
});
it('should handle APRS compressed position example', () => {
it("should handle APRS compressed position example", () => {
// Using actual characters from APRS test vector
const latStr = '/:*E';
const lonStr = 'qZ=O';
const latStr = "/:*E";
const lonStr = "qZ=O";
const latValue = base91ToNumber(latStr);
const lonValue = base91ToNumber(lonStr);
// Just verify they decode without error and produce valid numbers
expect(typeof latValue).toBe('number');
expect(typeof lonValue).toBe('number');
expect(typeof latValue).toBe("number");
expect(typeof lonValue).toBe("number");
expect(latValue).toBeGreaterThanOrEqual(0);
expect(lonValue).toBeGreaterThanOrEqual(0);
});
it('throws on invalid character', () => {
expect(() => base91ToNumber(' ')).toThrow(); // space (code 32) is invalid
it("throws on invalid character", () => {
expect(() => base91ToNumber(" ")).toThrow(); // space (code 32) is invalid
});
});
describe('unit conversions', () => {
it('converts knots <-> km/h', () => {
describe("unit conversions", () => {
it("converts knots <-> km/h", () => {
expect(knotsToKmh(10)).toBeCloseTo(18.52, 5);
expect(kmhToKnots(18.52)).toBeCloseTo(10, 3);
});
it('converts feet <-> meters', () => {
it("converts feet <-> meters", () => {
expect(feetToMeters(10)).toBeCloseTo(3.048, 6);
expect(metersToFeet(3.048)).toBeCloseTo(10, 6);
});
it('converts celsius <-> fahrenheit', () => {
it("converts celsius <-> fahrenheit", () => {
expect(celsiusToFahrenheit(0)).toBeCloseTo(32, 6);
expect(fahrenheitToCelsius(32)).toBeCloseTo(0, 6);
expect(celsiusToFahrenheit(100)).toBeCloseTo(212, 6);