File
Blob: worker/src/client/radio/protocol.test.ts
| 1 | import assert from 'node:assert/strict'; |
| 2 | import { test } from 'node:test'; |
| 3 | import { newerTimestamp, parseRobot, parseSpectrum } from './protocol.ts'; |
| 4 | |
| 5 | function spectrum(pts: number, position: number, paused = false) { |
| 6 | const frame = new ArrayBuffer(44); |
| 7 | const data = new DataView(frame); |
| 8 | data.setUint8(0, 1); |
| 9 | data.setUint8(1, Number(paused)); |
| 10 | data.setUint32(4, pts, true); |
| 11 | data.setUint32(8, position, true); |
| 12 | new Uint8Array(frame, 12).fill(paused ? 0 : 127); |
| 13 | return frame; |
| 14 | } |
| 15 | |
| 16 | test('spectrum accepts track restart while rejecting duplicates and delayed packets', () => { |
| 17 | const before = parseSpectrum(spectrum(5000, 5000))!; |
| 18 | assert.equal(parseSpectrum(spectrum(5000, 5000), before.pts), undefined); |
| 19 | assert.equal(parseSpectrum(spectrum(4980, 4980), before.pts), undefined); |
| 20 | const restarted = parseSpectrum(spectrum(5040, 0), before.pts)!; |
| 21 | assert.equal(restarted.positionMs, 0); |
| 22 | assert.deepEqual(Array.from(restarted.bands), Array(32).fill(127)); |
| 23 | }); |
| 24 | |
| 25 | test('spectrum handles a wrapping RTP clock and pause frames', () => { |
| 26 | assert.equal(newerTimestamp(20, 0xfffffff0), true); |
| 27 | assert.equal(newerTimestamp(0xfffffff0, 20), false); |
| 28 | const paused = parseSpectrum(spectrum(20, 100, true), 0xfffffff0)!; |
| 29 | assert.equal(paused.paused, true); |
| 30 | assert.ok(paused.bands.every((value) => value === 0)); |
| 31 | assert.equal(parseSpectrum(new ArrayBuffer(43)), undefined); |
| 32 | const unknownVersion = spectrum(40, 100); |
| 33 | new DataView(unknownVersion).setUint8(0, 2); |
| 34 | assert.equal(parseSpectrum(unknownVersion), undefined); |
| 35 | }); |
| 36 | |
| 37 | test('robot messages reject malformed JSON and invalid acknowledgments', () => { |
| 38 | assert.equal(parseRobot('{'), undefined); |
| 39 | assert.equal(parseRobot('x'.repeat(4097)), undefined); |
| 40 | assert.equal( |
| 41 | parseRobot( |
| 42 | JSON.stringify({ event: 'ack', command_id: 'a', result: 0, led: [999, 0, 0], paused: false }), |
| 43 | ), |
| 44 | undefined, |
| 45 | ); |
| 46 | }); |